SMOTE算法代码实现-机器学习
類別不平衡問題
類別不平衡問題,顧名思義,即數據集中存在某一類樣本,其數量遠多于或遠少于其他類樣本,從而導致一些機器學習模型失效的問題。例如邏輯回歸即不適合處理類別不平衡問題,例如邏輯回歸在欺詐檢測問題中,因為絕大多數樣本都為正常樣本,欺詐樣本很少,邏輯回歸算法會傾向于把大多數樣本判定為正常樣本,這樣能達到很高的準確率,但是達不到很高的召回率。
類別不平衡問題在很多場景中存在,例如欺詐檢測,風控識別,在這些樣本中,黑樣本(一般為存在問題的樣本)的數量一般遠少于白樣本(正常樣本)。
上采樣(過采樣)和下采樣(負采樣)策略是解決類別不平衡問題的基本方法之一。上采樣即增加少數類樣本的數量,下采樣即減少多數類樣本以獲取相對平衡的數據集。
最簡單的上采樣方法可以直接將少數類樣本復制幾份后添加到樣本集中,最簡單的下采樣則可以直接只取一定百分比的多數類樣本作為訓練集。
SMOTE算法詳解
SMOTE全稱是Synthetic Minority Oversampling Technique即合成少數類過采樣技術,它是基于隨機過采樣算法的一種改進方案,SMOTE算法的基本思想是對少數類樣本進行分析并根據少數類樣本人工合成新樣本添加到數據集中。
SMOTE 算法是利用特征空間中現存少數類樣本之間的相似性來建立人工數據的,也可以認為SMOTE算法假設了在相距較近的少數類樣本之間的樣本仍然是少數類,
具體過程如下:
隨機選擇一個少數類樣本,計算它到少數類樣本集中所有樣本的距離,得到它k近鄰。
根據樣本不平衡比例設置一個采樣比例以確定采樣倍率n,對于每一個少數類樣本x,從其k近鄰中隨機選擇若干個樣本
對于每一個隨機選出的近鄰,選擇一個在[0,1]之間的隨機數乘以隨機近鄰和x的特征向量的差,然后加上一個x,
用公式表示:
SMOTE算法摒棄了隨機過采樣復制樣本的做法,可以防止隨機過采樣易過擬合的問題,而這些多出來的樣本本身不帶有信息,而且SMOTE 算法對于每個原少數類樣本產生相同數量的合成數據樣本,這就使得類間發生重復的可能性加大。
SMOTE算法調用
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)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
查看數據分布
from collections import Counter
#查看所生成的樣本類別分布,0和1樣本比例9比1,屬于類別不平衡數據
print(Counter(y))
#Counter({0: 900, 1: 100})
- 1
- 2
- 3
- 4
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)
- 1
- 2
- 3
- 4
- 5
查看經過SMOTE之后的數據分布
print(Counter(y_smo))
#Counter({0: 900, 1: 900})
- 1
- 2
從上述代碼中可以看出,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})
- 1
- 2
- 3
- 4
- 5
- 6
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})
- 1
- 2
- 3
- 4
- 5
- 6
欠采樣代碼
如果數據類別不平衡高達200:1,可將其比例調整為10:1,
from imblearn.under_sampling import RandomUnderSampler
from collections import Counter
def ratio_multiplier(y):multiplier = {0: 0.05, 1: 1}target_stats = Counter(y)for key, value in target_stats.items():target_stats[key] = int(value * multiplier[key])return target_stats
rus = RandomUnderSampler(random_state=100,ratio=ratio_multiplier)#100
X_res, y_res = rus.fit_sample(X_train_all, y_train_all)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
參考:https://blog.csdn.net/nlpuser/article/details/81265614
</div>
總結
以上是生活随笔為你收集整理的SMOTE算法代码实现-机器学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 样本不均衡问题
- 下一篇: 预见未来丨机器学习:未来十年研究热点