首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在scikit-learn和/或pandas中重新采样

在scikit-learn和/或pandas中重新采样
EN

Stack Overflow用户
提问于 2015-04-26 11:02:36
回答 3查看 10.6K关注 0票数 11

Pandas或Scikit-learn中是否有一个内置函数,用于根据指定的策略进行重采样?我想根据分类变量对我的数据进行重新采样。

例如,如果我的数据中有75%的男性和25%的女性,但我希望将我的模型训练成50%的男性和50%的女性。(我也希望能够推广到不是50/50的情况)

我需要的是根据指定的比例对我的数据进行重采样的东西。

EN

回答 3

Stack Overflow用户

发布于 2015-08-31 06:47:30

我尝试使用一个函数来做我想做的事情,如下。希望这对其他人有帮助。

假设Xy分别是熊猫DataFrame和系列。

代码语言:javascript
运行
复制
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
票数 2
EN

Stack Overflow用户

发布于 2018-03-14 08:48:39

如果您愿意导入库,我发现imbalanced-learn库在解决重采样问题时很有用。这里的分类变量是目标'y‘,要重采样的数据是'X’。在下面的例子中,对鱼进行了重新采样,使其与狗的数量相等,为3:3。

代码稍微修改了一下关于不平衡-learn:2.1.1. Naive random over-sampling的文档。您可以对数字数据和字符串使用此方法。

代码语言:javascript
运行
复制
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);  
票数 2
EN

Stack Overflow用户

发布于 2015-08-22 23:42:34

分层抽样意味着类分布被保留。只需使用变量而不是目标变量。例如,如果您在列i中有一个分类变量,

代码语言:javascript
运行
复制
skf = cross_validation.StratifiedKFold(X[:,i])

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

代码语言:javascript
运行
复制
sample_weights = sklearn.preprocessing.balance_weights(X[:,i])
clf = svm.SVC()
clf_weights.fit(X, y, sample_weight=sample_weights)

对于不均匀的目标分布,您必须相应地调整sample_weights。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29873224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档