scikit-learn中的不平衡

时间:2013-02-25 11:23:10

标签: python scikit-learn

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

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

5 个答案:

答案 0 :(得分:71)

这里有一个新的

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

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

  • 对大多数班级进行抽样调查。
  • 对少数民族的过度抽样。
  • 结合过度采样和欠采样。
  • 创建合奏平衡集。

答案 1 :(得分:27)

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

其中某些内容(如Svmlogistic regression)具有class_weight参数。如果您使用SVC上设置的此参数设置'auto'实例化,则会按比例对每个类示例的频率进行加权。

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

答案 2 :(得分:14)

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

A Python Package to Tackle the Curse of Imbalanced Datasets in Machine Learning

答案 3 :(得分:5)

SMOTE不是scikit-learn中的内置,但仍有在线实现。
例如Here

答案 4 :(得分:0)

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

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(即在拆分后),然后在验证集和测试集上进行验证,以查看您的SMOTE模型是否执行了其他模型。如果不这样做,将导致数据泄漏,并且您将获得一个完全不相关的模型。

from collections import Counter
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})
X_resampled, y_resampled = sm.fit_sample(X_normalized, y)

print('Original dataset shape:', Counter(y))
print('Resampled dataset shape:', Counter(y_resampled))

X_train_smote, X_test_smote, y_train_smote, y_test_smote = train_test_split(X_resampled, y_resampled)
X_train_smote.shape, X_test_smote.shape, y_train_smote.shape, y_test_smote.shape, X_resampled.shape, y_resampled.shape

smote_xgbc = XGBClassifier(n_jobs=8).fit(X_train_smote, y_train_smote)

print('TRAIN')
print(accuracy_score(smote_xgbc.predict(np.array(X_train_normalized)), y_train))
print(f1_score(smote_xgbc.predict(np.array(X_train_normalized)), y_train))

print('TEST')
print(accuracy_score(smote_xgbc.predict(np.array(X_test_normalized)), y_test))
print(f1_score(smote_xgbc.predict(np.array(X_test_normalized)), y_test))