聚类算法作为无监督学习的核心分支,就像一位“智能分类师”,能在没有标签的数据集里,自动把相似的对象归为一类,把不同的对象分开。它广泛应用于客户分群、图像分割、异常检测等场景,接下来我们用通俗易懂的方式拆解常见聚类算法的原理、例子和代码实现。
一、K-Means聚类:最经典的“中心靠拢”算法
原理
K-Means是最常用的聚类算法之一,核心思想很简单:先指定要划分的类别数K,随机选取K个点作为初始聚类中心,然后反复做两件事:一是把每个样本分配到距离最近的中心所在的类别;二是根据每个类的样本重新计算新的聚类中心。直到聚类中心不再变化,或者变化很小,就完成了聚类。
可以类比成:老师要把学生分成K组,先随便选K个学生当组长,然后让其他学生选离自己“最合得来”的组长组队;组队后,每组重新选一个“最能代表大家”的新组长,再重复这个过程,直到每组的组长不再更换,分组就稳定了。
例子
比如电商平台要对用户分群,选取“月消费额”和“月购买次数”两个特征,假设指定K=3,K-Means就能自动把用户分成“高消费高频次”“低消费低频次”“中等消费中等频次”三类,方便平台针对不同群体做精准营销。
代码实现(Python)
我们用sklearn库实现K-Means,以经典的鸢尾花数据集为例(虽然鸢尾花有标签,但可以当作无监督数据来聚类):
fromsklearn.clusterimportKMeansfromsklearn.datasetsimportload_irisimportmatplotlib.pyplotasplt# 加载数据,取前两个特征方便可视化iris=load_iris()X=iris.data[:,:2]# 构建K-Means模型,指定聚类数为3kmeans=KMeans(n_clusters=3,random_state=42)y_pred=kmeans.fit_predict(X)# 可视化聚类结果plt.scatter(X[:,0],X[:,1],c=y_pred,cmap='viridis')plt.scatter(kmeans.cluster_centers_[:,0],kmeans.cluster_centers_[:,1],s=200,c='red',marker='X',label='聚类中心')plt.xlabel('花萼长度')plt.ylabel('花萼宽度')plt.legend()plt.title('K-Means聚类结果')plt.show()二、层次聚类:“树状图”式的逐步聚合/分裂
原理
层次聚类就像搭建一棵“分类树”,分为两种方式:
- 凝聚式(自下而上):一开始每个样本都是一个单独的类,然后不断把最相似的两个类合并,直到所有样本聚成一个类,或者达到指定的类别数。
- 分裂式(自上而下):一开始所有样本是一个大类,然后不断把最不相似的类拆分,直到每个样本都是单独的类,或者达到指定类别数。
可以类比成:一堆散落在地上的积木,凝聚式就是先把相似的积木两两拼在一起,再把拼好的小模块继续合并,最后拼成一个大整体;分裂式则是先把所有积木看成一个大整体,然后慢慢拆成小模块,直到每个积木单独分开。
例子
在生物分类中,层次聚类可以用来构建物种的进化树:从单个物种开始,把亲缘关系近的物种逐步合并,最终形成一棵展示物种进化关系的树状图。
代码实现(Python)
用scipy和sklearn实现凝聚式层次聚类:
fromsklearn.clusterimportAgglomerativeClusteringfromsklearn.datasetsimportmake_blobsimportmatplotlib.pyplotaspltfromscipy.cluster.hierarchyimportdendrogram,linkage# 生成模拟数据X,_=make_blobs(n_samples=50,centers=3,random_state=42)# 构建层次聚类模型agg_clustering=AgglomerativeClustering(n_clusters=3)y_pred=agg_clustering.fit_predict(X)# 绘制树状图(基于linkage矩阵)linked=linkage(X,'ward')# ward方法使合并后的类内方差最小plt.figure(figsize=(10,5))dendrogram(linked,orientation='top',distance_sort='descending',show_leaf_counts=True)plt.title('层次聚类树状图')plt.show()# 可视化聚类结果plt.scatter(X[:,0],X[:,1],c=y_pred,cmap='viridis')plt.xlabel('特征1')plt.ylabel('特征2')plt.title('凝聚式层次聚类结果')plt.show()三、DBSCAN:基于“密度”的异常检测能手
原理
DBSCAN(密度基于空间聚类的应用与噪声)不依赖预先指定类别数,它的核心是“密度”:把样本分为三类——核心点(周围一定范围内有足够多的样本)、边界点(靠近核心点但自身不是核心点)、噪声点(既不是核心点也不是边界点)。聚类过程就是找到所有相互可达的核心点和边界点,形成一个类,噪声点则被单独区分出来。
可以类比成:在人群中,核心点就是周围有很多朋友的人,边界点是靠近这些“社交达人”但自己朋友不多的人,噪声点是孤零零站在角落的人。DBSCAN会把相互认识的“社交达人”和他们身边的人归为一群,角落的人就是异常。
例子
在信用卡欺诈检测中,正常交易的样本会形成密集的簇,而欺诈交易因为数量少、特征异常,会被DBSCAN识别为噪声点,从而快速定位异常交易。
代码实现(Python)
用sklearn实现DBSCAN:
fromsklearn.clusterimportDBSCANfromsklearn.datasetsimportmake_moonsimportmatplotlib.pyplotasplt# 生成模拟的“月亮形”数据(K-Means难以处理这种非凸数据)X,_=make_moons(n_samples=200,noise=0.05,random_state=42)# 构建DBSCAN模型,eps是邻域半径,min_samples是邻域内最少样本数dbscan=DBSCAN(eps=0.3,min_samples=5)y_pred=dbscan.fit_predict(X)# 可视化聚类结果(-1表示噪声点)plt.scatter(X[:,0],X[:,1],c=y_pred,cmap='viridis')plt.xlabel('特征1')plt.ylabel('特征2')plt.title('DBSCAN聚类结果(-1为噪声点)')plt.show()四、高斯混合模型(GMM):“概率化”的聚类算法
原理
GMM假设每个类别的样本都服从高斯分布(正态分布),整个数据集是多个高斯分布的混合。它的核心是通过EM算法(期望最大化),估计每个高斯分布的均值、方差,以及每个样本属于各个高斯分布的概率,最终根据概率最大的类别给样本归类。
可以类比成:有几台不同的机器在生产零件,每台机器生产的零件尺寸服从不同的正态分布,GMM就能通过零件尺寸数据,反推出有几台机器,以及每个零件更可能是哪台机器生产的。
例子
在图像分割中,GMM可以根据像素的颜色、亮度等特征,把图像分成不同的区域,比如把背景和前景分开,因为背景和前景的像素分布通常符合不同的高斯分布。
代码实现(Python)
用sklearn实现GMM:
fromsklearn.mixtureimportGaussianMixturefromsklearn.datasetsimportmake_blobsimportmatplotlib.pyplotasplt# 生成模拟数据X,_=make_blobs(n_samples=300,centers=3,random_state=42)# 构建GMM模型,指定组件数为3gmm=GaussianMixture(n_components=3,random_state=42)y_pred=gmm.fit_predict(X)# 可视化聚类结果plt.scatter(X[:,0],X[:,1],c=y_pred,cmap='viridis')plt.xlabel('特征1')plt.ylabel('特征2')plt.title('高斯混合模型聚类结果')plt.show()以上只是常见聚类算法的基础介绍,实际应用中还有谱聚类、OPTICS等算法,不同算法适合不同的数据场景(比如K-Means适合凸形簇,DBSCAN适合非凸簇和异常检测)。
个人能力有限,文中介绍的算法原理和代码实现仅为基础入门内容,若需深入理解算法的数学推导和复杂场景下的调优技巧,还需参考专业书籍和学术资料进一步学习。