聚类是在线性主成分分析和非线性流形分析之外的一个无监督学习方法大类,聚类学习的目标是将不具有 标签的数据按照规则划分到不同的类别中,使类别内部的数据具有近似的 特性。聚类算法主要包含:
- K均值聚类 KMeans
- 仿射传播 Affinity propagation
- 均值漂移 Mean-shift
- 谱聚类 Spectral Clustering
- 凝聚聚类 Agglomerative clustering
- DBSCAN
- OPTICS
- 高斯混合 Gaussian Mixture
每种聚类算法的共性方法:
- 可以使用
fit
方法训练的聚类算法的参数, - 在给定训练集的情况下,返回对应于不同聚类结果的标签。对于不同的类,可以在
labels_
属性中找到训练结果的标签。
下面图中的每一列给出了9种算法对不同数据的聚类结果,用颜色代表了分类。
9种算法对不同数据的聚类效果
K均值 KMeans
- 无监督学习的KMeans算法与监督学习的K近邻算法原理基本相同,是通过把样本分离成个具有相同方差的类的方式来聚集数据。
- 算法最小化目标是惯量(inertia),也叫做簇内平方和(within-cluster sum-of-squares)。
- 算法需要指定簇的数量K。它可以很好地扩展到大量样本(large number of samples),并已经被广泛应用于许多不同领域的应用领域。
K-means通常被称为
劳埃德算法(Lloyd’s algorithm),可分为三个步骤:
- 选择初始质心(centroids):最基本的方法是从X数据集中选择
n_cluster
个样本。 - 将每个样本分配到其最近的质心,通过取分配给每个先前质心的所有样本的平均值来创建新的质心。
- 计算新旧质心之间的差异,并且重复后两步,直到该值小于阈值,即直到质心不再显著移动。
主要参数:
n_cluster
算法图示如下:
代码如下:
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
# 生成模拟的二维数据
X, y = make_blobs(random_state=1)
# 构建聚类模型
kmeans = KMeans(n_clusters=3)
kmeans.fit(X)
# 可以在 kmeans.labels_ 属性中找到分类标签
print("Cluster memberships:\n{}".format(kmeans.labels_))
# 也可以用 predict 方法为新数据点分配簇标签
print(kmeans.predict(X))
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
# 生成模拟的二维数据
X, y = make_blobs(random_state=1)
# 构建聚类模型
kmeans = KMeans(n_clusters=3)
kmeans.fit(X)
# 可以在 kmeans.labels_ 属性中找到分类标签
print("Cluster memberships:\n{}".format(kmeans.labels_))
# 也可以用 predict 方法为新数据点分配簇标签
print(kmeans.predict(X))
仿射传播 Affinity Propagation
AP聚类是通过在样本对之间发送消息直到收敛的方式来创建聚类。然后使用少量模范样本作为聚类中心来描述数据集,而这些模范样本可以被认为是最能代表数据集中其它数据的样本。在样本对之间发送的消息表示一个样本作为另一个样本的模范样本的适合程度,适合程度值在根据通信的反馈不断更新。更新迭代直到收敛,完成聚类中心的选取,因此也给出了最终聚类。信息类型:
- 第一种叫做responsibility,, 它反映了样本k适合作为样本i的聚类中心的程度;
- 第二种是availability,,反映了样本i选择样本k作为聚类中心的适合程度。
均值漂移 Mean-shift
均值漂移算法也是基于质心的算法,通过更新质心的候选位置,这些候选位置通常是所选定区域内点的均值。然后,这些候选位置在后处理阶段被过滤以消除近似重复,从而形成最终质心集合。
谱聚类 Spectral Clustering
谱聚类首先在样本之间进行关联矩阵的低维度
嵌入(即将高维离散数据转为低维连续数据的表示),然后在低维空间中使用 KMeans 算法进行分类。 谱聚类需要指定簇的数量,适用于簇数量少时,在簇数量多时是不建议使用。
谱聚类中的的assign_labels
参数代表着可以使用不同的分配策略,其中:
-
kmeans
可以匹配更精细的数据细节,但是可能更加不稳定。特别是,除非可以控制random_state
否则可能无法复现运行的结果,因为它取决于随机初始化。 - 使用
discretize
策略是 100% 可以复现的,但是它往往会产生相当均匀的几何形状的闭合块。
谱聚类还可以通过谱嵌入对图进行聚类。在这种情况下,关联矩阵(affinity matrix) 是图形的邻接矩阵,可以由
affinity=’precomputed’
进行初始化。
凝聚聚类 Agglomerative Clustering
凝聚聚类是
层次聚类的一种:
- 层次聚类代表着一类的聚类算法,这种类别的算法通过不断的合并或者分割内置聚类来构建最终聚类。
- 聚类的层次可以被表示成树(或者树形图(dendrogram)),树根是拥有所有样本的唯一聚类,叶子是仅有一个样本的聚类。
凝聚聚类使用自下而上的方法进行层次聚类:开始是每一个对象是一个聚类, 并且聚类别相继合并在一起。合并的标准包含以下几种:
- Ward:最小化所有聚类内的平方差总和。这是一种方差最小化(variance-minimizing)的优化方向,与k-means的目标函数相似的优化方法,但是用凝聚分层(agglomerative hierarchical)的方法处理。
- Maximum或complete:最小化成对聚类间最远样本距离。取两个集合中距离最远的两个点的距离作为两个集合的距离。
- Average:最小化成对聚类间平均样本距离值。把两个集合中的点两两的距离全部放在一起求均值,相对也能得到合适一点的结果。
- Single:最小化成对聚类间最近样本距离值。就是取两个类中距离最近的两个样本的距离作为这两个集合的距离。
四种连接方式的结果如下:
凝聚聚类的四种样本距离
凝聚聚类存在“强者恒强”的现象,会导致聚类大小不均匀。这方面Single 是最坏的策略,Ward给出了规则合适的大小。然而,在Ward中样本距离不能被改变,对于非欧氏度量来说, average则是一个好的选择。Single虽然对于噪声数据的鲁棒性并不强, 但是对规模较大的dataset提供非常有效的层次聚类算法,而且对非全局数据有很好的效果。
用凝聚算法预测
由于算法的工作原理,凝聚算法不能对新数据点做出预测。因此
AgglomerativeClustering
没有
predict
方法。为了构造模型并得到训练集上簇的成员关系,可以改用
fit_predict
方法,代码如下:
from sklearn.cluster import AgglomerativeClustering
X, y = make_blobs(random_state=1)
agg = AgglomerativeClustering(n_clusters=3)
assignment = agg.fit_predict(X)
mglearn.discrete_scatter(X[:, 0], X[:, 1], assignment)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
from sklearn.cluster import AgglomerativeClustering
X, y = make_blobs(random_state=1)
agg = AgglomerativeClustering(n_clusters=3)
assignment = agg.fit_predict(X)
mglearn.discrete_scatter(X[:, 0], X[:, 1], assignment)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
DBSCAN
介绍
- DBSCAN(density-based spatial clustering of applications with noise),意为“具有噪声的基于密度的空间聚类应用”。
- 优点是它不需要用户先验地设置簇的个数,可以划分具有复杂形状的簇,还可以找出不属于任何簇的点。DBSCAN比凝聚聚类和k均值稍慢,但仍可以扩展到相对较大的数据集。
- 思想是,簇形成数据的密集区域,并由相对较空的区域分隔开。
- 原理是识别特征空间的“拥挤”区域中的点,这些区域被称为特征空间中的密集(dense)区域。
算法
- 任意选取一个点,然后找到到这个点的距离小于等于eps的所有的点。
- 如果距起始点的距离在
eps
之内的数据点个数小于min_sample
s,那么这个点被标记为噪声(noise),也就是说它不属于任何簇;如果距离在 eps 之内的数据点个数大于min_samples
,则这个点被标记为核心样本,并被分配一个新的簇标签。 - 访问该点的所有邻居(在距离
eps
以内)。如果它们还没有被分配一个簇,那么就将刚刚创建的新的簇标签分配给它们。如果它们是核心样本,那么就依次访问其邻居,以此类推。簇逐渐增大,直到在簇的 eps 距离内没有更多的核心样本为止。 - 然后选取另一个尚未被访问过的点,并重复相同的过程。
- 最后,一共有三种类型的点:核心点、与核心点的距离在
eps
之内的点(叫作边界点, boundary point)和噪声。
在
min_samples
和
eps
参数不同取值的情况下,DBSCAN 找到的簇分配如下:
不同参数下的识别结果
代码如下:
X, y = make_moons(n_samples=200, noise=0.05, random_state=0)
# 将数据缩放成平均值为0、方差为1
scaler = StandardScaler() scaler.fit(X)
X_scaled = scaler.transform(X)
dbscan = DBSCAN()
clusters = dbscan.fit_predict(X_scaled)
# 绘制簇分配
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=clusters, cmap=mglearn.cm2, s=60)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
X, y = make_moons(n_samples=200, noise=0.05, random_state=0)
# 将数据缩放成平均值为0、方差为1
scaler = StandardScaler() scaler.fit(X)
X_scaled = scaler.transform(X)
dbscan = DBSCAN()
clusters = dbscan.fit_predict(X_scaled)
# 绘制簇分配
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=clusters, cmap=mglearn.cm2, s=60)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
OPTICS
OPTICS算法与DBSCAN算法有许多相似之处,可以认为是DBSCAN算法将
eps
要求从一个值放宽到一个值范围的推广。OPTICS与DBSCAN的关键区别在于OPTICS算法建立了一个可达性图,它为每个样本分配了一个
reachability_
(可达性距离)和一个簇
ordering_
属性内的点(spot);这两个属性是在模型拟合时分配的,用于确定簇的成员关系。如果运行OPTICS时
max_eps
设置为默认值inf,则可以使用
cluster_optics_dbscan
方法对任意给定的eps值在线性时间内重复执行DBSCAN样式的簇提取。将
max_eps
设置为一个较低的值将导致较短的运行时间,并可以视为从每个点到找到其他潜在可达点的最大邻域半径。
高斯混合 Gaussian Mixture
高斯混合模型是一种概率模型,它假设所有数据点都是从有限数量、参数未知的高斯分布混合分布中生成的。它可以被视为结合了数据结构方差以及潜在高斯分布中心信息的广义的K均值聚类。GaussianMixture对象使用
期望最大化算法-EM 算法来拟合混合高斯模型。它还可以为多元模型绘制
置信椭圆体,并计算贝叶斯信息准则以评估数据中的聚类数量。GaussianMixture可以用不同的选项来约束类别差异的协方差估计:spherical,diagonal,tied或full covariance。
不同约束下的高斯混合模型识别结果
总结
聚类的应用是对未知定性的过程,通常在数据分析的探索阶段很有帮助。
- 三种聚类算法:K均值、DBSCAN 和凝聚聚类,都可以控制聚类的粒度(granularity)。
- K均值可以用簇的平均值来表示簇。它还可以被看作一种分解方法,每个数据点都由其簇中心表示。
- DBSCAN 可以检测到没有分配任何簇的“噪声点”, 还可以帮助自动判断簇的数量。与其他两种方法不同,它允许簇具有复杂的形状。
- 凝聚聚类可以提供数据的可能划分的整个层次结构,可以通过树状图轻松查看。
分解、流形学习和聚类都是加深数据理解的重要工具,在没有监督信息的情况下,也是理解数据的仅有的方法。