Python之ML–聚类分析
使用监督学习来构建学习模型,其中训练数据都是事先已知预测结果的,即训练数据中已提供了数据的类标;在本节,我们将转而研究聚类分析,它是一个无监督学习(unsupervised learning),可以在事先不知道正确结果(即无类标信息或预期输出值)的情况下,发现数据本身所蕴含的结构等信息;聚类的目标是发现数据中自然形成的分组,使得每个簇内样本的相似性大于与其他簇内样本的相似性
主要知识点如下:
使用k-means算法发现簇中心
使用自底向上的方法构建层次聚类树
基于密度聚类方法发现任意形状簇
一.使用k-means算法对相似性进行分组
k-means算法是基于原型的聚类.两种聚类:层次(hierarchical)聚类和基于密度(density-based)的聚类.基于原型的聚类意味着每个簇都对应一个原型,它可以是一些具有连续型特征的相似点的中心点(centroid)(平均值),或者是类别特征情况下相似点的众数(medoid)–最典型或是出现频率最高的点.虽然k-means算法可以高效识别球形簇,但是此算法的缺点在于必须事先指定先验的簇数量k.如果k值选择不当,则可能导致聚类效果不佳
尽管k-means聚类适用于高维数据,但出于可视化需要,我们将使用一个二维数据集的例子进行演示:
from IPython.display import Image
from sklearn.datasets import make_blobs
X,y=make_blobs(n_samples=150,
n_features=2,
centers=3,
cluster_std=0.5,
shuffle=True,
random_state=0)
import matplotlib.pyplot as plt
plt.scatter(X[:,0],X[:,1],c='blue',marker='o',s=50)
plt.grid()
plt.show()
我们刚才创建的数据集中包含150个随机生成的点,它们大致分为三个高密度区域,其二维散点图如下:
在聚类算法的实际使用应用,我们没有任何关于这些样本的类别基础信息;否则算法就要划分到监督学习的范畴.由此,我们的目标就是根据样本自身特征的相似性对其进行分组,对此可采用k-means算法,具体有如下四个步骤:
从样本点中随机选择k个点作为初始簇中心
将每个样本点划分到距离它最近的中心点u^(j),j属于{1,…,k}所代表的簇中
用各簇中所有样本的中心点替代原有的中心点
重复步骤2和3,直到中心点不变或者达到预定迭代次数时,算法终止
我们可以将相似性定义为距离的倒数,在m维空间中,对于特征取值为连续型实数的聚类分析来说,常用的距离度量标准是欧几里得距离的平方:
公式中,小标索引j为样本点x和y的第j个维度(特征列).使用上标i和j代表样本索引和簇索引
基于欧几里得度量标准,我们可以将k-means算法描述为一个简单的优化问题,通过迭代使用簇内误差平方和(within-cluster sum of squared errors,SSE)最小,也称作簇惯性(cluster intertia)
其中,u 为簇j的中心点,如果样本x属于簇j,则有w=1,否则w=0
使用scikit-learn中的KMeans类将k-means算法应用于我们的示例数据集:
from sklearn.cluster import KMeans
km=KMeans(n_clusters=3,
init='random',
n_init=10,
max_iter=300,
tol=1e-04,
random_state=0)
y_km=km.fit_predict(X)
我们设定簇数量为3个;指定先验的簇数量是k-means算法的一个缺陷,设置n_init=10,程序能够基于不同的随机初始中心点独立运行算法10次,并从中选择SSE最小的作为最终模型;通过max_iter参数,指定算法每轮运行的迭代次数.请注意,在scikit-learn对k-means算法的实现中,如果模型收敛了,即使未达到预定迭代次数,算法也将终止
解决收敛问题的一个方法就是为tol参数设置一个较大的值,此参数控制对簇内误差平方和的容忍度,此容忍度用于判定算法是否收敛
1.k-means++
我们已经讨论了经典的k-means算法,它使用随机点作为初始中心点,若初始中心点选择不当,有可能会导致簇效果不佳或产生收敛速度慢等问题.解决此问题的一种方案就是在数据集上多次运行k-means算法,并根据误差平方和(SSE)选择性最好的模型.另一种方案就是使用k-means++算法让初始中心点彼此尽可能远离,相比传统k-means算法,它能够产生更好,更一致的结果
k-means++算法的初始化过程可以概括如下:
初始化一个空的集合M,用于存储选定的k个中心点
从输入样本中随机选定第一个中心点u,并将其加入到集合M中
对于集合M之外的任一样本点x通过计算找到与其平方距离最小的样本d(x,M)
使用加权概率分布来随机选择下一个中心点u
重复步骤2,3,直到选定k个中心点
基于选定的中心点执行k-means算法
通过scikit-learn的KMeans对象来实现k-means算法,只需将init参数的值random替换为k-means(默认值)即可
我们已经将簇结果存储在y_km中,并且讨论k-means算法面临的挑战.现在对k-means算法的簇结果及其相应的簇中心做可视化展示.簇中心保存在KMeans对象的centers_属性中:
plt.scatter(X[y_km==0,0],X[y_km==0,1],
s=50,c='lightgreen',marker='s',label='cluster 1')
plt.scatter(X[y_km==1,0],X[y_km==1,1],
s=50,c='orange',marker='o',label='cluster 2')
plt.scatter(X[y_km==2,0],X[y_km==2,1],
s=50,c='lightblue',marker='v',label='cluster 3')
plt.scatter(km.cluster_centers_[:,0],km.cluster_centers_[:,1],
s=250,c='red',marker='*',label='centroids')
plt.legend()
plt.grid()
plt.show()
在上面的散点图中,我们可以看到,通过k-means算法得到的3个中心点位于各球状簇的圆心位置
k-means的缺点之一就是我们必须指定一个先验的簇数量k,但在实际应用中,簇数量并非总是显而易见的,特别当我们面对的是一个无法可视化展现的高维数据集.k-means的另一个特点就是簇不可重叠,也不可分层,并且假定每个簇至少会有一个样本
2.硬聚类与软聚类
硬聚类(hard clustering)指的是数据集中每个样本只能划至一个簇的算法
软聚类(soft clustering)指的是一个样本划分到一个或者多个簇
3.使用肘方法确定簇的最佳数量
无监督学习中存在一个问题,就是我们并不知道问题的确切答案.由于没有数据集样本类标的确切数据,我们无法在无监督学习中使用评估监督学习模型性能的相关技术.因此,为了对聚类效果进行定量分析,我们需要使用模