一.总结
分析了网上找的一份谱聚类算法的python代码,以加深对其的理解。之所以先找python,一是因为python代码阅读较为容易,助于理解;缺点是算法的许多核心步骤作者直接调用库就完事了。。(这一点也是我做笔记做到后面才发现)因此后续还需要找C代码阅读,或者搞懂python库的内部实现原理。
另外还有一个重要问题,许多外网链接点不开(如github),代码查看不了,今天按网上的方法做了好久也没有解决,但许多资料又只有外网才能查,这一点后续解决吧
二. 学习笔记
1.距离矩阵
def euclidDistance(x1, x2, sqrt_flag=False): # 以欧氏距离为例
res = np.sum((x1-x2)**2)
if sqrt_flag:
res = np.sqrt(res)
return res
def calEuclidDistanceMatrix(X): # 生成距离矩阵S
X = np.array(X)
S = np.zeros((len(X), len(X))) # 先填充为全0
for i in range(len(X)):
for j in range(i+1, len(X)): # 只需要循环遍历比前一个点大的,因为小的可根据对称性得到
S[i][j] = 1.0 * euclidDistance(X[i], X[j])
S[j][i] = S[i][j] # 对称矩阵
return S
2.邻接(相似)矩阵
采用的是k临近法,也就是构建的A是稀疏相似矩阵
def myKNN(S, k, sigma=1.0):
N = len(S)
A = np.zeros((N,N))
# 对于每一个数据点,都先找出距离其最近的k个点,将它们的编号放进neighbours_id数组中
for i in range(N):
dist_with_index = zip(S[i], range(N))
dist_with_index = sorted(dist_with_index, key=lambda x:x[0])
neighbours_id = [dist_with_index[m][1] for m in range(k+1)]
# 遍历k个邻居中的每一个,用高斯核函数计算它们与当前数据点的相似度
for j in neighbours_id:
A[i][j] = np.exp(-S[i][j]/2/sigma/sigma)
A[j][i] = A[i][j] # mutually //对称
# 对于不是邻居的数据点,其与当前数据点相似度认为是0
return A
3.标准的拉普拉斯矩阵
def calLaplacianMatrix(adjacentMatrix): //输入是稀疏相似矩阵A
# 先计算度矩阵,其实np.diag(degreeMatrix)才是度矩阵
# axis=1表示将矩阵A的每一行相加,得到一个N*1的列向量
degreeMatrix = np.sum(adjacentMatrix, axis=1)
# 计算拉普拉斯矩阵:L=D-A
laplacianMatrix = np.diag(degreeMatrix) - adjacentMatrix
# 将拉普拉斯矩阵单位(标准)化 D^(-1/2) L D^(-1/2)
sqrtDegreeMatrix = np.diag(1.0 / (degreeMatrix ** (0.5))) # 计算D^(-1/2)
# np.dot当两个参数都为矩阵时,表示矩阵的乘法
return np.dot(np.dot(sqrtDegreeMatrix, laplacianMatrix), sqrtDegreeMatrix)
4.特征值分解
lam, H = np.linalg.eig(Laplacian)
# 这里直接使用numpy库里的现成函数
# lam是一个一维数组,其每个元素就是方阵Laplacian的一个特征值
# H是一个和Laplacian大小相同的矩阵,其每一个列向量就是
# Laplacian的一个单位化后的特征向量,顺序与lam元素一一对应
# 但要注意特征值并不一定是按顺序排列的
5.K-means
from sklearn.cluster import KMeans
def spKmeans(H):
sp_kmeans = KMeans(n_clusters=2).fit(H)
return sp_kmeans.labels_
# 这里也是直接调用了sklearn库中的k-means算法
以下是对skleaen.cluster库中的KMean的笔记:
(1)参数
n_clusters:整形,缺省值=8 【生成的聚类数,即产生的质心数】
max_iter:整形,缺省值=300 【执行一次k-means算法所进行的最大迭代数】
n_init:整形,缺省值=10 【用不同的质心初始化值运行算法的次数,最终解是在inertia意义下选出的最优结果】
init:有三个可选值:’k-means++’, ‘random’,或者传递一个ndarray向量。此参数指定初始化方法,默认值为 ‘k-means++’
precompute_distances:三个可选值,‘auto’,True 或者 False。预计算距离,计算速度更快但占用更多内存
‘auto’:如果 样本数乘以聚类数大于 12million 的话则不预计算距离
True:总是预先计算距离
False:永远不预先计算距离。
tol:float形,默认值= 1e-4 与inertia结合来确定收敛条件。
n_jobs:整形数。指定计算所用的进程数。内部原理是同时进行n_init指定次数的计算。
若值为 -1,则用所有的CPU进行运算
若值为1,则不进行并行运算
若值小于-1,则用到的CPU数为 n_cpus(总cpu数) + 1 + n_jobs
(2)属性
cluster_centers_:向量,[n_clusters, n_features] (聚类中心的坐标)
Labels_: 每个点的分类
inertia_:float形 每个点到其簇的质心的距离之和
(3)方法
fit(X[,y]):计算k-means聚类
三.工作记录
暂无