您好,登錄后才能下訂單哦!
更多大數據分析、建模等內容請關注公眾號《bigdatamodeling》
在分類問題中常常遇到一個比較頭疼的問題,即目標變量的類別存在較大偏差的非平衡問題。這樣會導致預測結果偏向多類別,因為多類別在損失函數中所占權重更大,偏向多類別可以使損失函數更小。
處理非平衡問題一般有兩種方法,欠抽樣和過抽樣。欠抽樣方法可以生成更簡潔的平衡數據集,并減少了學習成本。但是它也帶來了一些問題,它會刪掉一些有用的樣本,尤其當非平衡比例較大時,刪掉更多的樣本會導致原始數據的分布嚴重扭曲,進而影響分類器的泛化能力。
因此,后來發展出了過抽樣方法,它不會刪除多類別的樣本,而是通過復制少類別樣本的方法處理非平衡問題。但是,應用隨機過抽樣方法復制少類別樣本意味著對少類別樣本賦予更高的權重,容易產生過擬合問題。
2002年,研究者提出了SMOTE(Synthetic Minority Oversampling Technique)方法來替代標準的隨機過抽樣方法,可以一定程度克服隨機過抽樣帶來的過擬合問題,提高分類器的泛化能力。SMOTE方法通過在少類別樣本的近鄰中應用插值法創造新的少類別樣本,而不再是簡單的復制或賦予權重。
SMOTE算法的步驟如下:
(1)選取第i個少類別樣本在所有少類別樣本中的K個近鄰
(2)從K個近鄰中隨機選擇N個樣本,和第i個樣本通過插值法獲取N個新樣本
(3)重復步驟(1)和(2)直到所有少類別樣本被遍歷一遍
見下圖:
SMOTE算法的偽代碼:
#============================== SMOTE算法偽代碼 ===============================#
Algorithm 1 SMOTE algorithm
1: function SMOTE(T, N, k)
Input: T; N; k # T:Number of minority class examples
# N:Amount of oversampling
# K:Number of nearest neighbors
Output: (N/100) * T # synthetic minority class samples
Variables: Sample[][] # array for original minority class samples;
newindex # keeps a count of number of synthetic samples generated, initialized to 0;
Synthetic[][] # array for synthetic samples
2: if N < 100 then
3: Randomize the T minority class samples
4: T = (N/100)*T
5: N = 100
6: end if
7: N = (int)N/100 # The amount of SMOTE is assumed to be in integral multiples of 100.
8: for i = 1 to T do
9: Compute k nearest neighbors for i, and save the indices in the nnarray
10: POPULATE(N, i, nnarray)
11: end for
12: end function
Algorithm 2 Function to generate synthetic samples
1: function POPULATE(N, i, nnarray)
Input: N; i; nnarray # N:instances to create
# i:original sample index
# nnarray:array of nearest neighbors
Output: N new synthetic samples in Synthetic array
2: while N != 0 do
3: nn = random(1,k)
4: for attr = 1 to numattrs do # numattrs:Number of attributes
5: Compute: dif = Sample[nnarray[nn]][attr] ? Sample[i][attr]
6: Compute: gap = random(0, 1)
7: Synthetic[newindex][attr] = Sample[i][attr] + gap * dif
8: end for
9: newindex + +
10: N ? ?
11: end while
12: end function
SMOTE算法的python實現:
下面用python實現一個SMOTE的最簡單的版本:
####### python3.6 ########
import random
import numpy as np
from sklearn.neighbors import NearestNeighbors
def smote_sampling(samples, N=100, K=5):
n_samples, n_attrs = samples.shape
if N<100:
n_samples = int(N/100*n_samples)
indx = random.sample(range(len(samples)), n_samples)
samples = samples[indx]
N = 100
N = int(N/100)
synthetic = np.zeros((n_samples * N, n_attrs))
newindex = 0
neighbors=NearestNeighbors(n_neighbors=K+1).fit(samples)
for i in range(n_samples):
nnarray=neighbors.kneighbors(samples[i].reshape(1,-1),return_distance=False)[0]
for j in range(N):
nn = random.randint(1, K)
dif = samples[nnarray[nn]]- samples[i]
gap = random.random()
synthetic[newindex] = samples[i] + gap * dif
newindex += 1
return synthetic
python中imblearn模塊對SMOTE算法的封裝
python 中有封裝好的SMOTE方法,在實踐中可以直接調用該方法,具體參數可以查看官方文檔。簡單應用舉例:
from sklearn.datasets import make_classification
from collections import Counter
from imblearn.over_sampling import SMOTE
# 生成數據集
X, y = make_classification(n_classes=2, class_sep=2,
weights=[0.1, 0.9], n_informative=3,
n_redundant=1, flip_y=0,
n_features=20, n_clusters_per_class=1,
n_samples=1000, random_state=9)
# 類別比例
Counter(y)
# SMOTE合成新數據
sm = SMOTE(ratio={0: 900}, random_state=1)
X_res, y_res = sm.fit_sample(X, y)
# 新數據類別比例
Counter(y_res)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。