paint-brush
Korištenje metode stratifikacije za analizu eksperimentapo@nataliaogneva
33,172 čitanja
33,172 čitanja

Korištenje metode stratifikacije za analizu eksperimenta

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

Predugo; Čitati

Stratificirano uzorkovanje je moćna tehnika za povećanje učinkovitosti eksperimenta i metričke osjetljivosti u analizi podataka. Grupiranjem publike i dijeljenjem s određenim težinama možete optimizirati eksperimente, smanjiti varijance i povećati pouzdanost rezultata.

Company Mentioned

Mention Thumbnail
featured image - Korištenje metode stratifikacije za analizu eksperimenta
Natalia Ogneva HackerNoon profile picture
0-item


Svaki eksperiment uključuje kompromis između brzih rezultata i mjerne osjetljivosti. Ako je odabrana metrika široka u smislu varijance, moramo čekati dugo vremena kako bismo bili sigurni da su rezultati eksperimenta točni. Razmotrimo jednu metodu koja pomaže analitičarima da poboljšaju svoje eksperimente bez gubitka previše vremena ili metričke osjetljivosti.


Formulacija problema

Pretpostavimo da provodimo standardni eksperiment za testiranje novog algoritma za rangiranje, s duljinom sesije kao primarnim pokazateljem. Osim toga, uzmite u obzir da se naša publika može grubo kategorizirati u tri skupine: 1 milijun tinejdžera, 2 milijuna korisnika u dobi od 18 do 45 godina i 3 milijuna korisnika u dobi od 45 i više godina. Odgovor na novi algoritam rangiranja značajno bi se razlikovao među tim skupinama publike. Ova velika varijacija smanjuje osjetljivost metrike.


Drugim riječima, stanovništvo se može podijeliti u tri sloja, opisana na sljedeći način:


Recimo da svaka komponenta ima normalnu distribuciju. Zatim, glavna metrika za populaciju također ima normalnu distribuciju.

Metoda stratifikacije

Nasumično dijelimo sve korisnike iz populacije u klasičnom dizajnu eksperimenta ne uzimajući u obzir razlike među našim korisnicima. Stoga razmatramo uzorak sa sljedećom očekivanom vrijednošću i varijancom.


Drugi način je nasumična podjela unutar svake strate prema težini strate u općoj populaciji.

U ovom slučaju, očekivana vrijednost i varijanca su sljedeći.


Očekivana vrijednost je ista kao u prvom odabiru. Međutim, varijanca je manja, što jamči veću metričku osjetljivost.

Razmotrimo sada Neymanovu metodu . Predlažu nasumično dijeljenje korisnika unutar svake strate s određenim težinama.

Dakle, očekivana vrijednost i varijanca su u ovom slučaju jednake sljedećem.

Očekivana vrijednost je asimptotski jednaka očekivanoj vrijednosti u prvom slučaju. Međutim, varijanca je mnogo manja.

Empirijsko testiranje

Teorijski smo dokazali učinkovitost ove metode. Simulirajmo uzorke i empirijski testirajmo metodu stratifikacije.

Razmotrimo tri slučaja:

  • svi strati s jednakim sredinama i varijancama,
  • svi strati s različitim sredinama i jednakim varijancama,
  • svi strati s jednakim sredinama i različitim varijancama.

Primijenit ćemo sve tri metode u svim slučajevima i iscrtati histogram i okvir kako bismo ih usporedili.

Priprema koda

Prvo, stvorimo klasu u Pythonu koja simulira našu opću populaciju koja se sastoji od tri strata.

 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]


Zatim, dodajmo funkcije za tri metode uzorkovanja opisane u teoretskom dijelu.

 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


Također, za empirijski dio uvijek nam je potrebna funkcija za simulaciju eksperimentalnog procesa.

 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


Rezultati simulacije

Ako pogledamo opću populaciju, gdje svi naši strati imaju iste vrijednosti i varijance, očekuje se da će rezultati sve tri metode biti manje-više jednaki.

Različite srednje vrijednosti i jednake varijance dale su uzbudljivije rezultate. Korištenje stratifikacije dramatično smanjuje varijancu.

U slučajevima s jednakim srednjim vrijednostima i različitim varijancama, vidimo smanjenje varijance u Neymanovoj metodi.

Zaključak

Sada možete primijeniti metodu stratifikacije kako biste smanjili varijancu metrike i pojačali eksperiment ako svoju publiku grupirate i tehnički je nasumično podijelite unutar svake skupine s određenim težinama!