机器学习手册学习笔记--聚类

229 阅读5分钟

仅供自己复习回顾使用,若有侵权可删除

聚类可以说是工作中预处理也好,还是建模时最常用的模型了。

聚类算法的目标是找出这些观察值潜在的分类,如果做得好的话,我们能在没有目标向量的情况下预测观察值的分类。

使用 K-Means 聚类算法

  • 第一, K-Means 聚类假设所有的聚类是凸形的(比如,圆形或者球形)。

  • 第二,所有特征在同一度量范围内。在解决方案中,我们对特征进行了标准化,以满足这个条件。

  • 第三,分组之间是均衡的(即每个分组中观察值的数量大致相等)。

  • K值确定:我们希望可以基于一些条件来选择 k 值。例如,轮廓系数

from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
iris = datasets.load_iris()
features = iris.data
scaler = StandardScaler()
features_std = scaler.fit_transform(features)

# 创建 K-Means 对象
cluster = KMeans(n_clusters=3, random_state=0, n_jobs=-1)
# 训练模型
model = cluster.fit(features_std)
# 创建新观察值
new_observation = [[0.8, 0.8, 0.8, 0.8]]
# 预测观察值的分类
model.predict(new_observation)
# 查看分类的中心点
model.cluster_centers_

加速 K-Means 聚类

前者计算量最大的步骤只在观察值的一部分随机样本上而非所有的观察值上执行。这个方法可以在只损失一小部分质量的情况下显著缩短算法收敛的时间。MiniBatchKMeans 的用法和 KMeans 十分相似,最大的区别在于 batch_size 参数。batch_size 控制每个批次中随机选择的观察值的数量。批次中的观察值越多,在训练过程中需要花费的算力就越大。

from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import MiniBatchKMeans
iris = datasets.load_iris()
features = iris.data

# 标准化特征
scaler = StandardScaler()
features_std = scaler.fit_transform(features)
# 创建 K-Means 对象
cluster = MiniBatchKMeans(n_clusters=3, random_state=0, batch_size=100)
# 训练模型
model = cluster.fit(features_std)

使用 Meanshift 聚类算法

在不对分类的数量和形状做假设的情况下对观察值聚类

原理类比: 想象有一个有雾气弥漫的足球场(即一个二维的特征空间),上面站着 100 个人(即我们的观察值)。因为雾很大,人只能看到很近的地方。每分钟每个人向四周看一看,然后朝着可以看到最多人的方向移动一步。随着时间流逝,因为人们一次次地朝着越来越大的人群移动,球场上的人开始聚集成一个个小组,最终这些人就在球场上形成了聚类(cluster)。每个人的分类被指定为他们最终所在的聚类。

MeanShift 有两个重要的参数: 第一个是 bandwidth,它设定了一个观察值用以决定移动方向的区域(又叫作核)的半径。在我们的类比中, bandwidth就是一个人能在雾里能看到的距离。我们可以手动设定这个参数,但是默认情况下,MeanShift 会自动估计一个合理的 bandwidth 值(会显著增加计算开销)。 第二,有时候执行 Meanshift 算法时,在一个观察值的核中看不到任何其他观察值。这就相当于球场上有一个人看不到任何其他人。默认情况下, MeanShift 把所有的这些“孤儿”观察值分配给离它最近的观察值的核。如果你想丢弃这些孤值,可以设置 cluster_all=False,这样所有孤值的标签就被设定为 -1。

# 加载库
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import MeanShift
# 加载数据
iris = datasets.load_iris()
features = iris.data
# 标准化特征
scaler = StandardScaler()
features_std = scaler.fit_transform(features)
# 创建 MeanShift 对象
cluster = MeanShift(n_jobs=-1)
# 训练模型
model = cluster.fit(features_std)

使用 DBSCAN 聚类算法

要把观察值分组成高密度的聚类,原理其实有点不理解。

# 加载库
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import DBSCAN
# 加载数据
iris = datasets.load_iris()
features = iris.data
# 标准化特征
scaler = StandardScaler()
features_std = scaler.fit_transform(features)
# 创建 DBSCAN 对象
cluster = DBSCAN(n_jobs=-1)
'''
eps从一个观察值到另一个观察值的最远距离,超过这个距离将不再认为二者是邻居。
min_samples最小限度的邻居数量,如果一个观察值在其周围小于 eps 距离的范围内有超过这个数量的邻居,就被认为是核心观察值。
metric eps 所用的距离度量,比如 minkowski(闵可夫斯基距离)或者 euclidean(欧氏距离)。注意,如果使用闵可夫斯基距离,就可以用参数 p 设定闵可夫斯基距离中的幂次。
'''
# 训练模型
model = cluster.fit(features_std)
# 显示聚类的情况
model.labels_

使用层次合并聚类算法

'''

在 Agglomerative 聚类中,所有观察值一开始都是一个独立的聚类。接着,满足一定条件的聚类被合并。不断重复这个合并过程,让聚类不断增长,直到达到某个临界点。在 scikit-learn 中,AgglomerativeClustering使用 linkage参数来决定合并策略,使其可以最小化下面的值:

  1. 1.合并后的聚类的方差(ward)。
  2. 2.两个聚类之间观察值的平均距离(average)。
  3. 3.两个聚类之间观察值的最大距离(complete)。 还有两个参数也很有用。
    第一个是 affinity,它决定 linkage 使用何种距离度量(比如minkowski 或者 euclidean 等)。
    第二个是 n_clusters,它设定了聚类算法试图寻找的聚类的数量。也就是说,直到有 n_clusters 个聚类时,聚类的合并才结束。 '''
# 加载库
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import AgglomerativeClustering
# 加载数据
iris = datasets.load_iris()
features = iris.data
# 标准化特征
scaler = StandardScaler()
features_std = scaler.fit_transform(features)
# 创建一个 Agglomerative 聚类对象
cluster = AgglomerativeClustering(n_clusters=3)
# 训练模型
model = cluster.fit(features_std)