谱聚类和Kmeans聚类算法实现(python的sklearn)

Kmeans算法大家都基本耳熟能详了,而谱聚类算法的过程如下

 

 

  1. 构建样本相似度矩阵S
  2. 根据S构建度矩阵H
  3. 计算拉普拉斯矩阵L=H-S 
  4. 构建标准化拉普拉斯矩阵 H(-1/2)LH(-1/2)
  5. 计算 L  的最小的K个特征值对应的特征向量(K为cluster数量)
  6. 将向量按照行进行标准化(每个元素除以本行所有元素的平方和在开根号)得到N*K的矩阵F,N为样本点数
  7. F中每一行作为一个样本,共N个样本,对其进行聚类
  8. 得到cluster{C1,C2,…Ck}  

  起始本质就是得到特征矩阵之后在对特征矩阵执行 聚类

代码如下(jupyter运行)

import numpy as np
import matplotlib.pyplot as plt
import random
import heapq
from sklearn.cluster import KMeans
import sklearn
import pyamg

#参数初始化

N=20 #用户数
distance=2000 #距离
sigma_d=100
K=4 #无人机数量

 

users=np.random.randint(0,distance+1,(N,2))#0-2000随机20个点
scatter_x=[]
scatter_y=[]
for i in range(N):
scatter_x.append(users[i][0])
scatter_y.append(users[i][1])

#矩阵S

matric_S=np.zeros((N,N))
for i in range(N):
  for j in range(N):
    matric_S[i][j]=np.exp(-((scatter_x[i]-scatter_x[j])**2+(scatter_x[i]-scatter_x[j])**2)/(2*sigma_d**2))

 

#矩阵H(度矩阵)

matric_H=np.zeros((N,N))

for i in range(N):
  for j in range(N):
    matric_H[i][i]=matric_H[i][i]+matric_S[i][j]

#矩阵H(度矩阵负二分之一次幂)

matric_H_ = np.sqrt(np.linalg.inv(matric_H))

 

#将数组转化为矩阵
matric_S=np.mat(matric_S)
matric_H=np.mat(matric_H)
matric_H_=np.mat(matric_H_)

#拉普拉斯矩阵

matric_L=np.dot(np.dot(matric_H_,(matric_H-matric_S)),matric_H_)

求解特征值 w 和特征向量 v 

w, v = np.linalg.eigh(matric_L)
print(w)
w=list(w)
min_4 = map(w.index, heapq.nsmallest(K, w))
min_4=list(min_4)
min_4.sort()
print(min_4)

 

#特征值矩阵U

matric_U=np.zeros((N,K))
for i in range(N):
  for j in range(K):
    matric_U[i,j]=v[i,min_4[j]]

#特征值归一化矩阵T

matric_T=np.zeros((N,K))
for i in range(N):
  for j in range(K):
    matric_T[i,j]=matric_U[i,j]/np.sqrt((matric_U[i,0]**2+matric_U[i,1]**2+matric_U[i,2]**2+matric_U[i,3]**2))

 

 

#对特征值进行Kmeans聚类

kmeans = KMeans(n_clusters=4, init='k-means++', random_state=1,n_init=100).fit(matric_T)
colors = []
for i in range(kmeans.labels_.shape[0]):
  if kmeans.labels_[i] == 1:
    colors.append('red')
  elif kmeans.labels_[i] == 2:
    colors.append('blue')
  elif kmeans.labels_[i] == 3:
    colors.append('green')
  else:
    colors.append('purple')

 

#对原始数据进行Kmeans聚类

kmeans_=KMeans(n_clusters=4, init='k-means++', random_state=1,n_init=100).fit(users)
colors_ = []
for i in range(kmeans_.labels_.shape[0]):
  if kmeans_.labels_[i] == 1:
    colors_.append('red')
  elif kmeans_.labels_[i] == 2:
    colors_.append('blue')
  elif kmeans_.labels_[i] == 3:
    colors_.append('green')
  else:
    colors_.append('purple')

 

#可视化

plt.figure(dpi=720,figsize=(24,8))

plt.subplot(131)
plt.title('random users')
plt.grid()
plt.scatter(scatter_x,scatter_y)
# plt.scatter(scatter_x,scatter_y,color='',edgecolors='blue')

plt.subplot(132)
plt.title('kmeans ')
plt.grid()
# plt.scatter(scatter_x, scatter_y, color='',edgecolors=colors_, marker='o')
plt.scatter(scatter_x, scatter_y, c=colors_, marker='o')


plt.subplot(133)
plt.title('spectral cluster ')
plt.grid()
plt.scatter(scatter_x, scatter_y, c=colors, marker='o')
# plt.scatter(scatter_x, scatter_y, color='',edgecolors=colors, marker='o')
plt.show()

 

 

 

 

 

 

 

 

 

但是效果不是那么好,哪位朋友能帮忙找下原因么,sklearn有集成的SpectralClustering谱聚类也可以自行使用,调制相关参数即可得到,我的效果也不太好

 

posted @ 2022-04-08 20:53  浅谈2134  阅读(264)  评论(0)    收藏  举报