Pandas或Scikit-learn中是否有一个内置函数,用于根据指定的策略进行重采样?我想根据分类变量对我的数据进行重新采样。
例如,如果我的数据中有75%的男性和25%的女性,但我希望将我的模型训练成50%的男性和50%的女性。(我也希望能够推广到不是50/50的情况)
我需要的是根据指定的比例对我的数据进行重采样的东西。
发布于 2015-08-31 06:47:30
我尝试使用一个函数来做我想做的事情,如下。希望这对其他人有帮助。
假设X
和y
分别是熊猫DataFrame和系列。
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
发布于 2018-03-14 08:48:39
如果您愿意导入库,我发现imbalanced-learn库在解决重采样问题时很有用。这里的分类变量是目标'y‘,要重采样的数据是'X’。在下面的例子中,对鱼进行了重新采样,使其与狗的数量相等,为3:3。
代码稍微修改了一下关于不平衡-learn:2.1.1. Naive random over-sampling的文档。您可以对数字数据和字符串使用此方法。
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);
发布于 2015-08-22 23:42:34
分层抽样意味着类分布被保留。只需使用变量而不是目标变量。例如,如果您在列i
中有一个分类变量,
skf = cross_validation.StratifiedKFold(X[:,i])
但是,如果我理解正确的话,您希望对某个分类特征的特定目标分布(例如50/50)进行重新采样。我猜你必须想出你自己的方法来获得这样的样本(按变量值拆分数据集,然后从每次拆分中随机抽取相同数量的样本)。如果你的主要动机是平衡分类器的训练集,一个技巧可能是调整sample_weights
。您可以设置权重,使其根据所需的变量平衡训练集:
sample_weights = sklearn.preprocessing.balance_weights(X[:,i])
clf = svm.SVC()
clf_weights.fit(X, y, sample_weight=sample_weights)
对于不均匀的目标分布,您必须相应地调整sample_weights。
https://stackoverflow.com/questions/29873224
复制相似问题