paint-brush
Použitie stratifikačnej metódy na experimentálnu analýzupodľa@nataliaogneva
33,155 čítania
33,155 čítania

Použitie stratifikačnej metódy na experimentálnu analýzu

podľa Natalia Ogneva8m2024/04/19
Read on Terminal Reader
Read this story w/o Javascript

Príliš dlho; Čítať

Stratifikované vzorkovanie je výkonná technika na zvýšenie účinnosti experimentu a metrickej citlivosti pri analýze údajov. Zoskupením publika a jeho rozdelením podľa konkrétnych váh môžete optimalizovať experimenty, znížiť rozptyl a zvýšiť spoľahlivosť výsledkov.

Company Mentioned

Mention Thumbnail
featured image - Použitie stratifikačnej metódy na experimentálnu analýzu
Natalia Ogneva HackerNoon profile picture
0-item


Každý experiment zahŕňa kompromis medzi rýchlymi výsledkami a metrickou citlivosťou. Ak je zvolená metrika široká, pokiaľ ide o rozptyl, musíme dlho čakať, aby sme sa uistili, že výsledky experimentu sú presné. Uvažujme o jednej metóde, ktorá pomôže analytikom zintenzívniť experimenty bez straty príliš veľa času alebo metrickej citlivosti.


Formulácia problému

Predpokladajme, že vykonáme štandardný experiment na testovanie nového hodnotiaceho algoritmu s dĺžkou relácie ako primárnou metrikou. Okrem toho si uvedomte, že naše publikum možno zhruba rozdeliť do troch skupín: 1 milión tínedžerov, 2 milióny používateľov vo veku 18 – 45 rokov a 3 milióny používateľov vo veku 45 a viac rokov. Reakcia na nový algoritmus hodnotenia by sa medzi týmito skupinami publika výrazne líšila. Táto široká variácia znižuje citlivosť metriky.


Inými slovami, obyvateľstvo možno rozdeliť do troch vrstiev, ktoré sú opísané nasledovne:


Povedzme, že každý komponent má normálne rozdelenie. Hlavná metrika pre populáciu má potom tiež normálne rozdelenie.

Stratifikačná metóda

Náhodne rozdeľujeme všetkých používateľov z populácie v klasickom dizajne experimentu bez toho, aby sme zohľadnili rozdiely medzi našimi používateľmi. Preto uvažujeme vzorku s nasledujúcou očakávanou hodnotou a rozptylom.


Ďalším spôsobom je náhodné rozdelenie vnútri každej vrstvy podľa váhy vrstvy vo všeobecnej populácii.

V tomto prípade očakávaná hodnota a rozptyl sú nasledujúce.


Očakávaná hodnota je rovnaká ako pri prvom výbere. Rozptyl je však menší, čo zaručuje vyššiu metrickú citlivosť.

Teraz sa pozrime na Neymanovu metódu . Navrhujú rozdeliť používateľov náhodne v rámci každej vrstvy so špecifickými váhami.

Takže očakávaná hodnota a rozptyl sa v tomto prípade rovnajú nasledujúcim.

Očakávaná hodnota sa rovná očakávanej hodnote v prvom prípade asymptoticky. Rozptyl je však oveľa menší.

Empirické testovanie

Teoreticky sme dokázali účinnosť tejto metódy. Simulujme vzorky a empiricky otestujme metódu stratifikácie.

Zoberme si tri prípady:

  • všetky vrstvy s rovnakými prostriedkami a odchýlkami,
  • všetky vrstvy s rôznymi prostriedkami a rovnakými odchýlkami,
  • všetky vrstvy s rovnakými prostriedkami a rôznymi rozptylmi.

Použijeme všetky tri metódy vo všetkých prípadoch a vykreslíme histogram a boxplot na ich porovnanie.

Príprava kódu

Najprv vytvorte triedu v Pythone, ktorá simuluje našu všeobecnú populáciu pozostávajúcu z troch vrstiev.

 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]


Potom pridajme funkcie pre tri metódy vzorkovania opísané v teoretickej časti.

 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


Pre empirickú časť tiež vždy potrebujeme funkciu na simuláciu procesu experimentu.

 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


Výsledky simulácie

Ak sa pozrieme na všeobecnú populáciu, kde všetky naše vrstvy majú rovnaké hodnoty a rozptyly, očakáva sa, že výsledky všetkých troch metód budú viac-menej rovnaké.

Rôzne priemery a rovnaké rozdiely dosiahli vzrušujúcejšie výsledky. Použitie stratifikácie dramaticky znižuje rozptyl.

V prípadoch s rovnakými priemermi a rôznymi rozptylmi vidíme v Neymanovej metóde zníženie rozptylu.

Záver

Teraz môžete použiť metódu stratifikácie na zníženie metrických rozptylov a zintenzívnenie experimentu, ak zoskupíte svoje publikum a technicky ho náhodne rozdelíte do každého zoskupenia so špecifickými váhami!