Анализаторите често срещат отклонения в данните по време на работата си, като например по време на анализ на AB-тест, създаване на прогнозни модели или проследяване на тенденции. Решенията обикновено се основават на средната стойност на извадката, която е много чувствителна към отклонения и може драматично да промени стойността. Така че е изключително важно да се управляват извънредните стойности, за да се вземе правилното решение.
Нека разгледаме няколко прости и бързи подхода за работа с необичайни стойности.
Представете си, че трябва да проведете експериментален анализ, като използвате средна стойност на поръчката като основен показател. Да кажем, че нашата метрика обикновено има нормално разпределение. Освен това знаем, че разпределението на показателите в тестовата група е различно от това в контролната. С други думи, средната стойност на разпределението в контролата е 10, а в теста е 12. Стандартното отклонение и в двете групи е 3.
И двете проби обаче имат извънредни стойности, които изкривяват средните стойности на извадката и стандартното отклонение на извадката.
import numpy as np N = 1000 mean_1 = 10 std_1 = 3 mean_2 = 12 std_2 = 3 x1 = np.concatenate((np.random.normal(mean_1, std_1, N), 10 * np.random.random_sample(50) + 20)) x2 = np.concatenate((np.random.normal(mean_2, std_2, N), 4 * np.random.random_sample(50) + 1))
Забележка , че разглеждането на метрика може да има отклонения от двете страни. Ако вашият показател може да има отклонения само от едната страна, методите могат лесно да бъдат трансформирани за тази цел.
Най-лесният метод е да отрежете всички наблюдения преди 5% персентил и след 95% персентил . В този случай загубихме 10% от информацията като измама. Разпределенията обаче изглеждат по-оформени и моментите на извадката са по-близо до моментите на разпределение.
import numpy as np x1_5pct = np.percentile(x1, 5) x1_95pct = np.percentile(x1, 95) x1_cutted = [i for i in x1 if i > x1_5pct and i < x1_95pct] x2_5pct = np.percentile(x2, 5) x2_95pct = np.percentile(x2, 95) x2_cutted = [i for i in x2 if i > x2_5pct and i < x2_95pct]
Друг начин е да изключите наблюдения извън конкретния диапазон . Ниската лента е равна на 25% персентил минус половината от интерквартилния диапазон, а високата лента е равна на 75% персентил плюс половината. Тук ще загубим само 0,7% от информацията. Разпределенията изглеждат по-оформени от първоначалните. Извадковите моменти са още по-равни на моментите на разпределение.
import numpy as np low_band_1 = np.percentile(x1, 25) - 1.5 * np.std(x1) high_band_1 = np.percentile(x1, 75) + 1.5 * np.std(x1) x1_cutted = [i for i in x1 if i > low_band_1 and i < high_band_1] low_band_2 = np.percentile(x2, 25) - 1.5 * np.std(x2) high_band_2 = np.percentile(x2, 75) + 1.5 * np.std(x2) x2_cutted = [i for i in x2 if i > low_band_2 and i < high_band_2]
Вторият метод, който разгледахме тук, е bootstrap. При този подход средната стойност се конструира като средна стойност на подизвадките. В нашия пример средната стойност в контролната група е равна на 10,35, а в тестовата група е 11,78. Все още е по-добър резултат в сравнение с допълнителната обработка на данни.
import pandas as pd def create_bootstrap_samples( sample_list: np.array, sample_size: int, n_samples: int ): # create a list for sample means sample_means = [] # loop n_samples times for i in range(n_samples): # create a bootstrap sample of sample_size with replacement bootstrap_sample = pd.Series(sample_list).sample(n = sample_size, replace = True) # calculate the bootstrap sample mean sample_mean = bootstrap_sample.mean() # add this sample mean to the sample means list sample_means.append(sample_mean) return pd.Series(sample_means) (create_bootstrap_samples(x1, len(x1), 1000).mean(), create_bootstrap_samples(x2, len(x2), 1000).mean())
Откриването и обработката на извънредни стойности са важни за вземането на правилното решение. Сега най-малко три бързи и ясни подхода могат да ви помогнат да проверите данните преди анализ.
Важно е обаче да запомните, че откритите извънредни стойности могат да бъдат необичайни стойности и характеристика на ефекта на новост. Но това е друга история :)