我在我的Python程序中使用scikit-learn来执行一些机器学习操作。问题是我的数据集存在严重的不平衡问题。
是否有人熟悉scikit-learn或python中的不平衡解决方案?在Java中有SMOTE机制。在python中是否有并行的东西?
答案 0 :(得分:71)
这里有一个新的
https://github.com/scikit-learn-contrib/imbalanced-learn
它包含以下类别中的许多算法,包括SMOTE
答案 1 :(得分:27)
在Scikit学习中,有一些不平衡校正技术,根据您使用的学习算法而有所不同。
其中某些内容(如Svm或logistic 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.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))