毫升 |光谱聚类
先决条件: K-Means 聚类
Spectral Clustering是一种不断增长的聚类算法,在许多情况下它的性能优于许多传统的聚类算法。它将每个数据点视为一个图节点,从而将聚类问题转换为图分区问题。典型的实现包括三个基本步骤:-
- 构建相似图:此步骤以邻接矩阵的形式构建相似图,由 A 表示。邻接矩阵可以通过以下方式构建:-
- Epsilon-neighbourhood Graph:参数 epsilon 是预先固定的。然后,每个点都连接到其 epsilon 半径内的所有点。如果任何两点之间的所有距离在比例上都相似,则通常不存储边的权重,即两点之间的距离,因为它们不提供任何附加信息。因此,在这种情况下,构建的图是无向且未加权的图。
- K-Nearest Neighbors参数 k 是预先固定的。然后,对于两个顶点 u 和 v,只有当 v 在 u 的 k 最近邻中时,一条边才从 u 指向 v。请注意,这会导致加权和有向图的形成,因为对于每个将 v 作为 k-最近邻之一的 u 并不总是这样,对于 v 在其 k-最近邻中包含 u 的情况相同邻居。为了使该图无向,请遵循以下方法之一:-
- 如果 v 位于 u 的 k 个最近邻中或u 位于 v 的 k 个最近邻中,则将一条边从 u 指向 v 并从 v 指向 u。
- 如果 v 位于 u 的 k 个最近邻中且 u 位于 v 的 k 个最近邻中,则将一条边从 u 指向 v 并从 v 指向 u。
- 全连接图:要构建此图,每个点都与一个无向边相连,该边加权由两点到其他点之间的距离加权。由于这种方法用于对局部邻域关系进行建模,因此通常使用高斯相似度度量来计算距离。
- 将数据投影到较低的维度空间:执行此步骤是为了说明同一集群的成员在给定的维度空间中可能远离的可能性。因此,维度空间被缩减,使得这些点在缩减的维度空间中更接近,因此可以通过传统的聚类算法聚集在一起。它是通过计算图拉普拉斯矩阵来完成的。不过,要首先计算它,需要定义节点的度数。第 i 个节点的度数由下式给出
注意是上面邻接矩阵中定义的节点 i 和 j 之间的边。
度矩阵定义如下:-
因此,图拉普拉斯矩阵定义为:-
然后将该矩阵归一化以提高数学效率。为了减少维度,首先,计算特征值和各自的特征向量。如果簇的数量是 k,那么第一个特征值和它们的特征向量被提取并堆叠成一个矩阵,使得特征向量是列。
- 对数据进行聚类:此过程主要涉及通过使用任何传统的聚类技术(通常是 K-Means 聚类)对减少的数据进行聚类。首先,为每个节点分配一个归一化的 Graph Laplacian Matrix 的行。然后使用任何传统技术对这些数据进行聚类。为了转换聚类结果,保留节点标识符。
特性:
- 无假设:与其他传统技术不同,这种聚类技术不假设数据遵循某些属性。因此,这使得该技术可以回答更通用的聚类问题。
- 易于实现和速度:该算法比其他聚类算法更容易实现,并且速度也非常快,因为它主要由数学计算组成。
- 不可扩展:由于它涉及矩阵的构建以及特征值和特征向量的计算,因此对于密集数据集来说非常耗时。
以下步骤演示了如何使用 Sklearn 实现光谱聚类。以下步骤的数据是可以从 Kaggle 下载的信用卡数据。
第 1 步:导入所需的库
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import SpectralClustering
from sklearn.preprocessing import StandardScaler, normalize
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score
第 2 步:加载和清理数据
# Changing the working location to the location of the data
cd "C:\Users\Dev\Desktop\Kaggle\Credit_Card"
# Loading the data
X = pd.read_csv('CC_GENERAL.csv')
# Dropping the CUST_ID column from the data
X = X.drop('CUST_ID', axis = 1)
# Handling the missing values if any
X.fillna(method ='ffill', inplace = True)
X.head()
步骤 3:预处理数据以使数据可视化
# Preprocessing the data to make it visualizable
# Scaling the Data
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# Normalizing the Data
X_normalized = normalize(X_scaled)
# Converting the numpy array into a pandas DataFrame
X_normalized = pd.DataFrame(X_normalized)
# Reducing the dimensions of the data
pca = PCA(n_components = 2)
X_principal = pca.fit_transform(X_normalized)
X_principal = pd.DataFrame(X_principal)
X_principal.columns = ['P1', 'P2']
X_principal.head()
第 4 步:构建聚类模型并可视化聚类
在以下步骤中,两个不同的光谱聚类模型具有不同的参数“亲和力”值。您可以在此处阅读有关 Spectral Clustering 类的文档。
a)亲和力 = 'rbf'
# Building the clustering model
spectral_model_rbf = SpectralClustering(n_clusters = 2, affinity ='rbf')
# Training the model and Storing the predicted cluster labels
labels_rbf = spectral_model_rbf.fit_predict(X_principal)
# Building the label to colour mapping
colours = {}
colours[0] = 'b'
colours[1] = 'y'
# Building the colour vector for each data point
cvec = [colours[label] for label in labels_rbf]
# Plotting the clustered scatter plot
b = plt.scatter(X_principal['P1'], X_principal['P2'], color ='b');
y = plt.scatter(X_principal['P1'], X_principal['P2'], color ='y');
plt.figure(figsize =(9, 9))
plt.scatter(X_principal['P1'], X_principal['P2'], c = cvec)
plt.legend((b, y), ('Label 0', 'Label 1'))
plt.show()
b)亲和力 = 'nearest_neighbors'
# Building the clustering model
spectral_model_nn = SpectralClustering(n_clusters = 2, affinity ='nearest_neighbors')
# Training the model and Storing the predicted cluster labels
labels_nn = spectral_model_nn.fit_predict(X_principal)
第 5 步:评估性能
# List of different values of affinity
affinity = ['rbf', 'nearest-neighbours']
# List of Silhouette Scores
s_scores = []
# Evaluating the performance
s_scores.append(silhouette_score(X, labels_rbf))
s_scores.append(silhouette_score(X, labels_nn))
print(s_scores)
第 6 步:比较性能
# Plotting a Bar Graph to compare the models
plt.bar(affinity, s_scores)
plt.xlabel('Affinity')
plt.ylabel('Silhouette Score')
plt.title('Comparison of different Clustering Models')
plt.show()