我有一个pandas DataFrame,看起来大致如下:
cli_id | X1 | X2 | X3 | ... | Xn | Y |
----------------------------------------
123 | 1 | A | XX | ... | 4 | 0.1 |
456 | 2 | B | XY | ... | 5 | 0.2 |
789 | 1 | B | XY | ... | 5 | 0.3 |
101 | 2 | A | XX | ... | 4 | 0.1 |
...
Run Code Online (Sandbox Code Playgroud)
我有客户端ID,很少有分类属性,Y是事件的概率,其值从0到1乘以0.1.
我需要在每个组(10倍)的大小为200的Y中采取分层样本
在分成火车/测试时,我经常使用它来分层样本:
def stratifiedSplit(X,y,size):
sss = StratifiedShuffleSplit(y, n_iter=1, test_size=size, random_state=0)
for train_index, test_index in sss:
X_train, X_test = X.iloc[train_index], X.iloc[test_index]
y_train, y_test = y.iloc[train_index], y.iloc[test_index]
return X_train, X_test, y_train, y_test
Run Code Online (Sandbox Code Playgroud)
但在这种情况下我不知道如何修改它.
Qui*_*2k1 17
如果每个组的样本数相同,或者每个组的比例是恒定的,您可以尝试类似的方法
df.groupby('Y').apply(lambda x: x.sample(n=200))
Run Code Online (Sandbox Code Playgroud)
要么
df.groupby('Y').apply(lambda x: x.sample(frac=.1))
Run Code Online (Sandbox Code Playgroud)
要针对多个变量执行分层抽样,只需对更多变量进行分组.为此可能需要构造新的分箱变量.
但是,如果组大小太小,比例如groupize 1和propotion .25,则不会返回任何项目.这是由于pythons舍入int函数的实现int(0.25)=0
我不完全确定你是否是这个意思:
strats = []
for k in range(11):
y_val = k*0.1
dummy_df = your_df[your_df['Y'] == y_val]
stats.append( dummy_df.sample(200) )
Run Code Online (Sandbox Code Playgroud)
这会生成一个仅包含Y您想要的值的虚拟数据帧,然后抽取 200 个样本。
好的,所以您需要不同的块具有相同的结构。我想这有点难,我会这样做:
首先,我会得到一个直方图,如下所示X1:
hist, edges = np.histogram(your_df['X1'], bins=np.linespace(min_x, max_x, nbins))
Run Code Online (Sandbox Code Playgroud)
我们现在有了一个nbins带箱的直方图。
现在的策略是根据行的值绘制一定数量的行X1。X我们将从观察较多的箱中抽取更多的数据,并从观察较少的箱中抽取较少的数据,从而保留的结构。
特别是,每个 bin 的相对贡献应该是:
rel = [float(i) / sum(hist) for i in hist]
Run Code Online (Sandbox Code Playgroud)
这会是这样的[0.1, 0.2, 0.1, 0.3, 0.3]
如果我们想要200个样本,我们需要绘制:
draws_in_bin = [int(i*200) for i in rel]
Run Code Online (Sandbox Code Playgroud)
现在我们知道要从每个箱中抽取多少个观测值:
strats = []
for k in range(11):
y_val = k*0.1
#get a dataframe for every value of Y
dummy_df = your_df[your_df['Y'] == y_val]
bin_strat = []
for left_edge, right_edge, n_draws in zip(edges[:-1], edges[1:], draws_in_bin):
bin_df = dummy_df[ (dummy_df['X1']> left_edge)
& (dummy_df['X1']< right_edge) ]
bin_strat.append(bin_df.sample(n_draws))
# this takes the right number of draws out
# of the X1 bin where we currently are
# Note that every element of bin_strat is a dataframe
# with a number of entries that corresponds to the
# structure of draws_in_bin
#
#concatenate the dataframes for every bin and append to the list
strats.append( pd.concat(bin_strat) )
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11805 次 |
| 最近记录: |