sklearn聚类之谱聚类SpectralClustering

基本原理

谱聚类是一种基于图论的聚类方法,所谓图,就是将空间中的所有点连接起来,只要这些连接中出现了一个圈,就可以称之为图。如果把这些连线加上一个权重,就叫做加权图。

如果连线越长则权重越小,连线越短则权重越大,然后把权重最小的边切断,使得一个图变成两个图,便完成了一次聚类,这就是谱算法的基本思路,而其基本流程,就是构图->切图。

所以,问题来了,如何构图?若将所有的点都连接起来,这显然有些离谱,毕竟这种平方级别的复杂度不是一般内存能吃得消的,作为有一点聚类基础的人,第一时间就会想到KNN算法,即k近邻。

由于谱聚类中,两个点是否要被切断,最关键的因素是短边而非长边,所以只要将点与其最近的k个点连接起来就行了。这样得到的图有一个问题,即x最近的k个点中可能有y,但y最近的k个点中可能没有x,像极了女神和你。

对此有两种解决方案,一种是x也不要y了,另一种是强制让x加入到y的近邻中。

除了k近邻之外,还可以定死一个距离r,凡是距离小于r的都连线,大于r的都不连线。由于点和点之间的距离往往相差较大,故其权重一般会在距离的基础上做一些变换,这个变换在下文乘坐权重函数。

sklearn中谱聚类的构造

sklearn中,谱聚类的构造函数为

SpectralClustering(n_clusters=8, *, eigen_solver=None, n_components=None, random_state=None, n_init=10, gamma=1.0, affinity='rbf', n_neighbors=10, eigen_tol='auto', assign_labels='kmeans', degree=3, coef0=1, kernel_params=None, n_jobs=None)

其中affinity参数表示构图方法,可以输入字符串或者sklearn.metrics.pairwise.pairwise_kernels中的函数,当输入字符串时:

  • nearest_neighbors: 表示采用最邻近算法
  • rbf:即rbf方法,表达式为 e − γ d i j 2 e^{-\gamma d_{ij}^2} eγdij2 d i j d_{ij} dij表示点i和j的距离。

pairwise_kernels中,还支持5种变换方法:rbf,sigmoid, polynomial/poly, linear, cosine

当选择最近邻算法时,可通过参数n_neighbors来设置最近邻的个数,即KNNK

当选择rbf时,可通过参数gamma来设置权重函数的系数 γ \gamma γ

当选择poly或者polynomial时,表示采用多项式函数,可通过degree来设置最高次的值。

当采用多项式或者sigmoid时,可通过coef0来设置0阶项系数。

通过kernel_params可以设置更加复杂的权重函数的系数。

此外,还有如下常用的参数

  • n_clusters 聚类数
  • eigen_solver 特征值分解策略,可选**‘arpack’, ‘lobpcg’’amg’;其中amg要求安装pyamg**,可以更快地处理大规模样本,但可能有点不稳定;
  • random_state:随机数种子,便于结果复现
  • n_init:k-means算法的初值个数
  • eigen_tol:精度要求
  • assign_labels:表示分配标签的策略,可选kmeans, discretizecluster_qr
  • n_jobs 并行数

实战

import numpy as np
from sklearn import datasets
from sklearn.cluster import SpectralClustering
import matplotlib.pyplot as plt

X, y = datasets.make_circles(n_samples=1000, factor=0.5, noise=0.05)

fig = plt.figure()

# 谱聚类默认聚类数为8
model = SpectralClustering().fit(X)
ax = fig.add_subplot(131)
ax.scatter(X[:,0], X[:,1], c=model.labels_, marker='.')

model = SpectralClustering(n_clusters=2).fit(X)
ax = fig.add_subplot(132)
ax.scatter(X[:,0], X[:,1], c=model.labels_, marker='.')


model = SpectralClustering(n_clusters=2, affinity="nearest_neighbors").fit(X)
ax = fig.add_subplot(133)
ax.scatter(X[:,0], X[:,1], c=model.labels_, marker='.')

plt.show()

效果为

在这里插入图片描述

SpectralClustering有一个成员是affitiny_matrix_,存储了连接矩阵,将其调出后,可绘制具体的图

model = SpectralClustering( affinity="nearest_neighbors").fit(X)
inds = model.affinity_matrix_.nonzero()
inds = np.array(inds).T

for ind in inds:
    tmp = plt.plot(X[ind,0], X[ind, 1], c='g', lw=0.5)

plt.scatter(X[:,0], X[:,1], c=model.labels_, marker='o')

plt.show()

效果为

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微小冷

请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值