我正在寻找进行随机分层抽样(如调查和民意调查)的最佳方法。我不想做 sklearn.model_selection.StratifiedShuffleSplit 因为我没有做监督学习而且我没有目标。我只想从 pandas DataFrame (https://www.investopedia.com/terms/stratified_random_sampling.asp) 创建随机分层样本。
Python 是我的主要语言。
感谢您的帮助
鉴于变量已分箱,下面的一个衬里应该会为您提供所需的输出。我看到 scikit-learn 主要用于您以外的目的,但使用它的功能不会造成任何伤害。
请注意,如果您的 scikit-learn 版本早于 0.19.0,采样结果可能包含重复行。
如果您测试以下方法,请分享它是否按预期运行。
from sklearn.model_selection import train_test_split
stratified_sample, _ = train_test_split(population, test_size=0.999, stratify=population[['income', 'sex', 'age']])
这是我迄今为止最好的解决方案。重要的是在之前对连续变量进行分箱,并对每个层进行最少的观察。
在这个例子中,我是:
比较两个样本时,分层样本更能代表总体。
如果有人有更好的方法,请随时分享。
import pandas as pd
import numpy as np
# Generate random population (100K)
population = pd.DataFrame(index=range(0,100000))
population['income'] = 0
population['income'].iloc[39000:80000] = 1
population['income'].iloc[80000:] = 2
population['sex'] = np.random.randint(0,2,100000)
population['age'] = np.random.randint(0,4,100000)
pop_count = population.groupby(['income', 'sex', 'age'])['income'].count()
# Random sampling (100 observations out of 100k)
random_sample = population.iloc[
np.random.randint(
0,
len(population),
int(len(population) / 1000)
)
]
# Random Stratified Sampling (100 observations out of 100k)
stratified_sample = list(map(lambda x : population[
(
population['income'] == pop_count.index[x][0]
)
&
(
population['sex'] == pop_count.index[x][1]
)
&
(
population['age'] == pop_count.index[x][2]
)
].sample(frac=0.001), range(len(pop_count))))
stratified_sample = pd.concat(stratified_sample)
您可以在没有 scikit-learn 的情况下使用类似于此的函数来执行此操作:
import pandas as pd
import numpy as np
def stratified_sampling(df, strata_col, sample_size):
groups = df.groupby(strata_col)
sample = pd.DataFrame()
for _, group in groups:
stratum_sample = group.sample(frac=sample_size, replace=False, random_state=7)
sample = sample.append(stratum_sample)
return sample
在上面:
然后您可以按如下方式调用
stratified_sampling
:
sample = stratified_sampling(df_to_be_sampled, 'gender', 0.2)
这将返回一个名为 sample 的新 DataFrame,其中包含随机采样的数据。请注意,我选择了
random_state=7
进行测试和再现性,但这当然是任意的。