Analitikai savo darbe dažnai susiduria su duomenų nukrypimais, pavyzdžiui, atlikdami AB testo analizę, kurdami nuspėjamuosius modelius ar stebėdami tendencijas. Sprendimai paprastai grindžiami imties vidurkiu, kuris yra labai jautrus nuokrypiams ir gali smarkiai pakeisti vertę. Taigi, norint priimti teisingą sprendimą, labai svarbu valdyti nuokrypius.
Apsvarstykite keletą paprastų ir greitų būdų dirbti su neįprastomis vertybėmis.
Įsivaizduokite, kad jums reikia atlikti eksperimento analizę naudodami vidutinę užsakymo vertę kaip pagrindinę metriką. Tarkime, kad mūsų metrika paprastai turi normalųjį skirstinį. Taip pat žinome, kad metrikos pasiskirstymas bandomojoje grupėje skiriasi nuo kontrolinės grupės. Kitaip tariant, pasiskirstymo vidurkis kontrolėje yra 10, o teste – 12. Standartinis nuokrypis abiejose grupėse yra 3.
Tačiau abiejuose mėginiuose yra iškrypimų, kurie iškreipia imties vidurkį ir imties standartinį nuokrypį.
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))
Įsidėmėkite , kad atsižvelgiant į metriką gali būti nuokrypių iš abiejų pusių. Jei jūsų metrika gali turėti nuokrypių tik iš vienos pusės, metodus galima lengvai transformuoti tuo tikslu.
Paprasčiausias būdas yra nutraukti visus stebėjimus prieš 5% procentilį ir po 95% procentilio . Šiuo atveju mes praradome 10% informacijos kaip sukčiavimo. Tačiau skirstiniai atrodo labiau suformuoti, o imties momentai yra arčiau paskirstymo momentų.
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]
Kitas būdas yra neįtraukti stebėjimų už konkretaus diapazono ribų . Žemoji juosta yra lygi 25 % procentiliui atėmus pusę tarpkvartilio diapazono, o viršutinė juosta lygi 75 % procentiliui plius pusei. Čia prarasime tik 0,7% informacijos. Paskirstymai atrodo labiau suformuoti nei pradiniai. Pavyzdiniai momentai dar labiau lygūs pasiskirstymo momentams.
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]
Antrasis metodas, kurį čia svarstėme, yra įkrovos įkrovimas. Taikant šį metodą, vidurkis sudaromas kaip subimties vidurkis. Mūsų pavyzdyje kontrolinės grupės vidurkis lygus 10,35, o bandomosios grupės – 11,78. Tai vis tiek geresnis rezultatas lyginant su papildomu duomenų apdorojimu.
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())
Nukrypimų aptikimas ir apdorojimas yra svarbūs norint priimti teisingą sprendimą. Dabar bent trys greiti ir paprasti metodai gali padėti patikrinti duomenis prieš analizę.
Tačiau būtina atsiminti, kad aptiktos nuokrypiai gali būti neįprastos reikšmės ir naujovės efekto ypatybė. Bet tai jau kita istorija :)