码迷,mamicode.com
首页 > 其他好文 > 详细

基于半监督学习方法的异常值检测

时间:2015-10-18 14:04:25      阅读:684      评论:0      收藏:0      [点我收藏+]

标签:

在韩家炜书中提到了使用半监督学习方法的异常值检测。在半监督学习中,一部分样本会被标记为“正常”或"离群点“,另一部分样本没有标号,需要算法去估计。貌似这看上去有些像分类得预测问题。但是半监督学习的思想是每次学习后,把最有可能预测正确的样本,加入到下一次迭代的训练集中去。如此不断扩大学习和标记的范围。问题是如何指定一开始的初始标签?( 当然可以人为指定 )

 

我们来看这个数据集。绿色部分是被标记“正常”的样本。红色的为“异常”的样本。蓝色的为“未标记”样本点。其实这里我自己采用的初始标记方法很简单,就是算出每个样本的K近邻距离的平方和。然后输入两个参数,分别是正常点的默认数量goodSampleNum和异常点的默认数量badSampleNum

技术分享

这里我默认选goodSampleNum = 10和badSampleNum = 5。至少对这个数据集是合适的。由于我们前面已经算出了每个样本的K近邻距离的平方和,K这里我们取5。所以goodSampleNum对应的正常点应该是K近邻平方和最小的goodSampleNum个。而异常值则是K近邻平方和最大的badSampleNum。具体的代码如下

def genInitLabels( X, k = 3, goodSampleNum = 10, badSampleNum = 5 ):
    labels = -1 * np.ones( len( X ) )    
    dists = calKNNSqDists( X, k )
    indices = np.argsort( dists )

    labels[ indices[ : goodSampleNum  ] ] = 0
    labels[ indices[ -badSampleNum : ] ] = 1  

    return labels, dists.reshape(-1,1)

这里的calKNNSqDists就是用来计算每个样本点的K近邻平方和,这里就不展开了。这里会返回初始的label,如果label是-1则为“未标记”

 

接着就是使用半监督学习方法。我们这里直接调用sklearn里的半监督方法LabelPropagation。这里我们继续使用前面获取的K近邻距离平方和来做为半监督学习方法的输入, 具体代码如下:

 

def detectOutliers( X, k = 5, goodSampleNum = 10, badSampleNum = 5 ):
    initLables, dists = genInitLabels( X, k, goodSampleNum, badSampleNum )

    semiModel = LabelPropagation( knn , n_neighbors = k + 1 )
    semiModel.fit( dists, initLables )
    labels = semiModel.predict( dists )
    
    print "Num of outliers:", np.sum( labels == 1 )
    return labels, initLables

 

这里的半监督算法我们依然采用knn核,最近邻由于sklearn里的近邻包含自身,所以就用k + 1。方法获取的结果如下,绿色的为异常值:

技术分享

大部分的异常点还是找得不错。但是还是有两个点,个人觉得不是太好,离群度不够。无论如何,这篇文章提供了个半监督学习方法在异常值检测应用的思路。

 

基于半监督学习方法的异常值检测

标签:

原文地址:http://www.cnblogs.com/zhuyubei/p/4889311.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!