經過隨機採樣和數據加強來解決數據不平衡的問題

在開發分類機器學習模型時遇到的挑戰之一是類別不平衡。大多數用於分類的機器學習算法都是在假設平衡類的狀況下開發的,然而,在現實生活中,擁有適當平衡的數據並不常見。所以,人們提出了各類方案來解決這個問題,以及一些應用這些解決方案的工具或者類庫。例如,imbalanced-learn 這個python庫,它實現了最相關的算法來解決類不平衡的問題。
html


在這篇文章中,咱們將瞭解什麼是類別不平衡、將準確性做爲不平衡類別的度量標準的問題是什麼、什麼是隨機欠採樣和隨機過採樣,以及imbalanced-learn如何做爲解決類別不平衡問題的替代工具。文章將分爲如下幾個部分:python

  • 什麼是類別不平衡?git

  • 準確率悖論github

  • 欠採樣和過採樣算法

  • Imbalanced-learn使用實踐微信

什麼是類別不平衡

當每一個類別的樣本不平衡時,即在類別分佈之間沒有平衡比率時,會出現類別不平衡的問題。這種失衡多是輕微的,也多是嚴重的。取決於樣本量,比率從1:2到1:10能夠理解爲輕微的不平衡,比率大於1:10能夠理解爲強烈的不平衡。在這兩種狀況下,都必須使用特殊技術(例如欠採樣,過採樣,cost-sensitive代價敏感等)處理具備類不平衡問題的數據。稍後,咱們將用imblearn [1]介紹欠採樣和過採樣以及它們的實現。app

準確率悖論

在分類問題中處理不平衡數據時要考慮的基本問題之一是使用的度量。準確率Accuracy 經常使用做事實度量標準,可是對於類不平衡問題,因爲準確率可能會產生誤導,所以不是一個好的選擇,該問題被稱爲準確率悖論。讓咱們看一下圖2,以更好地理解準確率悖論。dom

當使用準確率 accuracy做爲評估使用類不平衡問題數據集訓練的機器學習模型的指標時,結果可能會產生誤導。如咱們所見,準確度爲92%,這使咱們假設該模型足夠好。可是,若是咱們仔細觀察,就會發現該模型學會了將全部事物分類爲0類,從而產生了具備足夠好的準確性的效果。在這些狀況下,除了應用某種方法來解決類不平衡問題外,建議引入其餘評估指標,例如精度precision,召回率和F1-Score。讓咱們看一下圖3,以更好地瞭解精度precision,召回率和F1-Score指標如何幫助咱們更好地瞭解結果。
機器學習

準確率Accuracy 是一種度量標準,用於衡量真實確定和真實否認之間的平衡,可是,當數據集出現類不平衡問題時,模型極可能會學習將全部內容歸類爲優點類,在這種狀況下歸類爲類0。,即便該模型已將100%的數據分類爲0類,但鑑於TN的數量占主導地位,其準確率也足夠好。這就是爲何當存在類不平衡問題(準確性悖論)時,準確率Accuracy 度量經常會誤導人們的緣由。
ide

精度precision度量標準是:「在全部模型列爲正數的元素中,有多少是正確的。」「咱們觀察到的精度是完美的,它會使咱們認爲「好,準確率和精度都足夠好」,然而它並不徹底正確,由於10類1的元素,只有2個分類正確,也就是說,8個分類不正確,對比分類不正確能夠在召回指標中觀察到。

召回率recall度量標準是:「按模型分類爲陽性類別的人與y類別但實際上爲正的人之間的平衡」。如鍋召回率很是低就代表某些事情是不正確的。也就是說,一些確實爲陽性的樣本被歸類爲陰性。在實際狀況下,讓咱們假設陽性類別是指「患有癌症」,而陰性類別是指「未患有癌症」,在這種狀況下,咱們會將許多真正患有癌症的人分類爲沒有癌症的人這確定是致命性的錯誤。

最後,爲了歸納精度和召回率指標,咱們實現了F1-Score指標,該指標被理解爲精度和召回率之間的「諧波平均值」,換句話說,它提供了兩個指標之間的比率。如咱們所見,F1-Score值很低,這是另外一個不正確的指標(在咱們的示例中,精度是完美的,但召回率不好)。

到目前爲止,咱們已經看到了類不平衡問題,使用不平衡類的一些後果,以及評估存在類不平衡問題的模型時須要考慮的一些指標。如今,咱們來看一些能夠用來調整類不平衡的方法,特別是看看應用基於欠採樣和過採樣的技術的效果。

欠採樣和過採樣

當類別分佈之間沒有平衡時,就會出現類別不平衡問題,也就是說相對於一個或多個類別過多致使數據的失衡。直觀上說能夠經過將樣本添加到少數類別或從多數類別中刪除樣本或二者結合來解決此問題。從多數類中刪除樣本的過程稱爲欠採樣,而將樣本添加到少數類中的過程稱爲過採樣。

隨機欠採樣是指多數類別的隨機採樣。進行該過程,直到達到少數羣體的平衡爲止。儘管此技術有助於在多數和少數類別之間創建平衡,可是從多數類中刪除樣本時可能會丟失重要信息。

隨機過採樣是指少數羣體樣本的隨機重複。進行添加過程直到相對於多數類達到平衡爲止,可是,此技術可能致使訓練模型過分適應少數類。

隨機欠採樣和隨機過採樣能夠理解爲解決類不平衡問題的基本技術。現在,有更多有但願的技術試圖改善基於隨機方法的弊端,例如合成數據加強(SMOTE [2],ADASYN [3])或基於聚類的欠採樣技術(ENN [4])。

咱們已經知道基於欠採樣和過採樣的技術是什麼,讓咱們看看如何在實踐中使用它們!

Imbalanced-learn使用實踐

Imbalanced-learn是一個開源Python庫[5],由Guillaume Lemaître等人開發。[6]提供了一套處理類不平衡問題的算法。這一套算法分爲四類:欠採樣、過採樣、過/欠採樣結合和集成學習方法。出於咱們的目的,在這種狀況下,咱們將只使用欠採樣和過採樣擴展。

下面的示例將使用不平衡數據集。咱們將訓練機器學習模型(決策樹),並評估其準確率、精度、召回率和f1-score。隨後,咱們將使用欠採樣和過採樣算法,並再次評估上述指標,將未解決不平衡問題的模型訓練結果與使用欠採樣和過採樣的結果進行比較。

因此讓咱們首先生成一個不平衡的數據集:

 from sklearn.datasets import make_classification
 
 # Generates toy dataset for binary classification with shape x = [5000, 20]
 def generate_data():
    x, y = make_classification(n_samples=5000, n_features=20, n_classes=2, weights=[0.95, 0.05])
    return x, y

生成的不平衡數據集看起來如圖4所示:

如咱們所見,生成的數據集存在類不平衡的問題,比率爲1:10。在應用欠採樣和過採樣算法以前,咱們將定義一個函數,該函數可以使用固定的數據集訓練決策樹。

 # Metrics
 from sklearn.metrics import recall_score
 from sklearn.metrics import accuracy_score
 from sklearn.metrics import precision_score
 from sklearn.metrics import f1_score
 
 from sklearn.tree import DecisionTreeClassifier
 from sklearn.model_selection import StratifiedKFold
 
 def classify(x, y):
 
    print(f"Samples of class 0: {y.shape[0] - np.sum(y)}")
    print(f"Samples of class 1: {np.sum(y)}")
 
    # Defines the model to be used
    model = DecisionTreeClassifier(max_depth=3)
 
    avg_accuracy = []
    avg_precision = []
    avg_recall = []
    avg_f1score = []
 
    # Defines Stratified K-fold in order to keep
    # the class balance for each fold
    st_k_fold = StratifiedKFold(n_splits=10)
 
    for train_idx, test_idx in st_k_fold.split(x, y):
         
        # Training fold
        x_train = x[train_idx]
        y_train = y[train_idx]
         
        # Testing fold
        x_test = x[test_idx]
        y_test = y[test_idx]
 
        # Train
        model.fit(x_train, y_train)
 
        # Get metrics
        accuracy = accuracy_score(y_test, model.predict(x_test))
        precision = precision_score(y_test, model.predict(x_test))
        recall = recall_score(y_test, model.predict(x_test))
        f1score = f1_score(y_test, model.predict(x_test))
 
        # Save metrics
        avg_accuracy.append(accuracy)
        avg_precision.append(precision)
        avg_recall.append(recall)
        avg_f1score.append(f1score)
     
    print(f"Avg accuracy: {np.mean(avg_accuracy)}")
    print(f"Avg precision: {np.mean(avg_precision)}")
    print(f"Avg recall: {np.mean(avg_recall)}")
    print(f"Avg f1-score: {np.mean(avg_f1score)}")

正如咱們已經觀察到的,該函數實現了分層K折交叉驗證技術,以便在每一個折的類之間保持相同的平衡。

爲了進行說明性比較,咱們將定義一組函數,這些函數應用每種採樣算法(隨機採樣和上下采樣),SMOTE以及一個虛擬版本(用於訓練決策樹而不考慮類不平衡問題)。

 from imblearn.under_sampling import RandomUnderSampler
 from imblearn.over_sampling import RandomOverSampler
 from imblearn.over_sampling import SMOTE
 
 # Applies DT without fixing the class imbalance problem.
 def dummy_decision_tree():
    classify(x, y)
 
 # Applies Random Undersampling
 def under_sampler():
    rus = RandomUnderSampler()
    x, y = rus.fit_resample(x, y)
 
    classify(x, y)
 
 # Applies Random Undersampling
 def over_sampler():
    ros = RandomOverSampler()
    x, y = ros.fit_resample(x, y)
     
    classify(x, y)
 
 # Applies Synthetic Data Augmentation through SMOTE
 def smote():
    smote= SMOTE()
    x, y = smote.fit_resample(x, y)
 
    classify(x, y)

函數(第6行)使用代碼段1中生成的數據訓練決策樹,而無需考慮類不平衡問題。在第10行應用隨機欠採樣,在第17行應用隨機過採樣,在第25行應用SMOTE。在圖5中,咱們能夠看到在應用每種算法時如何轉換類平衡。

如咱們所見,欠採樣算法從多數類中刪除了樣本,使其與少數類保持一致。另外一方面,過採樣算法會複製少數類的元素(若是您看到的話,該圖看起來相似於圖4中的圖)。最後,SMOTE(一種數據加強技術)增長了少數派的樣本,直到與多數派達到平衡爲止。結果如圖6所示。

咱們能夠看到,在應用技術來糾正類平衡問題時,模型的有效性獲得了提升。對於此特定示例,基於合成數據擴充(SMOTE)的技術顯示出更好的結果。歸根結底,實施技術將徹底取決於您使用的數據。值得一提的是,imbalanced-learn提供了各類各樣的算法來解決不平衡類的問題,值得一看其文檔[1]。

總結

在此文章中,咱們看到了類不平衡的問題以及使用不平衡數據集時必須考慮的指標。咱們還看到了一個示例,該示例如何使用基於採樣和數據擴充的算法解決類不平衡問題。咱們還利用了不平衡學習庫來擴展現例中使用的算法。

引用

[1] https://imbalanced-learn.org/stable/user_guide.html

[2] SMOTE: Synthetic Minority Over-sampling Technique

[3] ADASYN: Adaptive Synthetic Sampling Approach for Imbalanced Learning

[4] Aymptotic Properties of Nearest Neighbor Rules Using Edited Data

[5] https://github.com/scikit-learn-contrib/imbalanced-learn

[6] Imbalanced-learn: A Python Toolbox to Tackle the Curse of Imbalanced Datasets in Machine Learning

做者:Fernando López

原文地址:https://towardsdatascience.com/class-imbalance-random-sampling-and-data-augmentation-with-imbalanced-learn-63f3a92ef04a

deephub翻譯組


本文分享自微信公衆號 - DeepHub IMBA(deephub-imba)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索