![Search icon](https://hackernoon.imgix.net/search-new.png?w=19&h=19)
Sebarang percubaan melibatkan pertukaran antara keputusan pantas dan kepekaan metrik. Jika metrik yang dipilih adalah luas dari segi varians, kita mesti menunggu lama untuk memastikan keputusan percubaan adalah tepat. Mari kita pertimbangkan satu kaedah untuk membantu penganalisis meningkatkan percubaan mereka tanpa kehilangan terlalu banyak masa atau sensitiviti metrik.
Katakan kita menjalankan percubaan standard untuk menguji algoritma kedudukan baharu, dengan panjang sesi sebagai metrik utama. Selain itu, pertimbangkan bahawa khalayak kami boleh dikategorikan secara kasar kepada tiga kumpulan: 1 juta remaja, 2 juta pengguna berumur 18-45 dan 3 juta pengguna berumur 45 tahun ke atas. Sambutan kepada algoritma kedudukan baharu akan berbeza dengan ketara dalam kalangan kumpulan khalayak ini. Variasi luas ini mengurangkan sensitiviti metrik.
Dengan kata lain, populasi boleh dibahagikan kepada tiga strata, yang diterangkan seperti berikut:
Katakan setiap komponen mempunyai taburan normal. Kemudian, metrik utama untuk populasi juga mempunyai taburan normal.
Kami membahagikan semua pengguna daripada populasi secara rawak dalam reka bentuk percubaan klasik tanpa mengambil kira perbezaan antara pengguna kami. Oleh itu, kami menganggap sampel dengan nilai dan varians yang dijangkakan berikut.
Cara lain ialah membahagikan secara rawak di dalam setiap strat mengikut berat strat dalam populasi umum.
Dalam kes ini, nilai dan varians yang dijangkakan adalah seperti berikut.
Nilai yang dijangkakan adalah sama seperti dalam pilihan pertama. Walau bagaimanapun, varians adalah kurang, yang menjamin sensitiviti metrik yang lebih tinggi.
Sekarang, mari kita pertimbangkan kaedah Neyman . Mereka mencadangkan untuk membahagikan pengguna secara rawak di dalam setiap strat dengan berat tertentu.
Jadi, nilai dan varians yang dijangkakan adalah sama dengan yang berikut dalam kes ini.
Nilai jangkaan adalah sama dengan nilai jangkaan dalam kes pertama secara asimptotik. Walau bagaimanapun, varians adalah lebih kurang.
Kami telah membuktikan kecekapan kaedah ini secara teori. Mari kita simulasi sampel dan uji kaedah stratifikasi secara empirik.
Mari kita pertimbangkan tiga kes:
Kami akan menggunakan ketiga-tiga kaedah dalam semua kes dan memplot histogram dan boxplot untuk membandingkannya.
Mula-mula, mari kita cipta kelas dalam Python yang menyerupai populasi umum kita yang terdiri daripada tiga strat.
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]
Kemudian, mari tambah fungsi untuk tiga kaedah persampelan yang diterangkan dalam bahagian teori.
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
Juga, untuk bahagian empirikal, kita sentiasa memerlukan fungsi untuk mensimulasikan proses eksperimen.
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
Jika kita melihat populasi umum, di mana semua strat kita mempunyai nilai dan varians yang sama, keputusan ketiga-tiga kaedah dijangka lebih kurang sama.
Cara yang berbeza dan varians yang sama memperoleh hasil yang lebih menarik. Menggunakan stratifikasi secara mendadak mengurangkan varians.
Dalam kes dengan cara yang sama dan varians yang berbeza, kita melihat pengurangan varians dalam kaedah Neyman.
Kini, anda boleh menggunakan kaedah stratifikasi untuk mengurangkan varians metrik dan meningkatkan percubaan jika anda mengelompokkan khalayak anda dan secara teknikal membahagikannya secara rawak di dalam setiap kelompok dengan pemberat tertentu!