Python 学习中的不平衡
我在Python程序中使用scikit learn来执行一些机器学习操作。问题是我的数据集存在严重的不平衡问题Python 学习中的不平衡,python,scikit-learn,Python,Scikit Learn,我在Python程序中使用scikit learn来执行一些机器学习操作。问题是我的数据集存在严重的不平衡问题 有人熟悉scikit learn或python中的不平衡解决方案吗?在Java中有SMOTE mechanizm。python中有类似的东西吗?SMOTE在scikit learn中不是内置的,但仍然有在线可用的实现 编辑:与SMOTE实现的讨论 链接到,似乎不再可用。代码被保留 下面@nos给出的较新答案也很好。在Scikit learn中,有一些不平衡校正技术,这些技术根据您使用的
有人熟悉scikit learn或python中的不平衡解决方案吗?在Java中有SMOTE mechanizm。python中有类似的东西吗?SMOTE在scikit learn中不是内置的,但仍然有在线可用的实现 编辑:与SMOTE实现的讨论 链接到,似乎不再可用。代码被保留
下面@nos给出的较新答案也很好。在Scikit learn中,有一些不平衡校正技术,这些技术根据您使用的学习算法而有所不同 其中一些参数,如or,具有
class\u-weight
参数。如果在'auto'
上设置此参数来实例化一个SVC
,它将根据其频率的倒数按比例加权每个类示例
不幸的是,没有一个预处理器工具可以达到这个目的。我在这里找到了另一个库,它实现了欠采样和多个过采样技术,包括多个
SMOTE
实现和另一个使用SVM
:
这里有一个新的 它包含以下类别的许多算法,包括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))
您可以尝试过采样/欠采样来平衡数据集。当然,这是一种通用的机器学习方法,并不特定于Python和scikit学习。事实上,这个问题在这里可能是离题的。也许这更适合统计数据。我知道这个话题很老,但我只是补充一点建议。对于不平衡数据集,除了过采样/欠采样和使用class_权重参数外,您还可以降低阈值以对案例进行分类。预测概率(而不是类)并尝试使用小于0.5的阈值。当然,这不会提高分类器的性能,这只是精度和召回率之间的折衷。斯特吉奥斯,你如何准确地调整阈值?任何对python代码的引用都可以做到这一点吗?仅从代码来看,它包含
TODO
s。这个实现正确吗?代码正确,我刚刚测试过。TODO
是一个特例,它忽略了如下内容:T=T[np.random.choice(range(len(T)),N)]
。但是保持这条线N=100
!我曾尝试在极不平衡的数据中使用class weight='auto',但我没有看到性能上的太大差异,这正常吗?@KubiK888您是否使用相同的X进行测试和验证?您使用的测量方法是什么?不,测试集和训练集是完全分开的。现在此参数称为class\u weight='balanced'
。这是应该遵循的答案,请相信此参数,而不是标记为正确的参数。著名的图书馆,收到了大量的反馈和良好的维护。@Noki:记录在案,我接受的答案比这个早了三年多。它也比第一次承诺使用scikit learn contrib/Inbalanced learn早了大约一年半。我想这就是OP接受它的原因。但我同意,这是2020年最有用的答案。@Junuxx是的,你是对的。那时候是你帮忙的!看起来你在分割之前对整个数据集应用了smote。嘿,谢谢你的反馈erick。我没有在整个数据集上使用smote,但我更新了变量以包含“train”,所以没有混淆。