聚类分析(英语:Cluster analysis)亦称为群集分析,是对于统计数据分析的一门技术,在许多领域受到广泛应用,包括机器学习,数据挖掘,模式识别,图像分析以及生物信息,顾客分类,文章分类等。聚类是把相似的对象通过静态分类的方法分成不同的组别或者更多的子集(subset),这样让在同一个子集中的成员对象都有相似的一些属性,常见的包括在坐标系中更加短的空间距离等。一般把数据聚类归纳为一种非监督式学习。
无监督学习(英语:unsupervised learning)是机器学习的一种方法,没有给定事先标记过的训练示例,自动对输入的数据进行分类或分群。无监督学习的主要运用包含:聚类分析(cluster analysis)、关系规则(association rule)、维度缩减(dimensionality reduce)。它是监督式学习和强化学习等策略之外的一种选择。一个常见的无监督学习是数据聚类。简单来说,就是给出的数据集合只有自变量,没有因变量,通过分析自变量,找出样本的关系,如分类、关系等。
分类和聚类的区别
分类:事先知道存在哪些类别(有x和y)
聚类:事先不知道存在哪些类别(只有x)
一、聚类分析的常见算法
K-Means(K均值)聚类
均值漂移聚类
基于密度的聚类方法(DBSCAN)
用高斯混合模型(GMM)的最大期望(EM)聚类
凝聚层次聚类
图团体检测(Graph Community Detection)
二、K-Means(K均值)聚类
算法步骤:
首先我们选择一些类/组,并随机初始化它们各自的中心点。中心点是与每个数据点向量长度相同的位置。这需要我们提前预知类的数量(即中心点的数量)。
计算每个数据点到中心点的距离,数据点距离哪个中心点最近就划分到哪一类中。
计算每一类中中心点作为新的中心点。
重复以上步骤,直到每一类中心在每次迭代后变化不大为止。也可以多次随机初始化中心点,然后选择运行结果最好的一个。
随机选择2个点(k=2)C1和C2,将剩下的所有点,根据距离C1和C2的距离的远近,划分给C1或者C2
根据获得的两类点,重新计算两类点中的质心(到该类所有点的距离最短)重新将所有的点归到两个新的质心的其中之一。
重复上面的过程,直到每一类中心在每次迭代后变化不大为止。
优点:速度快,计算简便,但缺点也比较明显:
我们必须提前知道数据有多少类/组;
聚类结果对初始类簇中心的选取较为敏感;
容易陷入局部最优;
只能发现球型类簇;
三、Python实现
3.1 导入模块和准备数据
import pandas as pd
import seaborn as sns
import numpy as np
from sklearn.cluster import KMeans
from sklearn.grid_search import GridSearchCV
iris = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data',header=None)
iris.columns=['SepalLengthCm','SepalWidthCm','PetalLengthCm','PetalWidthCm','Species']
features = ['PetalWidthCm','PetalLengthCm']
X = iris[features]
3.2 查看分类
sns.relplot(x="PetalWidthCm", y="PetalLengthCm", hue="Species",palette="Set1",data=iris)
3.3 模型建立
K均值聚类需要提供一个你希望的分类的数量,我们看看分成两类的效果如何。
km = KMeans(2)
km.fit(X)
iris['cluster_k2'] = km.predict(X)
sns.relplot(x="PetalWidthCm", y="PetalLengthCm", hue="cluster_k2",palette="Set1",data=iris)#把预测分类分类都在图表上画出来。
接下来我们看看分成三类的效果如何。
km = KMeans(3)
km.fit(X)
iris['cluster_k3'] = km.predict(X)
sns.relplot(x="PetalWidthCm", y="PetalLengthCm", hue="cluster_k3",palette="Set1",data=iris)#把预测分类都在图表上画出来。
如果用人眼判定,分三类其实和原来的类别很接近了,需要注意的是,我们一般做聚类,是没有原类别的。
那我们如何评价到底分多少个类别好呢,我们的X如果是两维的还可以画图来看看效果,X是三维以上就没办法画图了。
3.4 成本(目标)函数
成本(目标)函数:类内离差平方和\(\sum_{i=1}^k(\sum_{x∈C_{i}}dist(x,c_{i})^2)\),我们只有找到一个K使得目标函数最少,但一般情况下,K越大目标函数值越小,但随着K的增大,目标函数值会下降得越来越慢,我们找到下降一定的稳定程度就可以了。
接下来我们用网格搜索去循环计算不同的K值的目标函数值,并把目标函数对K的变化画图出来。
param_test1 = {'n_clusters':np.arange(2,11,1)}
gsearch1 = GridSearchCV(estimator = KMeans(),param_grid = param_test1,cv=5)
gsearch1.fit(X)
score_list=-pd.DataFrame(gsearch1.grid_scores_)['mean_validation_score']
sns.lineplot(x=range(2,11),y=score_list)
网格搜索有三个结果很常用:
gsearch1.grid_scores_:各个K值对应的得分
gsearch1.best_params_:最佳的K值
gsearch1.best_score_:最佳的得分
可以看出来,K=3及之后,目标函数值下降开始减缓,这样我们认为K=3就可以了。
对于环状的分类分别,K均值算法就无能为力了。记住K均值只能发现球型类簇。