前言
聚类是一种无监督学习问题。
它经常用来在输入数据的特征空间中寻找分组,例如基于顾客行为将消费者分组。
聚类算法有很多种,没有哪一种聚类算法适用于所有的问题。不过,有必要去探究多种聚类算法,以及每种算法的不同配置,这样在遇到问题时才能做出合适的选择。
在本文中,你将会了解如何选择合适的聚类算法,并且使用python和scikit-learn去实现它们。
目录
全文分为三大部分:
- 聚类问题
- 聚类算法
- 聚类算法的实例
3.1 安装相应的包
3.2 聚类数据集
3.3 近邻传播
3.4 凝聚聚类
3.5 BIRCH聚类
3.6 DBSCAN聚类
3.7 K-Means聚类
3.8 Mini-Batch K-Means聚类
3.9 Mean Shift聚类
3.10 OPTICS聚类
3.11 谱聚类
3.12 高斯混合模型
一 、聚类问题
聚类是无监督学习,可以自动发现数据中的自然分组。不像监督学习(预测模型等),聚类算法只解释输入数据,并且在特征空间中发现自然分组或者簇。
一个簇通常是特征空间中的一个集中密度区域,该范围(数据行)里的样本更加接近本簇,而不是其他簇。簇会有一个中心(质心),该中心可能是一个样本或者特征空间点,簇还会有一个边界或者范围。
聚类作为一种数据分析技术来帮助了解更多关于问题域的信息,即所谓的模式发现或知识发现。
举几个例子:
- 系统进化树可以认为是人工聚类分析的结果;
- 将正常数据与异常值分隔开是一种聚类问题;
- 根据自然行为将集群进行分组,称为市场细分;
聚类还能作为一种特征工程,样本被标记上簇标签,作为新的一组特征。
对已经识别的簇判定其准确性是非常主观的,尽管有很多量化的判定规则,但可能仍需要该领域的专家来确认。
聚类算法
聚类算法有很多种。
很多算法使用相似度或者距离测量在特征空间中的例子用来发现观测到的区域的粘稠度。同样的,在规整数据之前使用聚类算法是一种很好的做法。
"
中心对所有的聚类分析来说是一种在被聚类的个体之间相似度或者不相似度程度的概念。一个聚类的方法能够将对象根据相似度的概念分组。
"
--- Page 502, The Elements of Statistical Learning: Data Mining, Inference, and Prediction, 2016.
一些聚类算法需要你去指定或者猜测这个簇的数量在数据中,然而其他的需要指定在案例中可能会被考虑为"closed" 或者"connected"观察点之间的最小距离。"
因此,聚类分析是一种迭代的过程,在这个过程中确定簇的主观评价反馈到算法参数方面的改变直到一个需要的或者合适的结果被得到。
scikit-learn库提供了很多不同的聚类方法去选择。
10种最流行的算法如下列所示:
近邻传播
凝聚聚类
BIRCH聚类
DBSCAN聚类
K-Means聚类
Mini-Batch K-Means聚类
Mean Shift聚类
OPTICS聚类
谱聚类
高斯混合模型
每个算法提供了不同的方式去发现来自不同组自然数据的挑战。
没有最好的聚类算法,在不使用受控的实验条件下也不太容易发现最好的聚类算法。
再这个教程中,我们会回顾使用10种种来自于scikit-learn库最流行的算法。
实例将会提供使用这些例子并且再你自己的数据上进行使用这些方法进行测试。
我们不会探讨算法工作背后的理论,或者直接比较他们。对于这个话题比较好的起点,请看:
Clustering, scikit-learn API.
开始吧。
聚类散算法的实例
在这个章节中,我们将会回顾怎么使用在scikit-learn中10种流行的聚类算法。
这些包括一个适合这个模型的例子,和一个可视化结果的例子。
这些例子被设计成让你熟悉你自己的项目并且在你自己的数据上能够使用这些方法。
建立库
第一步,让我们来建立库。
不要跳过这一步,你需要确保你安装了最新的版本。
你可以通过pip建scikit-learn 库,如下
pip install scikit-learn
对于对你自己平台的额外的建立命令,可以从:
Installing scikit-learn找到答案
下一步,确定这个库被建立并且确定你正在使用的版本。
运行下列的脚本打印库的版本号。
import sklearn
print(sklearn.version)
运行这个脚本,你将会看到下列的版本号或者更高。
0.22.2
集簇数据集
我们将使用 make_classification() function来去创建一个二进制分类数据集。
这个数据集有10000个例子,有两个输入的特征,每个类有一个簇。簇在二维是很明显的可视的,所以我们能画出这个数据,并且通过特定的簇描绘出这些点。这些会。
在这个测试问题中的簇是基于多元高斯,而不是所有的聚类算法能够有效的识别这些簇。因此,在这个教程中的各个方法的结果不应该被用来比较这些方法。
下面是一个例子用来创建和总结集簇数据集
synthetic classification dataset
from numpy import where
from sklearn.datasets import make_classification
from matplotlib import pyplot
define dataset
X, y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, n_clusters_per_class=1, random_state=4)
create scatter plot for samples from each class
for class_value in range(2):
get row indexes for samples with this class
row_ix = where(y == class_value)
create scatter of these samples
pyplot.scatter(X[row_ix, 0], X[row_ix, 1])
show the plot
pyplot.show()
运行这个示例代码创造一个合成数据集,然后创造一个输入数据的散点图并且根据颜色分类。
我们可以清除的看到两个明显的不同组的数据在不同的方向,希望构成一个自动聚类算法可以检测出这些分组。
下一步,我们将开始关注于应用于这个数据集的聚类算法。
我做了最小的调整使这个方法实用这个数据集。
你能在其中一个算法中得到一个最好的结果吗?
让我在下面的评论区知道。
邻近算法
邻近算法内容为找到一系列最好的标本能够总结总的数据。
"
我们设计了一个方法称为"亲和传播",采用一种在数种成对相似性措施。实值信息是在数据点之间交换直到高质量的标本和相应的簇逐渐出现。
"
--- Clustering by Passing Messages Between Data Points, 2007.
这个技术在下列文章中被展现:
Clustering by Passing Messages Between Data Points, 2007.
它是通过相似传播类实现的,主要的参数减弱0.5至1,可能最好调整0.5至1.
完整的脚本在下面列出来。
affinity propagation clustering
from numpy import unique
from numpy import where
from sklearn.datasets import make_classification
from sklearn.cluster import AffinityPropagation
from matplotlib import pyplot
define dataset
X, _ = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, n_clusters_per_class=1, random_state=4)
define the model
model = AffinityPropagation(damping=0.9)
fit the model
model.fit(X)
assign a cluster to each example
yhat = model.predict(X)
retrieve unique clusters
clusters = unique(yhat)
create scatter plot for samples from each cluster
for cluster in clusters:
get row indexes for samples with this cluster
row_ix = where(yhat == cluster)
create scatter of these samples
pyplot.scatter(X[row_ix, 0], X[row_ix, 1])
show the plot
pyplot.show()
运行例子适合该模型的训练数据集和预测一个集群中的每个示例数据集。然后创建一个散点图与集群点颜色的分配。
在这个案例中,我不能得到一个好的结果。
凝聚聚类
凝聚聚类包括联合样本直到所需要的簇被得到。
这是一个更广泛的层次聚类的方法的一部分,你可以在这里了解更多:
Hierarchical clustering, Wikipedia
它通过凝聚聚类类实现并且主要的参数配置是"n_clusters",簇的数量的估计在data,e.g.2。
运行脚本适合该模型的训练数据集和预测一个集群中的每个示例数据集。然后创建一个散点图与集群点颜色的分配。
在这种情况下,找到一个合理的分组。
BIRCH聚类算法
BIRCH聚类算法(BIRCH是利用层次方法的平衡迭代规约和聚类)包括从簇中提取的树结构。
"
BIRCH持续增加簇,这些簇进入多重度量数据来在可用的资源(可用的内存以及时间约束)下生成最好的质量簇。
"
--- BIRCH: An efficient data clustering method for large databases, 1996.
这个技术在下列文章中被展现:
BIRCH: An efficient data clustering method for large databases, 1996.
这个方法是通过Birch类去实现的并且主要的参数调优是"threshold" 和 "n_clusters" 超参数,后者参数提供了估计集群的数量。
完整的脚本在下列被展现。
运行脚本适合该模型的训练数据集和预测一个集群中的每个示例数据集。然后创建一个散点图与集群点颜色的分配。
在这个案例中,一个极好的分组被发现。
DBSCAN聚类
DBSCAN聚类(DBSCAN聚类是具有噪声的基于密度的聚类方法)包括发现高密度区域以及扩大这些地区周围的特征空间作为簇。
"
我们提出新的聚类算法DBSCAN依赖于基于密度的簇的概念,DBSCAN被设计去发现不同形状的簇。DBSCAN只需要一个输入参数,支持用户确定一个适当的值。
"
--- A Density-Based Algorithm for Discovering Clusters in Large Spatial Databases with Noise, 1996.
这个技术在下列文章中被展现:
A Density-Based Algorithm for Discovering Clusters in Large Spatial Databases with Noise, 1996.
这是通过DBSCAN类实现的,主要的参数配置是"eps"和"min_samples"参数。
完整的示例脚本如下:
dbscan clustering
from numpy import unique
from numpy import where
from sklearn.datasets import make_classification
from sklearn.cluster import DBSCAN
from matplotlib import pyplot
define dataset
X, _ = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, n_clusters_per_class=1, random_state=4)
define the model
model = DBSCAN(eps=0.30, min_samples=9)
fit model and predict clusters
yhat = model.fit_predict(X)
retrieve unique clusters
clusters = unique(yhat)
create scatter plot for samples from each cluster
for cluster in clusters:
get row indexes for samples with this cluster
row_ix = where(yhat == cluster)
create scatter of these samples
pyplot.scatter(X[row_ix, 0], X[row_ix, 1])
show the plot
pyplot.show()
运行脚本适合该模型的训练数据集和预测一个集群中的每个示例数据集。然后创建一个散点图与集群点颜色的分配。
在这个案例中,一个可能的分组被发现,尽管更多的参数还需要调整。
K-Means聚类
K-means聚类可能是最广为人知的聚类算法,涉及到把样本分为簇以及减少在每个簇中的方差
"
本文主要目的是描述一个过程,这个过程是分割N维总体在k集样本的基础上。这个过程被称为"K-means",似乎是在各类之间的方差上进行分组
"
--- Some methods for classification and analysis of multivariate observations, 1967.
技术在下列文章中被展现:
k-means clustering, Wikipedia
主要是通过KMeans类以及主要的参数调整为"n_clusters"参数估计数据中簇的数量。
完整的脚本如下:
k-means clustering
from numpy import unique
from numpy import where
from sklearn.datasets import make_classification
from sklearn.cluster import KMeans
from matplotlib import pyplot
define dataset
X, _ = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, n_clusters_per_class=1, random_state=4)
define the model
model = KMeans(n_clusters=2)
fit the model
model.fit(X)
assign a cluster to each example
yhat = model.predict(X)
retrieve unique clusters
clusters = unique(yhat)
create scatter plot for samples from each cluster
for cluster in clusters:
get row indexes for samples with this cluster
row_ix = where(yhat == cluster)
create scatter of these samples
pyplot.scatter(X[row_ix, 0], X[row_ix, 1])
show the plot
pyplot.show()
运行脚本适合该模型的训练数据集和预测一个集群中的每个示例数据集。然后创建一个散点图与集群点颜色的分配。
在这个案例中,一个合理的分组被找见,尽管不等同的等方差在每个维度让这个方法不适合这个数据集。