Python 在scikit学习和/或熊猫中重新采样

Python 在scikit学习和/或熊猫中重新采样,python,pandas,scikit-learn,Python,Pandas,Scikit Learn,Pandas或Scikit learn中是否有内置功能,用于根据特定策略重新采样?我想根据分类变量对数据重新采样 例如,如果我的数据中有75%的男性和25%的女性,但我想用50%的男性和50%的女性来训练我的模型。(我还希望能够推广到非50/50的情况) 我需要的是按照指定的比例对数据进行重新采样。分层采样意味着保留类别分布。如果您正在寻找这一点,您仍然可以使用StratifiedKFold和StratifiedShuffleSplit,只要您有一个分类变量,您希望确保在每个折叠中具有相同的分布

Pandas或Scikit learn中是否有内置功能,用于根据特定策略重新采样?我想根据分类变量对数据重新采样

例如,如果我的数据中有75%的男性和25%的女性,但我想用50%的男性和50%的女性来训练我的模型。(我还希望能够推广到非50/50的情况)


我需要的是按照指定的比例对数据进行重新采样。

分层采样意味着保留类别分布。如果您正在寻找这一点,您仍然可以使用
StratifiedKFold
StratifiedShuffleSplit
,只要您有一个分类变量,您希望确保在每个折叠中具有相同的分布。只需使用变量而不是目标变量。例如,如果在列
i
中有一个分类变量

skf = cross_validation.StratifiedKFold(X[:,i])
但是,如果我理解正确,您希望对其中一个分类特征的特定目标分布(例如50/50)重新采样。我想您必须想出自己的方法来获得这样的样本(按变量值分割数据集,然后从每次分割中获取相同数量的随机样本)。如果您的主要动机是平衡分类器的训练集,那么一个技巧可能是调整
样本权重
。您可以设置权重,使其根据所需变量平衡训练集:

sample_weights = sklearn.preprocessing.balance_weights(X[:,i])
clf = svm.SVC()
clf_weights.fit(X, y, sample_weight=sample_weights)

对于非均匀目标分布,您必须相应地调整样本权重。

下面是我对函数的尝试。希望这对其他人有帮助

假设
X
y
分别为数据帧和序列

def resample(X, y, sample_type=None, sample_size=None, class_weights=None, seed=None):

    # Nothing to do if sample_type is 'abs' or not set.  sample_size should then be int
    # If sample type is 'min' or 'max' then sample_size should be float
    if sample_type == 'min':
        sample_size_ = np.round(sample_size * y.value_counts().min()).astype(int)
    elif sample_type == 'max':
        sample_size_ = np.round(sample_size * y.value_counts().max()).astype(int)
    else:
        sample_size_ = max(int(sample_size), 1)

    if seed is not None:
        np.random.seed(seed)

    if class_weights is None:
        class_weights = dict()

    X_resampled = pd.DataFrame()

    for yi in y.unique():
        size = np.round(sample_size_ * class_weights.get(yi, 1.)).astype(int)

        X_yi = X[y == yi]
        sample_index = np.random.choice(X_yi.index, size=size)
        X_resampled = X_resampled.append(X_yi.reindex(sample_index))

    return X_resampled

如果您愿意导入库,我发现该库在处理重采样时非常有用。这里,分类变量是目标“y”,要重新采样的数据是“X”。在下面的例子中,鱼被重新取样,使其与狗的数量相等,3:3

该代码根据以下日期的文档稍微修改:。您可以将此方法用于数字数据和字符串

import numpy as np  
from collections import Counter  
from imblearn.over_sampling import RandomOverSampler  

y = np.array([1,1,0,0,0]); # Fish / Dog  
print('target:\n', y)  
X = np.array([['red fish'],['blue fish'],['dog'],['dog'],['dog']]);  
print('data:\n',X);  

print('Original dataset shape {}'.format(Counter(y))) # Original dataset shape Counter({1: 900, 0: 100})  
print(type(X)); print(X);  
print(y);  

ros = RandomOverSampler(ratio='auto', random_state=42);  
X_res, y_res = ros.fit_sample(X, y);  

print('Resampled dataset shape {}'.format(Counter(y_res))) # Resampled dataset shape Counter({0: 900, 1: 900});  
print(type(X_res)); print(X_res); print(y_res);  

此外,您还可以提供一些带有各种参数的示例进行说明。