Analitičari se često susreću s odstupanjima u podacima tijekom svog rada, primjerice tijekom analize AB-testa, izrade prediktivnih modela ili praćenja trendova. Odluke se obično temelje na srednjoj vrijednosti uzorka, koja je vrlo osjetljiva na izvanredne vrijednosti i može dramatično promijeniti vrijednost. Dakle, ključno je upravljati outlierima kako bi se donijela ispravna odluka.
Razmotrimo nekoliko jednostavnih i brzih pristupa za rad s neobičnim vrijednostima.
Zamislite da morate provesti analizu eksperimenta koristeći prosječnu vrijednost narudžbe kao primarnu metriku. Recimo da naša metrika obično ima normalnu distribuciju. Također, znamo da je distribucija metrike u testnoj skupini drugačija od one u kontrolnoj. Drugim riječima, srednja vrijednost distribucije u kontroli je 10, au testu 12. Standardna devijacija u obje skupine je 3.
Međutim, oba uzorka imaju outliere koji iskrivljuju srednju vrijednost uzorka i standardnu devijaciju uzorka.
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))
Imajte na umu da bi uzimanje u obzir metrike moglo imati odstupanja s obje strane. Kad bi vaša metrika mogla imati odstupanja samo s jedne strane, metode bi se lako mogle transformirati u tu svrhu.
Najlakši način je odrezati sva promatranja prije 5% percentila i nakon 95% percentila . U ovom slučaju izgubili smo 10% informacija kao prijevaru. Međutim, distribucije izgledaju oblikovanije, a uzorci su bliži momentima distribucije.
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]
Drugi način je isključiti opažanja izvan određenog raspona . Donji pojas jednak je 25% percentilu minus jedna polovica interkvartilnog raspona, a visoki pojas jednak je 75% percentilu plus jedna polovica. Ovdje ćemo izgubiti samo 0,7% informacija. Distribucije izgledaju oblikovanije od početnih. Momenti uzorka još su jednakiji momentima distribucije.
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]
Druga metoda koju smo ovdje razmotrili je bootstrap. U ovom pristupu, srednja vrijednost je konstruirana kao srednja vrijednost poduzoraka. U našem primjeru srednja vrijednost u kontrolnoj skupini iznosi 10,35, au testnoj skupini 11,78. To je ipak bolji rezultat u odnosu na dodatnu obradu podataka.
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())
Otkrivanje i obrada izvanrednih vrijednosti važni su za donošenje ispravne odluke. Sada bi vam barem tri brza i jednostavna pristupa mogla pomoći da provjerite podatke prije analize.
Međutim, važno je upamtiti da bi otkriveni ekstremi mogli biti neuobičajene vrijednosti i značajka za učinak novosti. Ali to je već druga priča :)