机器学习(7) 您所在的位置:网站首页 简述层次聚类分析的基本思想 机器学习(7)

机器学习(7)

2023-02-27 21:31| 来源: 网络整理| 查看: 265

聚类算法

前面介绍的集中算法都是属于有监督机器学习方法,这章和前面不同,介绍无监督学习算法,也就是聚类算法。在无监督学习中,目标属性是不存在的,也就是所说的不存在“y”值,我们是根据内部存在的数据特征,划分不同的类别,使得类别内的数据比较相似。

我们对数据进行聚类的思想不同可以设计不同的聚类算法,本章主要谈论三种聚类思想以及该聚类思想下的三种聚类算法。666

本章主要涉及到的知识点有:

“距离”

K-Means算法

几种优化K-Means算法

密度聚类

算法思想:“物以类聚,人以群分”

本节首先通过聚类算法的基本思想,引出样本相似度这个概念,并且介绍几种基本的样本相识度方法。

算法思想

俗话说:“物以类聚,人以群分”,在自然科学和社会科学中,存在着大量的分类问题。所谓类,通俗地说,就是指相似元素的集合。例如,我们刚生下来父母就开始教我们分类,给我们买很多卡片,告诉我们:(一定要用现实中的例子说名,注重趣味性)

“这是汽车。”。 “这是飞机。” “这是鱼类。” “这是鸟类。” “这是圆。” “这是长方形。” “……。”

可见我们作为一个刚刚进入尘世的人,首先接触的就是分类了。然而到了今天,回顾我们的科学史,我们很多比较重要的就是发现一个新事物,然后给新事物分类。当然,我们眼里所熟悉的类别,都是根据常识,已经做好的分类。对于计算机来说,更具体一些,对于这里聚类算法;来说也是一样,只不过,通过算法把那些相识的数据划分在一起。这是我们本章主要解决的任务。 由上面可得我们本章的重点是将给定的数据划分为不同的数据类别,是类别之间的相识度最小。

如何将数据划分不同类别

通过计算样本之间的相识度,将相识度大的划分为一个类别。衡量样本之间的相识度的大小的方式有下面几种:

闵可夫斯基距离(Minkowski距离)也就是前面提到的范式距离 当p=1时为曼哈顿距离,公式如下(以二维空间为例): image.png 曼哈顿距离

当p=2时,为欧几里得距离,公式如下:

image.png

当p=为无穷大时候,为切比雪夫距离,公式如下:

image.png

一般情况下用欧几里得距离比较多,当数据量出现扁平化时候,一般用切夫雪比距离。

夹角余弦相识度

假设两个样本有2个特征, 则这两个样本的夹角余弦相似度公式如下:

image.png

最常见的应用就是计算文本相似度。将两个文本根据他们词,建立两个向量,计算这两个向量的余弦值,就可以知道两个文本在统计学方法中他们的相似度情况。实践证明,这是一个非常有效的方法。

杰卡德相似系数(Jaccard) 适用于样本只有(0,1)的情况,又叫二元相似性,计算公式如下: image.png

将杰卡德相似性度量应用到基于物品的协同过滤系统中,并建立起相应的评价分析方法。 与传统相似性度量方法相比,杰卡德方法完善了余弦相似性只考虑用户评分而忽略了其他信息量的弊端,特别适合于应用到稀疏度过高的数据。

类别的定义:簇

前面我们讲到把数据划分为不同类别,机器学习给这个类别定义一个新的名字—簇。 将具有M个样本的数据换分为k个簇,必然kT2) (2)从列表L中获取一个节点P,计算P到所有聚簇中心点的距离(如果不存在聚簇中心,那么此时点P形成一个新的聚簇),并选择出最小距离D(P,aj)。 (3)如果距离D小于T1,表示该节点属于该聚簇,添加到该聚簇列表中 (4)如果距离D小于T2,表示该节点不仅仅属于该聚簇,还表示和当前聚簇中心点非常近,所以将该聚簇的中心点设置为该簇中所有样本的中心点,并将P从列表L中删除。 (5)如果距离D大于T1,那么节点P形成一个新的聚簇。 (6)直到列表L中的元素数据不再有变化或者元素数量为0的时候,结束循环操作。 该步骤用流程图表示如下图所示:

Canopy算法流程图

Canopy算法得到的最终结果的值,聚簇之间是可能存在重叠的,但是不会存在某个对象不属于任何聚簇的情况。

可以看到canopy算法将可以将一堆杂乱的数据大致的划分为几块所以Canopy算法一般会和kmeans算法配合使用来到达使用者的目的在使用Canopy算法时,阈值t1,t2的确定是十分重要的。t1的值过大,会导致更多的数据会被重复迭代,形成过多的Canopy;值过小则导致相反的效果t2的值过大,会导致一个canopy中的数据太多,反之则过少这样的情况都会导致运行的结果不准确。该算法的过程图形说明如图所示:

Canopy算法图形说明 Mini batch k- Means算法

Mini Batch K-Means使用了一个种叫做Mini Batch(分批处理)的方法对数据点之间的距离进行计算。Mini Batch的好处是计算过程中不必使用所有的数据样本,而是从不同类别的样本中抽取一部分样本来代表各自类型进行计算。由于计算样本量少,所以会相应的减少运行时间,但另一方面抽样也必然会带来准确度的下降。这样使用于存在巨大的数据集合的情况下。 实际上,这种思路不仅应用于K-Means聚类,还广泛应用于梯度下降、深度网络等机器学习和深度学习算法。

该算法的算法流程和k- Means类似,流程如下:

(1)首先抽取部分数据集,使用K- Means算法构建出K个聚簇点的模型。 (2)继续抽取训练数据集中的部分数据集样本数据,并将其添加到模型中,分配给距离最近的聚簇中心点。 (3)更新聚簇的中心点值。 (4)循环迭代第二步和第三步操作,直到中心点稳定或者达到迭代次数,停止计算操作。 应用场景,由于Mini Batch KMeans跟K-Means是极其相似的两种聚类算法,因此应用场景基本一致。 后面我们就以 Mini batch k- Means算法为例子,比较一下它和 k- Means算法的区别。

8.1.1 聚类算法评估

有监督的分类算法的评价指标通常是accuracy, precision, recall, etc;由于聚类算法是无监督的学习算法,评价指标则没有那么简单了。因为聚类算法得到的类别实际上不能说明任何问题,除非这些类别的分布和样本的真实类别分布相似,或者聚类的结果满足某种假设,即同一类别中样本间的相似性高于不同类别间样本的相似性。

下面介绍几种常见的评估方法:

均一性又叫完整性 一个簇只包含一个类别样本,满足均一性,也可以认为正确率(每个簇中正确分类占该簇总样本的比),公式如下: image.png 兰德系数(RI)

兰德系数(Rand index)需要给定实际类别信息C,假设K是聚类结果,a表示在C与K中都是同类别的元素对数,b表示在C与K中都是不同类别的元素对数,则兰德指数为:

image.png

分子:属性一致的样本数,即同属于这一类或都不属于这一类。a是真实在同一类、预测也在同一类的样本数;b是真实在不同类、预测也在不同类的样本数; 分母:任意两个样本为一类有多少种组合,是数据集中可以组成的总元素对数; RI取值范围为[0,1],值越大意味着聚类结果与真实情况越吻合。 对于随机结果,RI并不能保证分数接近零。为了实现“在聚类结果随机产生的情况下,指标应该接近零”,调整兰德系数(Adjusted rand index)被提出,它具有更高的区分度:

image.png

ARI取值范围为[-1,1],值越大意味着聚类结果与真实情况越吻合。从广义的角度来讲,ARI衡量的是两个数据分布的吻合程度。

优点:

(1)对任意数量的聚类中心和样本数,随机聚类的ARI都非常接近于0; (2)取值在[-1,1]之间,负数代表结果不好,越接近于1越好; (3)可用于聚类算法之间的比较。

缺点: ARI需要真实标签

轮廓系数 Silhouette Coefficient

轮廓系数适用于实际类别信息未知的情况。

簇内不相似度:计算样本i倒同簇其它样本的平均距离为a;a越小,表示样本越应该被聚类到该簇,簇C中的所有样本的a的均值被称为簇C的簇不相似度。

簇间不相似度:计算样本i到其它簇C的所有样本的平均距离b;b=min{b;1,bi2,bi};b越大,表示样本越不属于其它簇。

轮廓系数:s值越接近1表示样本麇类越合理,越接近-1,表示样本j应该分类到另外的簇中,近似为0,表示样本应该在边界上;所有样本的s的均值被成为聚类结果的轮廓系数。伦敦系数可以写作:

image.png

Scikit-learn中有兰求德系数方法metrics.silhouette_score。

Python中实现的代码如下:

from sklearn import metrics from sklearn.metrics import pairwise_distances from sklearn import datasets dataset = datasets.load_iris() X = dataset.data y = dataset.target import numpy as np from sklearn.cluster import KMeans kmeans_model = KMeans(n_clusters=3, random_state=1).fit(X) labels = kmeans_model.labels_ metrics.silhouette_score(X, labels, metric='euclidean')

输出:

兰德系数为: 0.5730973570083832 示例:比较Mini batch k- Means算法和 k- Means算法

要求:给定较多数据,来比较两种算法的聚类速度,且用刚学到的聚类评估算法对,这两种算法进行评估。

两种的算法的API详情可以参考网址:

http://scikit-learn.org/0.19/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans。

#第一个参数表示给定中心点的个数,第二个参数给出初始质心怎么给,第三个参数是多套初始质心,第四个代表的是迭代次数 sklearn.cluster.KMeans(n_clusters=8, init=’k-means++’, n_init=10, max_iter=300) [](#sklearn.cluster.MiniBatchKMeans "Permalink to this definition") 1. 导入模块。 #导入我们要用的包,包括算法数据创建模块,算法评估模块,算法模块。 import time import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl from sklearn.cluster import MiniBatchKMeans, KMeans from sklearn.metrics.pairwise import pairwise_distances_argmin from sklearn.datasets.samples_generator import make_blobs 2. 创建数据 #创建呈现3个团状共3000个样本数据,样本有两个特征属性, #初始化三个中心 centers = [[1, 1], [-1, -1], [1, -1]] clusters = len(centers) #聚类的数目为3 #产生3000组二维的数据,中心是意思三个中心点,标准差是0.7 X, Y = make_blobs(n_samples=3000, centers=centers, cluster_std=0.7, random_state=0) 3. 模型构建 #构建kmeans算法 k_means = KMeans(init='k-means++', n_clusters=clusters, random_state=28) t0 = time.time() #当前时间 k_means.fit(X) #训练模型 km_batch = time.time() - t0 #使用kmeans训练数据的消耗时间 print ("K-Means算法模型训练消耗时间:%.4fs" % km_batch) #构建MiniBatchKMeans算法 batch_size = 100 mbk = MiniBatchKMeans(init='k-means++', n_clusters=clusters, batch_size=batch_size, random_state=28) t0 = time.time() mbk.fit(X) mbk_batch = time.time() - t0 print ("Mini Batch K-Means算法模型训练消耗时间:%.4fs" % mbk_batch) #输出的结果为: L- Means算法模型训练消耗时间:0.0416s M- Mini Batch K-Means算法模型训练消耗时间:0.0150s 4. 模型的预测 #预测结果 km_y_hat = k_means.predict(X) mbkm_y_hat = mbk.predict(X) print(km_y_hat[:10]) print(mbkm_y_hat[:10]) print(k_means.cluster_centers_) print(mbk.cluster_centers_) #输出的结果: [0 1 0 2 1 1 1 1 2 1] [[-1.07159013 -1.00648645] [ 0.96700708 1.01837274] [ 1.07705469 -1.06730994]] [[ 1.02538969 -1.08781328] [-1.06046903 -1.01509453] [ 0.97734743 1.08610316]] 5.求出质心得坐标并进行排序: ##获取聚类中心点并聚类中心点进行排序 k_means_cluster_centers = k_means.cluster_centers_#输出kmeans聚类中心点 mbk_means_cluster_centers = mbk.cluster_centers_#输出mbk聚类中心点 print ("K-Means算法聚类中心点:\ncenter=", k_means_cluster_centers) print ("Mini Batch K-Means算法聚类中心点:\ncenter=", mbk_means_cluster_centers) order = pairwise_distances_argmin(k_means_cluster_centers, mbk_means_cluster_centers) 得到的结果如下: K-Means算法聚类中心点: center= [[-1.07159013 -1.00648645] [ 0.96700708 1.01837274] [ 1.07705469 -1.06730994]] ### Mini Batch K-Means算法聚类中心点: center= [[ 1.02538969 -1.08781328] [-1.06046903 -1.01509453] [ 0.97734743 1.08610316]] 6. 画图,把原始数据和最终预测数据在图上表现出来 plt.figure(figsize=(12, 6), facecolor='w') plt.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.9) cm = mpl.colors.ListedColormap(['#FFC2CC', '#C2FFCC', '#CCC2FF']) cm2 = mpl.colors.ListedColormap(['#FF0000', '#00FF00', '#0000FF']) 7. 创建各个子图: #子图1:原始数据 plt.subplot(221) plt.scatter(X[:, 0], X[:, 1], c=Y, s=6, cmap=cm, edgecolors='none') plt.title(u'原始数据分布图') plt.grid(True) #子图2:K-Means算法聚类结果图 plt.subplot(222) plt.scatter(X[:,0], X[:,1], c=km_y_hat, s=6, cmap=cm,edgecolors='none') plt.scatter(k_means_cluster_centers[:,0], k_means_cluster_centers[:,1],c=range(clusters),s=60,cmap=cm2,edgecolors='none') plt.title(u'K-Means算法聚类结果图') plt.text(-3.8, 3, 'train time: %.2fms' % (km_batch*1000)) plt.grid(True) #子图三Mini Batch K-Means算法聚类结果图 plt.subplot(223) plt.scatter(X[:,0], X[:,1], c=mbkm_y_hat, s=6, cmap=cm,edgecolors='none') plt.scatter(mbk_means_cluster_centers[:,0], mbk_means_cluster_centers[:,1],c=range(clusters),s=60,cmap=cm2,edgecolors='none') plt.title(u'Mini Batch K-Means算法聚类结果图') plt.text(-3.8, 3, 'train time: %.2fms' % (mbk_batch*1000)) plt.grid(True) 8. 创建两则分不同的点子图: different = list(map(lambda x: (x!=0) & (x!=1) & (x!=2), mbkm_y_hat)) for k in range(clusters): different += ((km_y_hat == k) != (mbkm_y_hat == order[k])) identic = np.logical_not(different) different_nodes = len(list(filter(lambda x:x, different))) plt.subplot(224) # 两者预测相同的 plt.plot(X[identic, 0], X[identic, 1], 'w', markerfacecolor='#bbbbbb', marker='.') # 两者预测不相同的 plt.plot(X[different, 0], X[different, 1], 'w', markerfacecolor='m', marker='.') plt.title(u'Mini Batch K-Means和K-Means算法预测结果不同的点') plt.xticks(()) plt.yticks(()) plt.text(-3.8, 2, 'different nodes: %d' % (different_nodes)) plt.show() 输出结果如下: 两种算法的对比

分析:从上图,我们看出Mini batch k- Means算法比 k- Means算法速度快了不止一倍,而效果还是不错的。

思考:如果出现如图9.7所示出现的数据类型用类 k- Means算法就不能正确地对他们进行聚类了,因为他们属于非凸类数据。这时候就要转变聚类思想了,采用别的聚类方法了。

非凸数据集进行聚类 本章小结

本章主要介绍了聚类中的一种最常见的算法—K-Means算法以及其优化算法,聚类是一种无监督学习的方法。我们通过簇来把数据划分为不同的种类,介绍了该算法的构建流程,根据构建的流程中的初始值敏感问题,我们对最基本的K-Means算法进行了改进,其中Mini batch k- Means算法可以适用于数据量比较多的情况,且效果也不错。 本章的最后我们根据样本不同的特征,有时候不适合采用K-Means算法,我们将在下一章介绍几种其他思想产生的算法。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有