paint-brush
Stratifikaatiomenetelmän käyttäminen kokeen analyysissäkirjoittaja@nataliaogneva
33,138 lukemat
33,138 lukemat

Stratifikaatiomenetelmän käyttäminen kokeen analyysissä

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

Liian pitkä; Lukea

Ositettu näytteenotto on tehokas tekniikka kokeiden tehokkuuden ja metrisen herkkyyden parantamiseksi data-analyysissä. Klusteroimalla yleisösi ja jakamalla ne tietyillä painoilla voit optimoida kokeilut, vähentää varianssia ja parantaa tulosten luotettavuutta.

Company Mentioned

Mention Thumbnail
featured image - Stratifikaatiomenetelmän käyttäminen kokeen analyysissä
Natalia Ogneva HackerNoon profile picture
0-item


Kaikki kokeilut sisältävät kompromissin nopeiden tulosten ja metrisen herkkyyden välillä. Jos valittu mittari on varianssiltaan laaja, meidän on odotettava pitkään varmistaaksemme, että kokeilun tulokset ovat tarkkoja. Tarkastellaanpa yhtä menetelmää, jolla analyytikot voivat tehostaa kokeitaan menettämättä liikaa aikaa tai metristä herkkyyttä.


Ongelman muotoilu

Oletetaan, että suoritamme tavallisen kokeen testataksemme uutta sijoitusalgoritmia, jossa istunnon pituus on ensisijainen mittari. Lisäksi katsomme, että yleisömme voidaan karkeasti luokitella kolmeen ryhmään: 1 miljoona teini-ikäistä, 2 miljoonaa 18–45-vuotiasta käyttäjää ja 3 miljoonaa 45-vuotiasta ja sitä vanhempia käyttäjää. Reaktio uuteen sijoitusalgoritmiin vaihtelisi merkittävästi näiden yleisöryhmien välillä. Tämä laaja vaihtelu vähentää metriikan herkkyyttä.


Toisin sanoen väestö voidaan jakaa kolmeen kerrokseen, jotka kuvataan seuraavassa:


Oletetaan, että jokaisella komponentilla on normaalijakauma. Tällöin myös perusjoukon päämittarilla on normaalijakauma.

Stratifikaatiomenetelmä

Jaamme satunnaisesti kaikki käyttäjät populaatiosta klassiseen kokeilusuunnitelmaan ottamatta huomioon käyttäjiemme välisiä eroja. Näin ollen tarkastelemme otosta seuraavalla odotusarvolla ja varianssilla.


Toinen tapa on jakaa satunnaisesti jokaisen stratin sisällä osion painon mukaan yleisväestössä.

Tässä tapauksessa odotusarvo ja varianssi ovat seuraavat.


Odotettu arvo on sama kuin ensimmäisessä valinnassa. Varianssi on kuitenkin pienempi, mikä takaa korkeamman metrisen herkkyyden.

Tarkastellaan nyt Neymanin menetelmää . He ehdottavat, että käyttäjät jaetaan satunnaisesti jokaisen kerroksen sisällä tietyillä painoilla.

Joten odotusarvo ja varianssi ovat tässä tapauksessa yhtä suuret kuin seuraavat.

Odotusarvo on sama kuin odotusarvo ensimmäisessä tapauksessa asymptoottisesti. Ero on kuitenkin paljon pienempi.

Empiirinen testaus

Olemme todistaneet tämän menetelmän tehokkuuden teoreettisesti. Simuloitetaan näytteitä ja testataan kerrostusmenetelmää empiirisesti.

Tarkastellaan kolmea tapausta:

  • kaikki stratit yhtäläisin keskiarvoin ja vaihteluin,
  • kaikki stratit eri keskiarvoilla ja yhtäläisillä varianssilla,
  • kaikki osuudet samalla keskiarvolla ja eri varianssilla.

Käytämme kaikkia kolmea menetelmää kaikissa tapauksissa ja piirrämme histogrammin ja boxplotin vertaillaksemme niitä.

Koodin valmistelu

Luodaan ensin Pythonissa luokka, joka simuloi yleistä populaatiota, joka koostuu kolmesta kerroksesta.

 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]


Lisätään sitten funktioita kolmelle teoreettisessa osassa kuvatulle näytteenottomenetelmälle.

 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


Lisäksi empiiristä osaa varten tarvitsemme aina funktion koeprosessin simuloimiseksi.

 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


Simulaatiotulokset

Jos katsomme yleistä populaatiota, jossa kaikilla ositteillamme on samat arvot ja varianssit, kaikkien kolmen menetelmän tulosten odotetaan olevan suurin piirtein samat.

Erilaiset keskiarvot ja yhtäläiset varianssit tuottivat jännittävämpiä tuloksia. Kerrostuksen käyttö vähentää dramaattisesti varianssia.

Tapauksissa, joilla on samat keskiarvot ja erilaiset varianssit, näemme Neymanin menetelmässä varianssin pienenemisen.

Johtopäätös

Nyt voit käyttää kerrostusmenetelmää pienentääksesi metrien varianssia ja tehostaaksesi kokeilua, jos ryhmittelet yleisösi ja jaat ne teknisesti satunnaisesti kunkin klusterin sisällä tietyillä painoilla!