平时很多分类问题都会面对样本不均衡的问题,很多算法在这种情况下分类效果都不够理想。针对不均衡问题,一般有采样和代价敏感学习两种策略,采样的话又分为over-sampling和under-sampling。其中,smote算法算是over-sampling中比较常用的一种。
smote算法的思想是合成新的少数类样本,合成的策略是对每个少数类样本a,从它的最近邻中随机选一个样本b,然后在a、b之间的连线上随机选一点作为新合成的少数类样本。
论文地址:https://www.jair.org/media/953/live-953-2037-jair.pdf
下图是论文中给出的smote伪代码。
#encoding=gbk
from sklearn.neighbors import NearestNeighbors
import numpy as np
import random
class Smote:
#samples的最后一列是类标,都是1
def __init__(self, samples, N=10,k=5):
self.n_samples, self.n_attrs=samples.shape
self.N=N
self.k=k
self.samples=samples
def over_sampling(self):
if self.N<100:
old_n_samples=self.n_samples
print "old_n_samples", old_n_samples
self.n_samples=int(float(self.N)/100*old_n_samples)
print "n_samples", self.n_samples
keep=np.random.permutation(old_n_samples)[:self.n_samples]
print "keep", keep
new_samples=self.samples[keep]
print "new_samples", new_samples
self.samples=new_samples
print "self.samples", self.samples
self.N=100
N=int(self.N/100) #每个少数类样本应该合成的新样本个数
self.synthetic=np.zeros((self.n_samples*N, self.n_attrs))
self.new_index=0
neighbors=NearestNeighbors(n_neighbors=self.k).fit(self.samples)
print "neighbors", neighbors
for i in range(len(self.samples)):
nnarray=neighbors.kneighbors(self.samples[i],return_distance=False)[0]
#存储k个近邻的下标
self.__populate(N, i, nnarray )
return self.synthetic
#从k个邻居中随机选取N次,生成N个合成的样本
def __populate(self, N, i, nnarray):
for i in range(N):
nn = np.random.randint(0, self.k)
dif=self.samples[nnarray[nn]]-self.samples[i] #包含类标
gap=np.random.rand(1,self.n_attrs)
self.synthetic[self.new_index]=self.samples[i]+gap.flatten()*dif
self.new_index+=1
面对分类问题中的样本不均衡,Smote算法是一种常用的过采样策略。它通过合成新的少数类样本来平衡数据集,选择每个少数类样本的最近邻,然后在它们之间随机选取点创建新样本。该方法有助于提升算法在处理不平衡数据时的分类效果。
3392

被折叠的 条评论
为什么被折叠?



