過采樣中用到的SMOTE算法


        平時很多分類問題都會面對樣本不均衡的問題,很多算法在這種情況下分類效果都不夠理想。類不平衡(class-imbalance)是指在訓練分類器中所使用的訓練集的類別分布不均。比如說一個二分類問題,1000個訓練樣本,比較理想的情況是正類、負類樣本的數量相差不多;而如果正類樣本有995個、負類樣本僅5個,就意味着存在類不平衡。把樣本數量過少的類別稱為“少數類”。

        SMOTE算法的思想是合成新的少數類樣本,合成的策略是對每個少數類樣本a,從它的最近鄰中隨機選一個樣本b,然后在a、b之間的連線上隨機選一點作為新合成的少數類樣本。如圖所示:

 
 
 

算法流程:

        1、對於少數類中每一個樣本a,以歐氏距離為標准計算它到少數類樣本集中所有樣本的距離,得到其k近鄰。

        2、根據樣本不平衡比例設置一個采樣比例以確定采樣倍率N,對於每一個少數類樣本a,從其k近鄰中隨機選擇若干個樣本,假設選擇的近鄰為b。

        3、對於每一個隨機選出的近鄰b,分別與原樣本a按照如下的公式構建新的樣本:c=a+rand(0,1)∗|a−b|


類別不平衡問題

       類別不平衡問題,顧名思義,即數據集中存在某一類樣本,其數量遠多於或遠少於其他類樣本,從而導致一些機器學習模型失效的問題。例如邏輯回歸即不適合處理類別不平衡問題,例如邏輯回歸在欺詐檢測問題中,因為絕大多數樣本都為正常樣本,欺詐樣本很少,邏輯回歸算法會傾向於把大多數樣本判定為正常樣本,這樣能達到很高的准確率,但是達不到很高的召回率。

       類別不平衡問題在很多場景中存在,例如欺詐檢測,風控識別,在這些樣本中,黑樣本(一般為存在問題的樣本)的數量一般遠少於白樣本(正常樣本)。

       上采樣(過采樣)和下采樣(負采樣)策略是解決類別不平衡問題的基本方法之一。上采樣即增加少數類樣本的數量,下采樣即減少多數類樣本以獲取相對平衡的數據集。

       最簡單的上采樣方法可以直接將少數類樣本復制幾份后添加到樣本集中,最簡單的下采樣則可以直接只取一定百分比的多數類樣本作為訓練集。

       SMOTE算法是用的比較多的一種上采樣算法,SMOTE算法的原理並不是太復雜,用python從頭實現也只有幾十行代碼,但是python的imblearn包提供了更方便的接口,在需要快速實現代碼的時候可直接調用imblearn。

       imblearn類別不平衡包提供了上采樣和下采樣策略中的多種接口,基本調用方式一致,主要介紹一下對應的SMOTE方法和下采樣中的RandomUnderSampler方法。imblearn可使用pip install imblearn直接安裝。

代碼示例
生成類別不平衡數據

# 使用sklearn的make_classification生成不平衡數據樣本
from sklearn.datasets import make_classification
# 生成一組0和1比例為9比1的樣本,X為特征,y為對應的標簽
X, y = make_classification(n_classes=2, class_sep=2,
weights=[0.9, 0.1], n_informative=3, 
n_redundant=1, flip_y=0,
n_features=20, n_clusters_per_class=1, 
n_samples=1000, random_state=10)


查看數據分布

from collections import Counter
# 查看所生成的樣本類別分布,0和1樣本比例9比1,屬於類別不平衡數據
print(Counter(y))
# Counter({0: 900, 1: 100})

 

SMOTE算法核心語句

# 使用imlbearn庫中上采樣方法中的SMOTE接口
from imblearn.over_sampling import SMOTE
# 定義SMOTE模型,random_state相當於隨機數種子的作用
smo = SMOTE(random_state=42)
X_smo, y_smo = smo.fit_sample(X, y)


查看經過SMOTE之后的數據分布

print(Counter(y_smo))
# Counter({0: 900, 1: 900})


 從上述代碼中可以看出,SMOTE模型默認生成一比一的數據,如果想生成其他比例的數據,可以使用radio參數。不僅可以處理二分類問題,同樣適用於多分類問題

# 可通過radio參數指定對應類別要生成的數據的數量
smo = SMOTE(ratio={1: 300 },random_state=42)
# 生成0和1比例為3比1的數據樣本
X_smo, y_smo = smo.fit_sample(X, y)
print(Counter(y_smo))
# Counter({0: 900, 1: 300})

imblearn中上采樣接口提供了隨機上采樣RandomOverSampler,SMOTE,ADASYN三種方式,調用方式和主要參數基本一樣。下采樣接口中也提供了多種方法,以RandomUnderSampler為例。

from imblearn.under_sampling import RandomUnderSampler
# 同理,也可使用ratio來指定下采樣的比例
rus = RandomUnderSampler(ratio={0: 500 }, random_state=0)
X_rus, y_rus = rus.fit_sample(X, y)
print(Counter(y_smo))
# Counter({0: 500, 1: 300})

其他參考鏈接:https://www.cnblogs.com/bonelee/p/8535045.html

 

原文鏈接:https://www.jianshu.com/p/9a68934d1f56
原文鏈接:https://blog.csdn.net/nlpuser/article/details/81265614

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM