|
|
|
|
移动端
创建专栏

一文简述多种无监督聚类算法的Python实现

本文简要介绍了多种无监督学习算法的 Python 实现,包括 K 均值聚类、层次聚类、t-SNE 聚类、DBSCAN 聚类。

作者:机器之心编译|2018-05-28 15:33

技术沙龙 | 邀您于8月25日与国美/AWS/转转三位专家共同探讨小程序电商实战

无监督学习是一类用于在数据中寻找模式的机器学习技术。无监督学习算法使用的输入数据都是没有标注过的,这意味着数据只给出了输入变量(自变量 X)而没有给出相应的输出变量(因变量)。在无监督学习中,算法本身将发掘数据中有趣的结构。

人工智能研究的领军人物 Yan Lecun,解释道:无监督学习能够自己进行学习,而不需要被显式地告知他们所做的一切是否正确。这是实现真正的人工智能的关键!

监督学习 VS 无监督学习

在监督学习中,系统试图从之前给出的示例中学习。(而在无监督学习中,系统试图从给定的示例中直接找到模式。)因此,如果数据集被标注过了,这就是一个监督学习问题;而如果数据没有被标注过,这就是一个无监督学习问题。

上图是一个监督学习的例子,它使用回归技术找到在各个特征之间的最佳拟合曲线。而在无监督学习中,根据特征对输入数据进行划分,并且根据数据所属的簇进行预测。

重要的术语

  • 特征:进行预测时使用的输入变量。
  • 预测值:给定一个输入示例时的模型输出。
  • 示例:数据集中的一行。一个示例包含一个或多个特征,可能还有一个标签。
  • 标签:特征对应的真实结果(与预测相对应)。

准备无监督学习所需的数据

在本文中,我们使用 Iris 数据集来完成初级的预测工作。这个数据集包含 150 条记录,每条记录由 5 个特征构成——花瓣长度、花瓣宽度、萼片长度、萼片宽度、花的类别。花的类别包含 Iris Setosa、Iris VIrginica 和 Iris Versicolor 三种。本文中向无监督算法提供了鸢尾花的四个特征,预测它属于哪个类别。

本文使用 Python 环境下的 sklearn 库来加载 Iris 数据集,并且使用 matplotlib 进行数据可视化。以下是用于探索数据集的代码片段:

  1. # Importing Modules 
  2. from sklearn import datasets 
  3. import matplotlib.pyplot as plt 
  4.  
  5. # Loading dataset 
  6. iris_df = datasets.load_iris() 
  7.  
  8. # Available methods on dataset 
  9. print(dir(iris_df)) 
  10.  
  11. # Features 
  12. print(iris_df.feature_names) 
  13.  
  14. # Targets 
  15. print(iris_df.target) 
  16.  
  17. # Target Names 
  18. print(iris_df.target_names) 
  19. label = {0: 'red', 1: 'blue', 2: 'green'} 
  20.  
  21. # Dataset Slicing 
  22. x_axis = iris_df.data[:, 0] # Sepal Length 
  23. y_axis = iris_df.data[:, 2] # Sepal Width 
  24.  
  25. # Plotting 
  26. plt.scatter(x_axis, y_axis, c=iris_df.target) 
  27. plt.show() 
  1. ['DESCR', 'data', 'feature_names', 'target', 'target_names'] 
  2. ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'] 
  3. [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2] 
  4. ['setosa' 'versicolor' 'virginica'] 

紫色:Setosa,绿色:Versicolor,黄色:Virginica

聚类分析

在聚类分析中,数据被划分为不同的几组。简而言之,这一步旨在将具有相似特征的群组从整体数据中分离出来,并将它们分配到簇(cluster)中。

可视化示例:

如上所示,左图是没有进行分类的原始数据,右图是进行聚类之后的数据(根据数据本身的特征将其分类)。当给出一个待预测的输入时,它会基于其特征查看自己从属于哪一个簇,并以此为根据进行预测。

K-均值聚类的 Python 实现

K 均值是一种迭代的聚类算法,它的目标是在每次迭代中找到局部最大值。该算法要求在最初选定聚类簇的个数。由于我们知道本问题涉及到 3 种花的类别,所以我们通过将参数「n_clusters」传递给 K 均值模型来编写算法,将数据分组到 3 个类别中。现在,我们随机地将三个数据点(输入)分到三个簇中。基于每个点之间的质心距离,下一个给定的输入数据点将被划分到独立的簇中。接着,我们将重新计算所有簇的质心。

每一个簇的质心是定义结果集的特征值的集合。研究质心的特征权重可用于定性地解释每个簇代表哪种类型的群组。

我们从 sklearn 库中导入 K 均值模型,拟合特征并进行预测。

K 均值算法的 Python 实现:

  1. # Importing Modules 
  2. from sklearn import datasets 
  3. from sklearn.cluster import KMeans 
  4.  
  5. # Loading dataset 
  6. iris_df = datasets.load_iris() 
  7.  
  8. # Declaring Model 
  9. model = KMeans(n_clusters=3
  10.  
  11. # Fitting Model 
  12. model.fit(iris_df.data) 
  13.  
  14. # Predicitng a single input 
  15. predicted_label = model.predict([[7.2, 3.5, 0.8, 1.6]]) 
  16.  
  17. # Prediction on the entire data 
  18. all_predictions = model.predict(iris_df.data) 
  19.  
  20. # Printing Predictions 
  21. print(predicted_label) 
  22. print(all_predictions) 
  1. [0] 
  2. [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 1 1 2 1 1 1 1 1 1 2 2 1 1 1 1 2 1 2 1 2 1 1 2 2 1 1 1 1 1 2 1 1 1 1 2 1 1 1 2 1 1 1 2 1 1 2] 

层次聚类

层次聚类,顾名思义,是一种能够构建有层次的簇的算法。在这个算法的起始阶段,每个数据点都是一个簇。接着,两个最接近的簇合二为一。最终,当所有的点都被合并到一个簇中时,算法停止。

层次聚类的实现可以用 dendrogram 进行展示。接下来,我们一起来看一个粮食数据的层次聚类示例。数据集链接:

https://raw.githubusercontent.com/vihar/unsupervised-learning-with-python/master/seeds-less-rows.csv

1. 层次聚类的 Python 实现:

  1. # Importing Modules 
  2. from scipy.cluster.hierarchy import linkage, dendrogram 
  3. import matplotlib.pyplot as plt 
  4. import pandas as pd 
  5.  
  6. # Reading the DataFrame 
  7. seeds_df = pd.read_csv( 
  8.  "https://raw.githubusercontent.com/vihar/unsupervised-learning-with-python/master/seeds-less-rows.csv") 
  9.  
  10. # Remove the grain species from the DataFrame, save for later 
  11. varieties = list(seeds_df.pop('grain_variety')) 
  12.  
  13. # Extract the measurements as a NumPy array 
  14. samples = seeds_df.values 
  15.  
  16. """ 
  17. Perform hierarchical clustering on samples using the 
  18. linkage() function with the method='complete' keyword argument. 
  19. Assign the result to mergings. 
  20. """ 
  21. mergings = linkage(samples, method='complete'
  22.  
  23. """ 
  24. Plot a dendrogram using the dendrogram() function on mergings, 
  25. specifying the keyword arguments labels=varietiesleaf_rotation=90
  26. and leaf_font_size=6
  27. """ 
  28. dendrogram(mergings, 
  29.  labels=varieties
  30.  leaf_rotation=90
  31.  leaf_font_size=6
  32.  ) 
  33.  
  34. plt.show() 

2. K 均值和层次聚类之间的差别

  • 层次聚类不能很好地处理大数据,而 K 均值聚类可以。原因在于 K 均值算法的时间复杂度是线性的,即 O(n);而层次聚类的时间复杂度是平方级的,即 O(n2)。
  • 在 K 均值聚类中,由于我们最初随机地选择簇,多次运行算法得到的结果可能会有较大差异。而层次聚类的结果是可以复现的。
  • 研究表明,当簇的形状为超球面(例如:二维空间中的圆、三维空间中的球)时,K 均值算法性能良好。
  • K 均值算法抗噪声数据的能力很差(对噪声数据鲁棒性较差),而层次聚类可直接使用噪声数据进行聚类分析。

t-SNE 聚类

这是一种可视化的无监督学习方法。t-SNE 指的是 t 分布随机邻居嵌入(t-distributed stochastic neighbor embedding)。它将高维空间映射到一个可视化的二维或三维空间中。具体而言,它将通过如下方式用二维或三维的数据点对高维空间的对象进行建模:以高概率用邻近的点对相似的对象进行建模,而用相距较远的点对不相似的对象进行建模。

用于 Iris 数据集的 t-SNE 聚类的 Python 实现:

  1. # Importing Modules 
  2. from sklearn import datasets 
  3. from sklearn.manifold import TSNE 
  4. import matplotlib.pyplot as plt 
  5.  
  6. # Loading dataset 
  7. iris_df = datasets.load_iris() 
  8.  
  9. # Defining Model 
  10. model = TSNE(learning_rate=100
  11.  
  12. # Fitting Model 
  13. transformed = model.fit_transform(iris_df.data) 
  14.  
  15. # Plotting 2d t-Sne 
  16. x_axis = transformed[:, 0] 
  17. y_axis = transformed[:, 1] 
  18.  
  19. plt.scatter(x_axis, y_axis, c=iris_df.target) 
  20. plt.show() 

紫色:Setosa,绿色:Versicolor,黄色:Virginica

在这里,具备 4 个特征(4 维)的 Iris 数据集被转化到二维空间,并且在二维图像中进行展示。类似地,t-SNE 模型可用于具备 n 个特征的数据集。

DBSCAN 聚类

DBSCAN(带噪声的基于密度的空间聚类方法)是一种流行的聚类算法,它被用来在预测分析中替代 K 均值算法。它并不要求输入簇的个数才能运行。但是,你需要对其他两个参数进行调优。

scikit-learn 的 DBSCAN 算法实现提供了缺省的「eps」和「min_samples」参数,但是在一般情况下,用户需要对他们进行调优。参数「eps」是两个数据点被认为在同一个近邻中的最大距离。参数「min_samples」是一个近邻中在同一个簇中的数据点的最小个数。

1. DBSCAN 聚类的 Python 实现:

  1. # Importing Modules 
  2. from sklearn.datasets import load_iris 
  3. import matplotlib.pyplot as plt 
  4. from sklearn.cluster import DBSCAN 
  5. from sklearn.decomposition import PCA 
  6.  
  7. # Load Dataset 
  8. iris = load_iris() 
  9.  
  10. # Declaring Model 
  11. dbscan = DBSCAN() 
  12.  
  13. # Fitting 
  14. dbscan.fit(iris.data) 
  15.  
  16. # Transoring Using PCA 
  17. pca = PCA(n_components=2).fit(iris.data) 
  18. pcapca_2d = pca.transform(iris.data) 
  19.  
  20. # Plot based on Class 
  21. for i in range(0, pca_2d.shape[0]): 
  22.  if dbscan.labels_[i] == 0: 
  23.  c1 = plt.scatter(pca_2d[i, 0], pca_2d[i, 1], c='r'marker='+'
  24.  elif dbscan.labels_[i] == 1: 
  25.  c2 = plt.scatter(pca_2d[i, 0], pca_2d[i, 1], c='g'marker='o'
  26.  elif dbscan.labels_[i] == -1: 
  27.  c3 = plt.scatter(pca_2d[i, 0], pca_2d[i, 1], c='b'marker='*'
  28.  
  29. plt.legend([c1, c2, c3], ['Cluster 1', 'Cluster 2', 'Noise']) 
  30. plt.title('DB 

2. 更多无监督学习技术:

  • 主成分分析(PCA)
  • 异常检测
  • 自编码器
  • 深度信念网络
  • 赫布型学习
  • 生成对抗网络(GAN)
  • 自组织映射

原文链接:

https://towardsdatascience.com/unsupervised-learning-with-python-173c51dc7f03

【本文是51CTO专栏机构“机器之心”的原创译文,微信公众号“机器之心( id: almosthuman2014)”】

戳这里,看该作者更多好文

【编辑推荐】

  1. 有这5小段代码在手,轻松实现数据可视化(Python+Matplotlib)
  2. 手把手教你9步完成Python加密货币的价格预测
  3. 用Python实现数据驱动的接口自动化测试
  4. 从原理到应用:简述Logistic回归算法
  5. 无需深度学习框架,如何从零开始用Python构建神经网络
【责任编辑:赵宁宁 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

热门职位+更多