簡體   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