数据不平衡之SMOTE算法(人工合成数据)


       怎么让不平衡的数据变平衡呢?主要有两个方法,一是欠抽样,顾名思义就是删除正样本(以正样本占绝大多数为例)中的样本,删除的数量根据负样本的数量而定,这种方法的缺点也很明显,会删除正样本所带的信息,当正负样本的比例悬殊时,需要删除较多的正样本数量,这会减少很多正样本携带的信息。

        因此,最常用的方法是第二种——过抽样。
       一种过抽样的方法是随机采样,采用简单随机复制样本来增加负样本的数量。这样容易产生模型的过拟合问题,即使得模型学习到的信息过于特别而不够泛化。

        另一种过抽样的方法就是要介绍的SMOTE算法,其基本思想是对少数类样本进行分析并根据少数类样本人工合成新样本添加到数据集中,

算法流程如下

#SMOTE算法及其python实现
import random
from sklearn.neighbors import NearestNeighbors
import numpy as np

class Smote:
    def __init__(self,samples,N=10,k=5):
        # N:采样倍率
        self.N=N
        # k:近邻数
        self.k=k
        self.samples=samples

    def over_sampling(self):
        neighbors=NearestNeighbors(n_neighbors=self.k).fit(self.samples)
        print('neighbors',neighbors)
        synthetic = []
        for i in range(len(self.samples)):
            print('samples',self.samples[i])
            nnarray=neighbors.kneighbors(self.samples[i].reshape((1,-1)),return_distance=False)[0]  #Finds the K-neighbors of a point.
            print ('nna',nnarray)
            synthetic = self._populate(i,nnarray, synthetic)
        return synthetic

    # for each minority class sample i ,choose N of the k nearest neighbors and generate N synthetic samples.
    def _populate(self,i,nnarray, synthetic):
        for j in range(self.N):
            nn=random.randint(0,self.k-1)  #包括end
            dif=self.samples[nnarray[nn]]-self.samples[i]
            gap=random.random()
            synthetic.append(self.samples[i]+gap*dif)
            return synthetic

if __name__ == '__main__':
    a=np.array([[1,2,3],[4,5,6],[2,3,1],[2,1,2],[2,3,4],[2,3,4]])
    s=Smote(a,N=5,k=3)
    aa = s.over_sampling()
    print(aa)

更多资料参考

https://www.cnblogs.com/bonelee/p/9089984.html

https://www.cnblogs.com/bonelee/p/9087286.html

https://blog.csdn.net/qq_15111861/article/details/84402042

你可能感兴趣的:(机器学习)