هر آزمایشی شامل یک مبادله بین نتایج سریع و حساسیت متریک است. اگر متریک انتخابی از نظر واریانس وسیع باشد، باید مدت زیادی منتظر بمانیم تا از صحت نتایج آزمایش مطمئن شویم. بیایید یک روش را در نظر بگیریم تا به تحلیلگران کمک کنیم تا آزمایشات خود را بدون از دست دادن زمان یا حساسیت متریک زیاد افزایش دهند.
فرض کنید یک آزمایش استاندارد برای آزمایش یک الگوریتم رتبهبندی جدید، با طول جلسه به عنوان متریک اولیه، انجام میدهیم. علاوه بر این، در نظر بگیرید که مخاطبان ما را میتوان تقریباً به سه گروه دستهبندی کرد: 1 میلیون نوجوان، 2 میلیون کاربر 18 تا 45 ساله و 3 میلیون کاربر 45 سال و بالاتر. پاسخ به یک الگوریتم رتبه بندی جدید به طور قابل توجهی در بین این گروه های مخاطب متفاوت است. این تنوع گسترده حساسیت متریک را کاهش می دهد.
به عبارت دیگر، جمعیت را می توان به سه قشر تقسیم کرد که به شرح زیر است:
فرض کنید که هر جزء دارای توزیع نرمال است. سپس، معیار اصلی برای جمعیت نیز دارای توزیع نرمال است.
ما به طور تصادفی همه کاربران را از جمعیت در یک طرح آزمایشی کلاسیک بدون در نظر گرفتن تفاوتهای بین کاربران خود تقسیم میکنیم . بنابراین، نمونه را با مقدار و واریانس مورد انتظار زیر در نظر می گیریم.
روش دیگر تقسیم تصادفی درون هر لایه بر اساس وزن لایه در جمعیت عمومی است.
در این حالت مقدار و واریانس مورد انتظار به شرح زیر است.
مقدار مورد انتظار مانند انتخاب اول است. با این حال، واریانس کمتر است، که حساسیت متریک بالاتر را تضمین می کند.
حالا بیایید روش نیمان را در نظر بگیریم. آنها پیشنهاد می کنند که کاربران را به طور تصادفی در هر لایه با وزن های خاص تقسیم کنید.
بنابراین، مقدار و واریانس مورد انتظار در این مورد برابر با زیر است.
مقدار مورد انتظار برابر با مقدار مورد انتظار در حالت اول مجانبی است. با این حال، واریانس بسیار کمتر است.
ما کارایی این روش را به صورت تئوری ثابت کرده ایم. بیایید نمونه ها را شبیه سازی کنیم و روش طبقه بندی را به صورت تجربی آزمایش کنیم.
بیایید سه مورد را در نظر بگیریم:
ما هر سه روش را در همه موارد اعمال خواهیم کرد و یک هیستوگرام و باکس پلات برای مقایسه آنها ترسیم می کنیم.
ابتدا، بیایید یک کلاس در پایتون ایجاد کنیم که جمعیت عمومی ما متشکل از سه لایه را شبیه سازی کند.
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
اگر به جمعیت عمومی نگاه کنیم، جایی که همه لایههای ما دارای مقادیر و واریانسهای یکسان هستند، انتظار میرود نتایج هر سه روش کم و بیش برابر باشد.
میانگین های مختلف و واریانس های مساوی نتایج هیجان انگیزتری به دست آوردند. استفاده از طبقه بندی به طور چشمگیری واریانس را کاهش می دهد.
در مواردی با میانگین های مساوی و واریانس های متفاوت، شاهد کاهش واریانس در روش نیمن هستیم.
اکنون، اگر مخاطبان خود را خوشه بندی کنید و آنها را به صورت تصادفی در داخل هر خوشه با وزن های خاص تقسیم کنید، می توانید از روش طبقه بندی برای کاهش واریانس متریک و تقویت آزمایش استفاده کنید!