我有一个pandas数据框,名为 ratings_full
的形式。
userID nr_votes
123 12
124 14
234 22
346 35
763 45
238 1
127 17
我想对这个数据框进行抽样,因为它包含了数万个用户。我想提取100个用户,但要以某种方式优先考虑那些值较低的用户。nr_votes
,而不只对它们进行抽样。所以,一种 "分层抽样 "对 nr_votes
. 这可能吗?
这是我目前所能做到的。
SAMPLING_FRACTION = 0.0007
uid_samples = ratings_top['userId'] \
.drop_duplicates() \
.sample(frac=SAMPLING_FRACTION,
replace=False,
random_state=1)
ratings_sample = pd.merge(ratings_full, uid_samples, on='userId', how='inner')
这只是提供了一个随机抽样 userID
的,但没有办法确保抽样是以某种方式分层的。
EDIT: 我甚至很高兴,如果我们能分了这笔钱 nr_votes
成N个桶,我们对桶进行分层采样。
编辑2 我现在正在尝试这个。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X=ratings_full.drop([nr_votes], axis=1),
y=ratings_full.nr_votes,
test_size=0.33,
random_state=42,
stratify=y)
然后我必须把数据框重新组合起来。这不是一个理想的答案,但它可能会工作。我甚至会试着先把数据框扣起来,然后用数据框的列作为我的 "标签"。
我们可以这样做 np.random.choice
通过做索引切片
n = len(ratings_top)
idx = np.random.choice(ratings_top.index.values, p=ratings_top['probability'], size=n*0.0007, replace=True)
然后
sample_df = df.loc[idx].copy()
from sklearn.model_selection import StratifiedShuffleSplit
n_splits = 1
sss = model_selection.StratifiedShuffleSplit(n_splits=n_splits,
test_size=0.1,
random_state=42)
train_idx, test_idx = list(sss.split(X, y))[0]