當前位置:網站首頁>不均衡樣本集的重采樣

不均衡樣本集的重采樣

2022-05-14 04:08:59意念回複

目錄

1 背景

2 為什麼很多分類模型在訓練數據不均衡時會出現問題?

3 處理樣本不均衡問題——基於數據的方法

3.1 隨機采樣

3.2 SMOTE

3.2.1 概念

3.2.2 偽代碼

3.2.3 python程序

3.3 Borderline SMOTE

3.3.1 概念

3.3.2 python實現

3.4 ADASYN自適應綜合過采樣

3.5 Informed Undersampling

3.5.1 Easy Ensemble算法

3.5.2 Balance Cascade算法

4 處理樣本不均衡問題——基於算法的方法


1 背景

        在訓練二分類模型時, 例如醫療診斷、 網絡入侵檢測、 信用卡反詐騙等, 經常會遇到正負樣本不均衡的問題。 對於很多分類算法, 如果直接采用不均衡的樣本集來進行訓練學習, 會存在一些問題。 例如, 如果正負樣本比例達到1∶ 99, 則分類器簡單地將所有樣本都判為負樣本就能達到99%的正確率, 顯然這並不是我們想要的, 我們想讓分類器在正樣本和負樣本上都有足够的准確率和召回率。

2 為什麼很多分類模型在訓練數據不均衡時會出現問題?

本質原因是模型在訓練時優化的目標函數人們在測試時使用的評價標准不一致。

  1. 這種“不一致”可能是由於訓練數據的樣本分布與測試時期望的樣本分布不一致, 例如, 在訓練時優化的是整個訓練集(正負樣本比例可能是1∶ 99) 的正確率, 而測試時可能想要模型在正樣本和負樣本上的平均正確率盡可能大(實際上是期望正負樣本比例為1∶ 1) ;
  2. 也可能是由於訓練階段不同類別的權重(重要性) 與測試階段不一致,例如訓練時認為所有樣本的貢獻是相等的, 而測試時假陽性樣本(False Positive)和偽陰性樣本(False Negative) 有著不同的代價。

3 處理樣本不均衡問題——基於數據的方法

       對數據進行重采樣, 使原本不均衡的樣本變得均衡。 首先, 記樣本數大的類別為Cmaj, 樣本數小的類別為Cmin, 它們對應的樣本集分別為Smaj和Smin。 根據題設, 有|Smaj|>>|Smin。

3.1 隨機采樣

         最簡單的處理不均衡樣本集的方法是隨機采樣。 采樣一般分為:過采樣(Oversampling) 和欠采樣(Under-sampling) 。

  • 隨機過采樣是從少數類樣本集Smin中隨機重複抽取樣本(有放回) 以得到更多樣本;
  • 隨機欠采樣則相反, 從多數類樣本集Smaj中隨機選取較少的樣本(有放回或無放回) 。

        直接的隨機采樣雖然可以使樣本集變得均衡, 但會帶來一些問題, 比如,

  • 過采樣對少數類樣本進行了多次複制, 擴大了數據規模, 增加了模型訓練的複雜度, 同時也容易造成過擬合;
  • 欠采樣會丟弃一些樣本, 可能會損失部分有用信息, 造成模型只學到了整體模式的一部分。

3.2 SMOTE

3.2.1 概念

論文地址:https://arxiv.org/pdf/1106.1813.pdf

        為了解决上述問題, 通常在過采樣時並不是簡單地複制樣本, 而是采用一些方法生成新的樣本。 例如, SMOTE算法:

  1. 對少數類樣本集Smin中每個樣本x, 從它在Smin中的K近鄰中隨機選一個樣本y;
  2. 然後在x,y連線上隨機選取一點作為新合成的樣本(根據需要的過采樣倍率重複上述過程若幹次)

        如下圖所示。 這種合成新樣本的過采樣方法可以降低過擬合的風險:

        SMOTE算法為每個少數類樣本合成相同數量的新樣本, 這可能會增大類間重疊度, 並且會生成一些不能提供有益信息的樣本。 

3.2.2 偽代碼

 

3.2.3 python程序

# pip install imbalanced-learn

from collections import Counter
from sklearn.datasets import make_classification
from imblearn.over_sampling import SMOTE
import matplotlib.pyplot as plt


X, y = make_classification(n_classes=2, class_sep=2,
                           weights=[0.1, 0.9], n_informative=2, n_redundant=0, flip_y=0,
                           n_features=2, n_clusters_per_class=1, n_samples=100,random_state=10)
print('Original dataset shape %s' % Counter(y))
x1 = X[y==1]
x2 = X[y==0]
plt.scatter(x1[:, 0], x1[:, 1])
plt.scatter(x2[:, 0], x2[:, 1])
plt.show()

sm = SMOTE(random_state=42)
X_res, y_res = sm.fit_resample(X, y)
print('Resampled dataset shape %s' % Counter(y_res))
x1 = X_res[y_res==1]
x2 = X_res[y_res==0]
plt.scatter(x1[:, 0], x1[:, 1])
plt.scatter(x2[:, 0], x2[:, 1])
plt.show()

3.3 Borderline SMOTE

3.3.1 概念

        論文地址:https://sci2s.ugr.es/keel/keel-dataset/pdfs/2005-Han-LNCS.pdf

        Borderline SMOTE是在SMOTE基礎上改進的過采樣算法,該算法僅使用邊界上的少數類樣本來合成新樣本,從而改善樣本的類別分布。
  Borderline SMOTE采樣過程是將少數類樣本分為3類,分別為Safe、Danger和Noise,具體說明如下。最後,僅對錶為Danger的少數類樣本過采樣。

  • Safe,樣本周圍一半以上均為少數類樣本,如圖中點A  
  • Danger:樣本周圍一半以上均為多數類樣本,視為在邊界上的樣本,如圖中點B
  • Noise:樣本周圍均為多數類樣本,視為噪音,如圖中點C

  • 圖a 是原始數據
  • 圖b是識別出的邊界上的少量樣本
  • 圖c是使用 Borderline SMOTE生成假樣本

        Borderline-SMOTE又可分為Borderline-SMOTE1Borderline-SMOTE2:

  • Borderline-SMOTE1在對Danger點生成新樣本時,在K近鄰隨機選擇少數類樣本(與SMOTE相同);
  • Borderline-SMOTE2則是在k近鄰中的任意一個樣本(不關注樣本類別),但是生成的樣本更靠近少數類樣本。

3.3.2 python實現

from collections import Counter
from sklearn.datasets import make_classification
from imblearn.over_sampling import SMOTE, BorderlineSMOTE
import matplotlib.pyplot as plt


def borderline_smote(X, y):
    # X, y = make_classification(n_classes=2, class_sep=2,
    #                            weights=[0.1, 0.9], n_informative=2, n_redundant=0, flip_y=0,
    #                            n_features=2, n_clusters_per_class=1, n_samples=100, random_state=9)
    sm = BorderlineSMOTE(random_state=42, kind="borderline-1")
    X_res, y_res = sm.fit_resample(X, y)
    print('Resampled dataset shape %s' % Counter(y_res))
    x1 = X_res[y_res==1]
    x2 = X_res[y_res==0]
    plt.scatter(x1[:, 0], x1[:, 1])
    plt.scatter(x2[:, 0], x2[:, 1])
    plt.show()


if __name__ == "__main__":
    X, y = make_classification(n_classes=2, class_sep=2,
                               weights=[0.1, 0.9], n_informative=2, n_redundant=0, flip_y=0,
                               n_features=2, n_clusters_per_class=1, n_samples=100)
    print('Original dataset shape %s' % Counter(y))
    x1 = X[y == 1]
    x2 = X[y == 0]
    plt.scatter(x1[:, 0], x1[:, 1])
    plt.scatter(x2[:, 0], x2[:, 1])
    plt.show()
    borderline_smote(X, y)

3.4 ADASYN自適應綜合過采樣

       論文地址:​​​​​​​https://sci2s.ugr.es/keel/pdf/algorithm/congreso/2008-He-ieee.pdfhttps://sci2s.ugr.es/keel/pdf/algorithm/congreso/2008-He-ieee.pdf

        ADASYN (adaptive synthetic sampling)自適應合成抽樣,與Borderline SMOTE相似,對不同的少數類樣本賦予不同的權重,從而生成不同數量的樣本。

       具體流程如下:

步驟1:計算需要合成的樣本數量,公式如下: 
    

       其中,ml為多數類樣本數量,ms為少數類樣本數量,β∈[0,1]隨機數,若β等於1,采樣後正負比例為1:1。

步驟2:計算K近鄰中多數類占比,公式如下:

        

      其中,∆i為K近鄰中多數類樣本數,i = 1,2,3,……,ms 

步驟3:對ri標准化,公式如下:

         

 步驟4:根據樣本權重,計算每個少數類樣本需生成新樣本的數目,公式如下:

          

步驟5:根據g計算每個少數樣本需生成的數目,根據SMOTE算法生成樣本,公式如下: 

          

     其中,si為合成樣本,xi是少數類樣本中第i個樣本,xzi是xi的K近鄰中隨機選取的一個少數類樣本, λ∈[0,1]的隨機數。 

3.5 Informed Undersampling

       對於欠采樣, 可以采用Informed Undersampling來解决由於隨機欠采樣帶來的數據丟失問題。 常見的Informed Undersampling算法有:

3.5.1 Easy Ensemble算法

       每次從多數類Smaj中上隨機抽取一個子集E(|E|≈|Smin|), 然後用E+Smin訓練一個分類器; 重複上述過程若幹次, 得到多個分類器,最終的分類結果是這多個分類器結果的融合 .

3.5.2 Balance Cascade算法

       級聯結構, 在每一級中從多數類Smaj中隨機抽取子集E, 用E+Smin訓練該級的分類器; 然後將Smaj中能够被當前分類器正確判別的樣本剔除掉, 繼續下一級的操作, 重複若幹次得到級聯結構; 最終的輸出結果也是各級分類器結果的融合。

       其他諸如NearMiss( 利用K近鄰信息挑選具有代錶性的樣本) 、 Onesided Selection( 采用數據清理技術) 等算法。

       在實際應用中, 具體的采樣操作可能並不總是如上述幾個算法一樣, 但基本思路很多時候還是一致的。 例如, 基於聚類的采樣方法, 利用數據的類簇信息來指導過采樣/欠采樣操作; 經常用到的數據擴充方法也是一種過采樣, 對少數類樣本進行一些噪聲擾動或變換( 如圖像數據集中對圖片進行裁剪、 翻轉、 旋轉、 加光照等) 以構造出新的樣本; 而Hard Negative Mining則是一種欠采樣, 把比較難的樣本抽出來用於迭代分類器。

4 處理樣本不均衡問題——基於算法的方法

  • 在樣本不均衡時, 也可以通過改變模型訓練時的目標函數( 如代價敏感學習中不同類別有不同的權重) 來矯正這種不平衡性;
  • 當樣本數目極其不均衡時, 也可以將問題轉化為單類學習( one-class learning) 、 异常檢測( anomaly detection) 。 

不平衡數據處理之SMOTE、Borderline SMOTE和ADASYN詳解及Python使用_猫新人的博客-CSDN博客_borderline smote

版權聲明
本文為[意念回複]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/134/202205140406329545.html

隨機推薦