paint-brush
Выкарыстанне метаду стратыфікацыі для эксперыментальнага аналізупа@nataliaogneva
33,172 чытанні
33,172 чытанні

Выкарыстанне метаду стратыфікацыі для эксперыментальнага аналізу

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

Занадта доўга; Чытаць

Стратыфікаваная выбарка - гэта магутны метад для павышэння эфектыўнасці эксперыментаў і адчувальнасці паказчыкаў пры аналізе даных. Аб'ядноўваючы вашу аўдыторыю ў кластары і падзяляючы яе з пэўнымі вагамі, вы можаце аптымізаваць эксперыменты, паменшыць дысперсію і павысіць надзейнасць вынікаў.

Company Mentioned

Mention Thumbnail
featured image - Выкарыстанне метаду стратыфікацыі для эксперыментальнага аналізу
Natalia Ogneva HackerNoon profile picture
0-item


Любы эксперымент прадугледжвае кампраміс паміж хуткімі вынікамі і адчувальнасцю метрыкі. Калі абраная метрыка шырокая з пункту гледжання дысперсіі, мы павінны чакаць доўгі час, каб пераканацца, што вынікі эксперыменту дакладныя. Давайце разгледзім адзін метад, які дапаможа аналітыкам палепшыць свае эксперыменты, не губляючы занадта шмат часу або адчувальнасці паказчыкаў.


Пастаноўка задачы

Выкажам здагадку, што мы праводзім стандартны эксперымент для праверкі новага алгарытму ранжыравання з працягласцю сесіі ў якасці асноўнага паказчыка. Акрамя таго, улічыце, што нашу аўдыторыю можна ўмоўна падзяліць на тры групы: 1 мільён падлеткаў, 2 мільёны карыстальнікаў ва ўзросце 18-45 гадоў і 3 мільёны карыстальнікаў ва ўзросце 45 гадоў і старэй. Рэакцыя на новы алгарытм ранжыравання будзе значна адрознівацца сярод гэтых груп аўдыторыі. Такі шырокі варыянт зніжае адчувальнасць метрыкі.


Іншымі словамі, насельніцтва можна падзяліць на тры пласты, апісаныя наступным чынам:


Скажам, кожны кампанент мае нармальнае размеркаванне. Тады асноўны паказчык для сукупнасці таксама мае нармальнае размеркаванне.

Метад стратыфікацыі

Мы выпадковым чынам дзелім усіх карыстальнікаў з сукупнасці ў класічным дызайне эксперыменту, не ўлічваючы адрозненняў паміж нашымі карыстальнікамі. Такім чынам, мы разглядаем выбарку з наступным чаканым значэннем і дысперсіяй.


Іншы спосаб - гэта выпадковае дзяленне ўнутры кожнай страты ў залежнасці ад вагі страты ў агульнай сукупнасці.

У гэтым выпадку чаканае значэнне і дысперсія наступныя.


Чаканае значэнне такое ж, як і ў першым выбары. Аднак дысперсія меншая, што гарантуе больш высокую адчувальнасць метрыкі.

Зараз давайце разгледзім метад Нэймана . Яны прапануюць выпадковым чынам падзяліць карыстальнікаў у кожнай страце з пэўнай вагай.

Такім чынам, чаканае значэнне і дысперсія ў гэтым выпадку роўныя наступным.

чаканае значэнне роўна чаканаму значэнню ў першым выпадку асімптатычна. Аднак розніца значна меншая.

Эмпірычнае тэставанне

Эфектыўнасць гэтага метаду мы даказалі тэарэтычна. Давайце змадэлюем узоры і эмпірычна праверым метад стратыфікацыі.

Разгледзім тры выпадкі:

  • усе страты з роўнымі сярэднімі і дысперсіямі,
  • усе страты з рознымі сярэднімі і аднолькавымі дысперсіямі,
  • усе страты з аднолькавымі сярэднімі і рознымі дысперсіямі.

Мы будзем прымяняць усе тры метады ва ўсіх выпадках і пабудаваць гістаграму і скрынкавы графік для іх параўнання.

Падрыхтоўка кода

Спачатку давайце створым клас на Python, які імітуе нашу генеральную сукупнасць, якая складаецца з трох страт.

 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]


Затым дадамо функцыі для трох метадаў выбаркі, апісаных у тэарэтычнай частцы.

 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


Акрамя таго, для эмпірычнай часткі нам заўсёды патрэбна функцыя для мадэлявання працэсу эксперыменту.

 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


Вынікі мадэлявання

Калі мы паглядзім на агульную сукупнасць, дзе ўсе нашы страты маюць аднолькавыя значэнні і дысперсіі, чакаецца, што вынікі ўсіх трох метадаў будуць больш-менш аднолькавымі.

Розныя сярэднія і роўныя дысперсіі давалі больш захапляльныя вынікі. Выкарыстанне стратыфікацыі значна памяншае дысперсію.

У выпадках з аднолькавымі сярэднімі і рознымі дысперсіямі мы бачым памяншэнне дысперсіі ў метадзе Нэймана.

Заключэнне

Цяпер вы можаце ўжыць метад стратыфікацыі, каб паменшыць дысперсію метрыкі і павысіць эксперымент, калі вы згрупуеце сваю аўдыторыю і тэхнічна падзяліце яе выпадковым чынам у кожным кластары з пэўнымі вагамі!