今儿想和大家聊聊关于聚类的问题!!!!
在这之前咱们已经聊过 各个算法的优缺点的总结,以及8个回归类算法、7个正则化算法的总结、5 个集成算法模型、svm算法的全部总结、距离算法总结!!
感兴趣的可以翻到之前看看~
大部分人对聚类的认识可以归纳为以下几个方面:
数据分组:许多人将聚类视为将数据划分为不同的组或簇,使得同一组内的数据点更加相似或相关。这种观点认为聚类是一种无监督学习技术,用于发现数据中的内在结构和模式。
相似性度量:通常认为聚类算法通过计算数据点之间的相似性或距离来确定它们是否属于同一簇。相似性度量可以基于欧氏距离、余弦相似度等方法。
发现未知群体:聚类被视为一种工具,用于发现现有数据中隐藏的未知群体。通过聚类分析,可以发现数据集中的潜在模式、群体或类别,从而帮助了解数据的特征和结构。
应用领域:人们普遍认为聚类广泛应用于各个领域,如市场细分、客户分析、图像分割、推荐系统等。聚类可以帮助理解和利用大规模数据集,探索数据中的关联性和趋势。
然而,值得注意的是,不同人对聚类的认识和理解可能存在差异,因为聚类本质上是一个多样化的领域,涉及多种算法和技术。此外,聚类也可能面临一些挑战,如选择合适的距离度量、确定最佳簇的数量等。因此,在使用聚类算法时,需要根据具体问题和数据特点进行适当的选择和调整。
今天就来详细说说常见的几种:
大家伙如果觉得还不错!可以点赞、转发安排起来,让更多的朋友看到。
K均值聚类是一种常用的无监督学习算法,用于将数据点划分为不同的簇,使得同一簇内的数据点彼此相似度较高,不同簇之间的数据点相似度较低。
这个算法的目标是将数据点分为K个簇,其中K是用户定义的参数。K均值聚类的原理相对简单,主要思想是通过迭代寻找K个簇的中心点,将每个数据点分配给距离其最近的中心点,然后更新中心点的位置,直到满足停止条件为止。
1、选择要分成的簇的数量K。
2、随机初始化K个中心点,这些中心点可以是从数据集中随机选择的数据点。
3、重复以下过程,直到满足停止条件:
停止条件通常可以是以下之一:
K均值聚类的主要公式包括:
距离度量(一般使用欧氏距离):
对于两个数据点X和Y,它们之间的欧氏距离可以表示为:
其中,n是特征的数量。
计算每个数据点到每个中心点的距离:
其中,是第i个中心点,表示数据点X到中心点的距离。
分配数据点到最近的中心点:
即,将数据点X分配到距离它最近的中心点所属的簇。
更新中心点:
即,将每个簇的中心点更新为该簇内所有数据点的平均值。
一个用Python/ target=_blank class=infotextkey>Python实现K均值聚类:
import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
# 生成随机数据
np.random.seed(0)
X = np.random.rand(100, 2)
# 使用K均值聚类,假设要分成3个簇
kmeans = KMeans(n_clusters=3)
kmeans.fit(X)
# 获取簇的中心点和每个数据点的所属簇
centers = kmeans.cluster_centers_
labels = kmeans.labels_
# 绘制数据点和簇中心
plt.scatter(X[:, 0], X[:, 1], c=labels)
plt.scatter(centers[:, 0], centers[:, 1], marker='x', s=200, linewidths=3, color='r')
plt.title('K-Means Clustering')
plt.show()
这段代码首先生成一些随机数据,然后使用scikit-learn库的KMeans类进行聚类,并绘制了数据点和簇中心的图形。
可以看到K均值聚类是如何将数据点分成不同的簇的,并找到簇的中心点。图形展示了数据点的分布以及簇中心的位置。
层次聚类 通过构建数据点之间的层次结构来组织簇。这种层次结构通常以树状图(树状图或谱系图)的形式呈现,可以帮助理解数据点之间的相似性关系以及簇之间的关系。
层次聚类可以分为两种主要类型:自上而下的凝聚聚类和自下而上的分裂聚类。
层次聚类的主要步骤包括:
在层次聚类中,距离度量是关键。常用的距离度量包括欧氏距离、曼哈顿距离、马氏距离等,具体选择取决于问题的性质。合并或分裂簇的准则也可以有多种,例如最短距离、最长距离、平均距离等。
使用 scikit-learn 实现层次聚类:
import numpy as np
from sklearn.cluster import AgglomerativeClustering
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import dendrogram
# 生成随机数据
np.random.seed(0)
X = np.random.rand(10, 2)
# 使用凝聚聚类,假设要分成2个簇
agg_clustering = AgglomerativeClustering(n_clusters=2)
agg_clustering.fit(X)
# 绘制树状图(谱系图)
linkage_matrix = np.column_stack([agg_clustering.children_, agg_clustering.distances_])
dendrogram(linkage_matrix, p=10, truncate_mode='level')
plt.title('Hierarchical Clustering Dendrogram')
plt.xlabel('Data point index')
plt.ylabel('Distance')
plt.show()
首先生成一些随机数据,然后使用scikit-learn库的AgglomerativeClustering类进行凝聚聚类,并绘制了树状图(谱系图)。树状图显示了数据点的分层结构,以及簇之间的合并情况。
密度聚类 根据数据点周围的密度来发现簇。最著名的密度聚类算法之一是DBSCAN(Density-Based Spatial Clustering of Applications with Noise)。
DBSCAN是一种基于密度的聚类算法,它的主要思想是根据数据点周围的密度来确定簇的边界。
与K均值等算法不同,DBSCAN不需要事先指定簇的数量,而且能够发现各种形状的簇,同时还能识别异常点(噪声)。
DBSCAN 算法的核心思想是通过以下两个参数来定义簇:
1、**ε (epsilon)**:表示半径,它用来确定一个点的邻域范围。
2、MinPts:表示一个点的邻域内至少包含的数据点数目。
DBSCAN 算法的工作流程如下:
1、随机选择一个未被访问的数据点作为起始点。
2、计算该点的ε邻域内的数据点数量。
3、如果邻域内的数据点数目大于等于MinPts,则将该点标记为核心点(Core Point),并将其邻域内的所有点加入同一簇中。
4、重复以上过程,直到无法找到更多的核心点。
5、选择下一个未被访问的数据点,继续上述过程,直到所有数据点都被访问。
最终,所有被访问的点都将属于某个簇或者被标记为噪声点。
使用 Scikit-Learn 中的DBSCAN 做一个密度聚类。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
from sklearn.datasets import make_blobs
# 创建一个随机数据集
X, _ = make_blobs(n_samples=1000, centers=3, cluster_std=1.0, random_state=42)
# 使用DBSCAN算法进行密度聚类
dbscan = DBSCAN(eps=0.5, min_samples=5)
dbscan.fit(X)
# 获取每个点的簇标签
labels = dbscan.labels_
# 绘制聚类结果
unique_labels = np.unique(labels)
colors = plt.cm.Spectral(np.linspace(0, 1, len(unique_labels)))
for label, color in zip(unique_labels, colors):
if label == -1:
# 噪声点用黑色表示
color = 'k'
class_member_mask = (labels == label)
xy = X[class_member_mask]
plt.scatter(xy[:, 0], xy[:, 1], c=color, s=20, label='Cluster %d' % label)
plt.title('DBSCAN Clustering')
plt.legend()
plt.show()
这个示例使用了Scikit-Learn中的DBSCAN类来对一个具有3个簇的数据集进行聚类。
实际情况中,可以根据自己的数据和参数来调整代码以适应不同的情况。
谱聚类 通过将数据集表示为图的形式来进行聚类分析。
谱聚类在图论、线性代数和谱分析等领域有广泛的应用,它能够有效地处理复杂的数据结构,并且在一些情况下表现出色。
1、构建相似度图(Affinity Matrix):首先,将数据集中的样本视为图的节点,计算每一对样本之间的相似度。通常使用高斯核函数来度量相似性,具体计算方式如下:
这里,表示样本和之间的相似度,和是样本的特征向量,是高斯核的带宽参数。
2、构建拉普拉斯矩阵(Laplacian Matrix):将相似度矩阵转换成拉普拉斯矩阵。常用的拉普拉斯矩阵有两种形式:
a. 无向图拉普拉斯矩阵(Unnormalized Laplacian):,其中是度矩阵,其对角线元素表示节点的度(与节点相连的边的数量),是相似度矩阵。
b. 对称归一化拉普拉斯矩阵(Normalized Laplacian):,其中是单位矩阵。
3、计算特征向量:通过求解拉普拉斯矩阵的特征值问题,得到其前个最小特征值对应的特征向量,构成矩阵。
4、聚类:将矩阵的每一行作为新的特征向量,然后使用传统的聚类算法(如K均值)对这些特征向量进行聚类。
依旧使用 Scikit-Learn 进行实现:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.cluster import SpectralClustering
from sklearn.metrics import pairwise_distances
from scipy.sparse import csgraph
# 生成一个随机的月亮形状的数据集
X, _ = make_moons(n_samples=1000, noise=0.05, random_state=42)
# 计算相似度矩阵
sigma = 0.2
W = np.exp(-pairwise_distances(X, metric="sqeuclidean") / (2.0 * sigma ** 2))
# 构建对称归一化拉普拉斯矩阵
D = np.diag(W.sum(axis=1))
L = D - W
D_sqrt_inv = np.linalg.inv(np.sqrt(D))
L_sym = np.dot(np.dot(D_sqrt_inv, L), D_sqrt_inv)
# 计算特征向量
k = 2 # 聚类数
eigenvalues, eigenvectors = np.linalg.eigh(L_sym)
X_new = eigenvectors[:, :k]
# 使用谱聚类
sc = SpectralClustering(n_clusters=k, affinity="precomputed", random_state=42)
labels = sc.fit_predict(W)
# 可视化结果
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap="viridis")
plt.title("Spectral Clustering Result")
plt.subplot(1, 2, 2)
plt.scatter(X[:, 0], X[:, 1], c=_, cmap="viridis")
plt.title("Original Data")
plt.show()
首先生成一个月亮形状的数据集,然后计算相似度矩阵,构建对称归一化拉普拉斯矩阵,计算特征向量,最后使用谱聚类对数据集进行聚类,并可视化聚类结果和原始数据。
EM聚类 基于概率分布对数据进行建模,通过迭代的期望和最大化步骤来估计模型参数,并将数据分为不同的聚类。EM聚类通常用于处理混合分布的数据,其中每个聚类被建模为一个概率分布。
EM聚类的核心思想是将数据集中的每个样本视为来自于一个潜在的分布(通常是多元高斯分布)的观测结果。该算法迭代地执行两个步骤:
1、Expectation Step(E步骤):在这一步中,计算每个样本属于每个聚类的概率,即计算后验概率。这一步使用当前估计的模型参数(均值和协方差矩阵)来计算后验概率。
2、Maximization Step(M步骤):在这一步中,基于E步骤中计算得到的后验概率,更新模型的参数,包括均值和协方差矩阵,以使似然函数最大化。这一步是一个最大似然估计(MLE)步骤。
重复执行E步骤和M步骤,直到收敛或达到预定的迭代次数。
最终,每个样本将被分配到一个聚类中,同时模型的参数将收敛到使数据最可能的参数值。
EM聚类的主要数学公式涉及多元高斯分布。假设有个聚类,每个聚类被建模为一个多元高斯分布:
1、多元高斯分布:
多元高斯分布的概率密度函数如下,其中是均值,是协方差矩阵,是样本特征向量:
2、E步骤:计算每个样本属于每个聚类的后验概率,即条件概率:
其中,表示样本属于聚类的后验概率,是聚类的先验概率。
3、M步骤:更新模型参数,包括均值和协方差矩阵:
其中, 是更新后的聚类的均值, 是更新后的聚类的协方差矩阵。
下面使用EM聚类算法对一个大型数据集进行聚类:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.mixture import GaussianMixture
# 生成一个随机的大型数据集
X, _ = make_blobs(n_samples=2000, centers=4, random_state=42)
# 使用EM聚类
gmm = GaussianMixture(n_components=4, random_state=42)
labels = gmm.fit_predict(X)
# 可视化结果
plt.figure(figsize=(8, 6))
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap="viridis")
plt.title("EM Clustering Result")
plt.show()
代码中生成了一个包含4个聚类数据集,并使用EM聚类算法对数据进行聚类,并最终可视化聚类结果。
EM 聚类算法能够有效地识别数据中的聚类结构。
模糊聚类与传统的硬聚类方法(如K均值)不同,它允许数据点属于多个不同的聚类,而不是仅属于一个确定的聚类。
模糊聚类通常使用模糊集合理论来描述数据点与聚类的隶属度(membership degree),因此也称为模糊C均值(Fuzzy C-Means,FCM)算法。
模糊聚类的目标是将数据点划分为多个模糊聚类,每个数据点可以与每个聚类关联一个隶属度,表示其属于该聚类的程度。这个隶属度通常在0到1之间,0表示不属于聚类,1表示完全属于聚类。
FCM的主要思想是最小化数据点与聚类中心之间的加权欧氏距离的平方,其中权重是隶属度的幂。这可以用以下公式表示:
对于数据点i和聚类:
其中:
FCM 的优化过程通常使用迭代方法,通过更新隶属度和聚类中心来逐步优化目标函数。
使用sklearn库中的FCM算法进行模糊聚类:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score, calinski_harabasz_score, davies_bouldin_score, adjusted_rand_score
from fcmeans import FCM
# 生成模拟数据
n_samples = 3000
n_features = 2
n_clusters = 4
X, y = make_blobs(n_samples=n_samples, n_features=n_features, centers=n_clusters, random_state=42)
# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 使用FCM进行模糊聚类
fcm = FCM(n_clusters=n_clusters)
fcm.fit(X_scaled)
# 获取聚类标签
fuzzy_labels = np.argmax(fcm.u, axis=1)
# 绘制模糊聚类结果
plt.figure(figsize=(10, 6))
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=fuzzy_labels, cmap='viridis', s=50, alpha=0.5)
plt.scatter(fcm.centers[:, 0], fcm.centers[:, 1], marker='X', c='red', s=200, label='Cluster Centers')
plt.title('Fuzzy Clustering with FCM')
plt.legend()
plt.show()
# 计算模糊聚类的轮廓系数
silhouette_avg = silhouette_score(X_scaled, fuzzy_labels)
print(f'Silhouette Score: {silhouette_avg}')
# 计算每个数据点的轮廓系数
silhouette_values = silhouette_samples(X_scaled, fuzzy_labels)
# 绘制轮廓系数图
plt.figure(figsize=(8, 6))
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=fuzzy_labels, cmap='viridis', s=50, alpha=0.5)
plt.title('Silhouette Plot for Fuzzy Clustering')
plt.xlabel('Silhouette Coefficient Values')
plt.ylabel('Cluster Labels')
plt.colorbar()
plt.show()
首先生成模拟数据,然后使用FCM进行模糊聚类。
然后计算了轮廓系数、Calinski-Harabasz指数、Davies-Bouldin指数和调整兰德指数(如果有真实标签)。
最后,绘制了模糊聚类结果的散点图和轮廓系数图,以可视化评估聚类质量。
注意:需要提前安装scikit-learn
、matplotlib
、numpy
、fcmeans
等