paint-brush
Stratifikacijos metodo naudojimas eksperimento analizeipateikė@nataliaogneva
33,160 skaitymai
33,160 skaitymai

Stratifikacijos metodo naudojimas eksperimento analizei

pateikė Natalia Ogneva8m2024/04/19
Read on Terminal Reader
Read this story w/o Javascript

Per ilgai; Skaityti

Stratifikuotas mėginių ėmimas yra galingas metodas, leidžiantis padidinti eksperimento efektyvumą ir metrinį duomenų analizės jautrumą. Suskirstę auditoriją į grupes ir suskirstę jas pagal tam tikrus svorius, galite optimizuoti eksperimentus, sumažinti dispersiją ir padidinti rezultatų patikimumą.

Company Mentioned

Mention Thumbnail
featured image - Stratifikacijos metodo naudojimas eksperimento analizei
Natalia Ogneva HackerNoon profile picture
0-item


Bet koks eksperimentas apima kompromisą tarp greitų rezultatų ir metrinio jautrumo. Jei pasirinkta metrika yra plati dispersijos požiūriu, turime ilgai laukti, kad įsitikintume, jog eksperimento rezultatai yra tikslūs. Panagrinėkime vieną metodą, kuris padėtų analitikams paspartinti eksperimentus neprarandant per daug laiko ar metrinio jautrumo.


Problemos formulavimas

Tarkime, kad atliekame standartinį eksperimentą, kad išbandytume naują reitingavimo algoritmą, kurio pagrindinė metrika yra seanso trukmė. Be to, turėkite omenyje, kad mūsų auditoriją galima apytiksliai suskirstyti į tris grupes: 1 milijonas paauglių, 2 milijonai 18–45 metų naudotojų ir 3 milijonai 45 metų ir vyresnių vartotojų. Atsakymas į naują reitingavimo algoritmą šiose auditorijos grupėse labai skirsis. Šis didelis svyravimas sumažina metrikos jautrumą.


Kitaip tariant, gyventojus galima suskirstyti į tris sluoksnius, aprašytus taip:


Tarkime, kad kiekvienas komponentas turi normalųjį skirstinį. Tada pagrindinė populiacijos metrika taip pat turi normalųjį pasiskirstymą.

Stratifikacijos metodas

Klasikinio eksperimento dizaino vartotojus atsitiktinai suskirstome iš populiacijos, neatsižvelgdami į naudotojų skirtumus. Taigi, mes svarstome imtį su tokia numatoma verte ir dispersija.


Kitas būdas yra atsitiktinis padalijimas kiekvieno sluoksnio viduje pagal sluoksnio svorį bendroje populiacijoje.

Šiuo atveju numatoma reikšmė ir dispersija yra šios.


Numatyta vertė yra tokia pati kaip ir pirmojo pasirinkimo. Tačiau dispersija yra mažesnė, o tai garantuoja didesnį metrinį jautrumą.

Dabar panagrinėkime Neymano metodą . Jie siūlo atsitiktinai paskirstyti vartotojus kiekviename sluoksnyje su tam tikrais svoriais.

Taigi, laukiama vertė ir dispersija šiuo atveju yra lygios toliau nurodytoms.

Tikėtina vertė yra lygi laukiamai vertei pirmuoju atveju asimptotiškai. Tačiau dispersija yra daug mažesnė.

Empirinis testavimas

Teoriškai įrodėme šio metodo efektyvumą. Modeliuokime pavyzdžius ir empiriškai išbandykime stratifikacijos metodą.

Panagrinėkime tris atvejus:

  • visi sluoksniai vienodomis priemonėmis ir dispersijomis,
  • visi sluoksniai su skirtingomis priemonėmis ir vienodomis dispersijomis,
  • visi sluoksniai vienodomis priemonėmis ir skirtingomis dispersijomis.

Visais atvejais taikysime visus tris metodus ir nubraižysime histogramą bei langelį, kad juos palygintume.

Kodo paruošimas

Pirmiausia sukurkime Python klasę, kuri imituoja mūsų bendrą populiaciją, kurią sudaro trys sluoksniai.

 class GeneralPopulation: def __init__(self, means: [float], stds: [float], sizes: [int], random_state: int = 15 ): """ Initializes our General Population and saves the given distributions :param means: List of expectations for normal distributions :param stds: List of standard deviations for normal distributions :param sizes: How many objects will be in each strata :param random_state: Parameter fixing randomness. Needed so that when conducting experiment repeatedly with the same input parameters, the results remained the same """ self.strats = [st.norm(mean, std) for mean, std in zip(means, stds)] self._sample(sizes) self.random_state = random_state def _sample(self, sizes): """Creates a general population sample as a mixture of strata :param sizes: List with sample sizes of the corresponding normal distributions """ self.strats_samples = [rv.rvs(size) for rv, size in zip(self.strats, sizes)] self.general_samples = np.hstack(self.strats_samples) self.N = self.general_samples.shape[0] # number of strata self.count_strats = len(sizes) # ratios for every strata in GP self.ws = [size/self.N for size in sizes] # ME and Std for GP self.m = np.mean(self.general_samples) self.sigma = np.std(self.general_samples) # ME and std for all strata self.ms = [np.mean(strat_sample) for strat_sample in self.strats_samples] self.sigmas = [np.std(strat_sample) for strat_sample in self.strats_samples]


Tada pridėkime funkcijas trims atrankos metodams, aprašytiems teorinėje dalyje.

 def random_subsampling(self, size): """Creates a random subset of the entire population :param sizes: subsample size """ rc = np.random.choice(self.general_samples, size=size) return rc def proportional_subsampling(self, size): """Creates a subsample with the number of elements, proportional shares of strata :param sizes: subsample size """ self.strats_size_proport = [int(np.floor(size*w)) for w in self.ws] rc = [] for k in range(len(self.strats_size_proport)): rc.append(np.random.choice(self.strats_samples[k], size=self.strats_size_proport[k])) return rc def optimal_subsampling(self, size): """Creates a subsample with the optimal number of elements relative to strata :param sizes: subsample size """ sum_denom = 0 for k in range(self.count_strats): sum_denom += self.ws[k] * self.sigmas[k] self.strats_size_optimal = [int(np.floor((size*w*sigma)/sum_denom)) for w, sigma in zip(self.ws, self.sigmas)] if 0 in self.strats_size_optimal: raise ValueError('Strats size is 0, please change variance of smallest strat!') rc = [] for k in range(len(self.strats_size_optimal)): rc.append(np.random.choice(self.strats_samples[k], size=self.strats_size_optimal[k])) return rc


Be to, empirinei daliai visada reikia eksperimento proceso modeliavimo funkcijos.

 def run_experiments(self, n_sub, subsampling_method, n_experiments=1000): """Conducts a series of experiments and saves the results :param n_sub: size of sample :param subsampling_method: method for creating a subsample :param n_experiments: number of experiment starts """ means_s = [] if(len(self.general_samples)<100): n_sub = 20 if(subsampling_method == 'random_subsampling'): for n in range(n_experiments): rc = self.random_subsampling(n_sub) mean = rc.sum()/len(rc) means_s.append(mean) else: for n in range(n_experiments): if(subsampling_method == 'proportional_subsampling'): rc = self.proportional_subsampling(n_sub) elif(subsampling_method == 'optimal_subsampling'): rc = self.optimal_subsampling(n_sub) strats_mean = [] for k in range(len(rc)): strats_mean.append(sum(rc[k])/len(rc[k])) # Mean for a mixture means_s.append(sum([w_k*mean_k for w_k, mean_k in zip(self.ws, strats_mean)])) return means_s


Modeliavimo rezultatai

Jei pažvelgsime į bendrą populiaciją, kurioje visi mūsų sluoksniai turi tas pačias reikšmes ir dispersijas, tikimasi, kad visų trijų metodų rezultatai bus daugiau ar mažiau vienodi.

Skirtingos priemonės ir vienodos dispersijos davė įdomesnių rezultatų. Naudojant stratifikaciją, dispersija žymiai sumažėja.

Tais atvejais, kai vidurkis yra vienodas ir skirtingos dispersijos, Neymano metodu matome dispersijos sumažinimą.

Išvada

Dabar galite taikyti stratifikacijos metodą, kad sumažintumėte metrikos dispersiją ir padidintumėte eksperimentą, jei auditoriją suskirstysite į grupes ir techniškai atsitiktinai suskirstysite jas kiekvienoje grupėje naudodami konkrečius svorius!