繁体   English   中英

scikit-learn 中的不平衡

[英]Imbalance in scikit-learn

我在我的 Python 程序中使用 scikit-learn 来执行一些机器学习操作。 问题是我的数据集存在严重的不平衡问题。

有没有人熟悉 scikit-learn 或 python 中不平衡的解决方案? 在 Java 中有 SMOTE 机制。 python中有没有并行的东西?

这里有一个新的

https://github.com/scikit-learn-contrib/imbalanced-learn

它包含以下类别的许多算法,包括 SMOTE

  • 对多数类进行欠采样。
  • 对少数类进行过采样。
  • 结合过采样和欠采样。
  • 创建合奏平衡集。

在 Scikit learn 中,有一些不平衡校正技术,根据您使用的学习算法而有所不同。

其中一些,如Svm逻辑回归,具有class_weight参数。 如果您将此参数设置为'balanced'实例化一个SVC ,它将按每个类示例的频率的倒数按比例加权。

不幸的是,没有用于此目的的预处理器工具。

我在这里找到了另一个库,它实现了欠采样和多种过采样技术,包括多个SMOTE实现和另一个使用SVM

解决机器学习中不平衡数据集诅咒的 Python 包

SMOTE 不是 scikit-learn 中的内置函数,但仍有在线可用的实现。

编辑:与我最初链接的GMane上的SMOTE实现的讨论似乎不再可用。 代码保存在这里

@nos 下面的较新答案也很好。

由于其他人已经列出了非常流行的不平衡学习库的链接,我将概述如何正确使用它以及一些链接。

https://imbalanced-learn.org/en/stable/generated/imblearn.under_sampling.RandomUnderSampler.html

https://imbalanced-learn.org/en/stable/generated/imblearn.over_sampling.RandomOverSampler.html

https://imbalanced-learn.readthedocs.io/en/stable/generated/imblearn.over_sampling.SMOTE.html

https://imbalanced-learn.readthedocs.io/en/stable/auto_examples/over-sampling/plot_comparison_over_sampling.html#sphx-glr-auto-examples-over-sampling-plot-comparison-over-sampling-py

https://imbalanced-learn.org/en/stable/combine.html

不平衡学习中一些常见的过采样和欠采样技术是 imblearn.over_sampling.RandomOverSampler、imblearn.under_sampling.RandomUnderSampler 和 imblearn.SMOTE。 对于这些库,有一个很好的参数,允许用户更改采样率。

例如,在 SMOTE 中,要更改比率,您将输入字典,并且所有值必须大于或等于最大类(因为 SMOTE 是一种过采样技术)。 我发现 SMOTE 更适合模型性能的原因可能是因为使用 RandomOverSampler 可以复制行,这意味着模型可以开始记忆数据而不是泛化到新数据。 SMOTE 使用 K-Nearest-Neighbors 算法使“相似”数据点与采样数据点相似。

盲目使用 SMOTE,将比率设置为默认值(甚至类平衡)并不是一个好习惯,因为模型可能会过度拟合一个或多个少数类(即使 SMOTE 使用最近的邻居来进行“相似”的观察)。 以与调整 ML 模型的超参数类似的方式,您将调整 SMOTE 算法的超参数,例如比率和/或 knn。 以下是如何正确使用 SMOTE 的工作示例。

注意:不要在完整数据集上使用 SMOTE,这一点至关重要。 您必须仅在训练集上使用 SMOTE(拆分后)。 然后在您的 val/test 集上进行验证,看看您的 SMOTE 模型是否优于您的其他模型。 如果你不这样做,就会有数据泄露,你的模型本质上就是在作弊。

from collections import Counter
from sklearn.preprocessing import MinMaxScaler
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
import numpy as np
from xgboost import XGBClassifier
import warnings

warnings.filterwarnings(action='ignore', category=DeprecationWarning)
sm = SMOTE(random_state=0, n_jobs=8, ratio={'class1':100, 'class2':100, 'class3':80, 'class4':60, 'class5':90})

### Train test split
X_train, X_val, y_train, y_val = train_test_split(X, y)

### Scale the data before applying SMOTE
scaler = MinMaxScaler().fit(X_train)
X_train_scaled = scaler.transform(X_train)
X_val_scaled = scaler.transform(X_val)

### Resample X_train_scaled
X_train_resampled, y_train_resampled = sm.fit_sample(X_train_scaled, y_train)

print('Original dataset shape:', Counter(y_train))
print('Resampled dataset shape:', Counter(y_train_resampled))

### Train a model
xgbc_smote = XGBClassifier(n_jobs=8).fit(X_train_smote, y_train_smote,
                                         eval_set = [(X_val_scaled, y_val)],
                                         early_stopping_rounds=10)

### Evaluate the model
print('\ntrain\n')
print(accuracy_score(xgbc_smote.predict(np.array(X_train_scaled)), y_train))
print(f1_score(xgbc_smote.predict(np.array(X_train_scaled)), y_train))

print('\nval\n')
print(accuracy_score(xgbc_smote.predict(np.array(X_val_scaled)), y_val))
print(f1_score(xgbc_smote.predict(np.array(X_val_scaled)), y_val))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM