谱聚类原理
来源:互联网 发布:狼牙军品专卖店一淘宝 编辑:程序博客网 时间:2024/06/04 20:02
本文转载于http://blog.csdn.net/betarun/article/details/51154003
这方法是昨天听同学提起的,大致翻看了几篇博客跟论文,这里写下自己的理解
从样本相似性到图
根据我们一般的理解,聚类是将相似的样本归为一类,或者说使得同类样本相似度尽量高,异类样本相似性尽量低。无论如何,我们需要一个方式度量样本间的相似性。常用的方式就是引入各种度量,如欧氏距离、余弦相似度、高斯度量等等。
度量的选择提现了你对样本或者业务的理解。比如说如果你要比较两个用户对音乐选择的品味,考虑到有些用户习惯打高分,有些用户习惯打低分,那么选择余弦相似度可能会比欧式距离更合理。
现在我们假设已有的样本为
这是一个完全图,我们的目的是去掉一些边,使得这个图变成
- 子图内的连边权重尽量大,即同类样本间尽量相似
- 去掉的边权重尽量小,即异类样本间尽量不同
一个初步的优化方法是去掉部分权重小的边,常用的有两种方式:
ϵ 准则,即去掉权重小于ϵ 的所有边k 邻近准则,即每个节点之保留权最大的几条边
现在我们得到一个较为稀疏的图。
图与图的Laplacian矩阵
为了下一步的算法推导,首先介绍图的Laplacian矩阵,我们记节点
容易看到,矩阵
优化目标
现在我们来推导我们要优化的目标函数。前面说过,我们的目的是去掉一些边,使得这个图变成
为了方便,引入记号
那么
因此去掉的边的权重和为
现在的问题就转换为:找到
- 这是个NP难问题,没有有效算法
- 实际实验得到的结果常常将单独的一个样本分为一类
先来解决第二个问题:
我们实际希望的是,每个类别中的样本数要充分大,有两种调整目标函数的方法:
- RatioCut,将目标函数改成
12∑k=1nW(Ak,A¯k)|Ak| - Ncut, 将目标函数改成
12∑k=1nW(Ak,A¯k)vol(Ak)
其中vol(A)=∑i∈Adi
两种方法都使得某个类样本量少的时候,对应的目标函数项变大。这里我们以第一种方法为例,第二种是类似的。
现在来解决第二个问题:
我们碰到NP难问题的时候,通常是考虑近似解,谱聚类也不例外。首先,我们要引入列向量
那么,
令
现在的问题是找到
这里用到的一个trick是放宽
令
由于
可以分析得到
因此
且当
最后一步
现在我们得到了放宽限制条件下的优化问题的最优解解
我们知道,如果
谱聚类有意思的地方是选择了对
- 对满足原始限制条件的
H ,行向量一致等价于类别一致 - 在原始限制条件下得到的
H 跟放宽限制条件下得到的H 应该比较相近
如此可以推断在放宽条件下得到的
总结
至此,谱聚类的大致步骤就完成了,归纳下主要步骤
- 计算样本相似性得到样本为节点的完全图
- 基于
ϵ 准则或者m 邻近准则将完全图稀疏化 - 计算稀疏化后的图的laplacian矩阵,计算其前
K 小特征值对应的特征向量作为矩阵H 的列 - 对矩阵
H 的行向量作k-means聚类 - 若
H 的第i 行与第j 行被聚为一类,则表示xi 与xj 聚为一类。
代码例子
左图是原始数据,右图是谱聚类结果
import numpy as npimport networkx as nximport scipy.linalg as llgfrom Queue import PriorityQueueimport matplotlib.pylab as pltimport heapq as hpfrom sklearn.cluster import k_means# fake data from multivariate normal distributionS = np.random.multivariate_normal([1,1], [[0.5,0],[0,0.7]],100)T = np.random.multivariate_normal([-1,-1], [[0.3,0],[0,0.8]],100)R = np.random.multivariate_normal([-1,0], [[0.4,0],[0,0.5]],100)Data = np.vstack([S,T,R])plt.subplot(1,2,1)plt.scatter(S.T[0],S.T[1],c='r')plt.scatter(T.T[0],T.T[1],c='b')plt.scatter(R.T[0],R.T[1],c='y')# calc k-nearest neighborsdef min_k(i,k): pq = [] for j in range(len(Data)): if i == j: continue if len(pq) < k: hp.heappush( pq,(1/np.linalg.norm(Data[i]-Data[j]), j) ) else: hp.heappushpop( pq, (1/np.linalg.norm(Data[i]-Data[j]), j) ) return pq# calc laplacianL = np.zeros((len(Data),len(Data)))for i in range(len(Data)): for (v,j) in min_k(i, 3): L[i,j] = -v L[j,i] = -vL = L + np.diag(-np.sum(L,0)) # kmean(lam, vec) = llg.eigh(L)A = vec[:,0:3]kmean = k_means(A,3)plt.subplot(1,2,2)plt.scatter(Data.T[0],Data.T[1],c=['r' if v==0 else 'b' if v==1 else 'y' for v in kmean[1]])plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 谱聚类原理
- 谱聚类原理
- 谱聚类原理
- 谱聚类算法原理介绍
- 原理
- 原理
- 原理
- 谱聚类算法原理及实现
- 谱聚类的增量更新原理
- 谱聚类原理简述(含实验代码)
- 谱聚类(spectral clustering)原理总结
- 谱聚类原理总结-by刘建平大神
- 谱聚类(spectral clustering)原理总结
- 谱聚类(spectral clustering)原理总结
- 加法原理乘法原理
- 谱聚类(spectral clustering)原理+算法流程--总结
- Win32ASM原理
- win32asm原理
- Retrofit+fastjson
- Unity触发检测和碰撞检测
- 字符串匹配——KMP算法
- jekyll _config timezone
- solr 6.3 入门(三)
- 谱聚类原理
- Hibernate(5.2.10)快速入门 (一) 初识Hibernate、框架搭建、xml基本配置
- 程序片段----随机森林 opencv
- 层次分析法
- 卢卡斯定理
- DZNEmptyDataSet——空白数据集显示框架
- Eclipse打war包(maven项目)错误To see the full stack trace of the errors, re-run Maven with the -e switch
- DrawLayout侧拉
- 如何对你的linux服务器进行快捷管理