标签:
七月算法4月机器学习算法班课程笔记——No.10
与回归与分类不同,聚类是无监督学习算法,无监督指的是只需要数据,不需要标记结果,试图探索和发现一些模式。比如对用户购买模式的分析、图像颜色分割等。聚类算法的提出比较早,是数据挖掘的一个重要模块,可以对大量数据分类并概括出每一类的特点。目前也有很多种聚类算法,包括划分法、层次法、基于密度的方法、基于网格的方法等。实际生产中,很少有只用聚类算法的系统,因为聚类效果的好坏不容易衡量,有时候会用做监督学习中稀疏特征的预处理。
接下来会重点介绍K-means聚类、层次聚类和混合高斯模型。
聚类算法的思想:给定N个训练样本(未标记的)
评定内容的选择:相似度评定对于聚类至关重要,选用的评定内容决定了相似度的偏向。看下面的两张图:
如果以轮廓和色调作为评定标准,那么这两张图很容易被分为一类,如果以眼睛鼻子来评定,就能区分开。所以在不同的场景下,应该选用不同的评定内容。例如:
- 图片检索: 图片内容相似度
- 图片分割: 图片像素(颜色)相似度
- 网页聚类: 文本内容相似度
- 社交网络聚类: (被)关注人群, 喜好, 喜好内容
- 电商用户聚类: 点击/加车/购买商品, 行为序列。比如按时间聚类,夜晚12点以后还在购物的多是学生党。
计算相似度距离:不管用什么样的评定内容,最终都会把样本表示成向量,那么向量的距离怎么表示呢?常用的距离计算公式有:
- 欧式距离
K-means是提出非常早, 使用非常频繁的聚类算法。之前面试的时候我以为面试官会问比较难的聚类算法,但是发现多是问k-means,不过不仅仅是描述算法,要知道k-means的优缺点、适用场合,会问一些细致的问题。现在理解为什么了,因为公司大多也不会用太复杂的算法,K-means算是聚类中用的最多的了。
输入:N个样本、拟定的聚类个数K
初始化:随机初始化K个D维的向量 或 选取K个不同的样本点作为初始聚类中心
迭代直至收敛:
1. 对于每个样本xn都指定其为离其最近的聚类中心的cluster
2. 重新计算聚类中心
迭代收敛怎么定义呢? 一是聚类中心不再有变化,二是每个样本到对应聚类中心的距离之和不再有很大变化。
下面演示聚类的过程。
初始化:比如以下样本点要聚成2类,先随机初始化两个中心点。
计算距离,分类:对原始数据中的每个样本点,分别计算到两个中心点的距离,样本点离哪个中心的距离近,就分到相应的类别中。如下图,得到两个类别的分隔线,其实这条线也可以是两个点的垂直平分线,因为垂直平分线的性质可知,垂直平分线上的点,到两个中心点的距离相同。
重新计算中心点:把蓝色点的位置的平均值作为蓝色的中心点,同理红色。
迭代:重新计算距离分类,重新计算中心点,知道达到了收敛条件。
K-means算法确实是对初始化聚类中心敏感的,比较好的初始中心不仅可以降低迭代次数,也会引导更好的聚类结果。上面提到,初始化中心是随机产生的,那么怎么优化初始化中心呢?
1. 初始第一个聚类中心为某个样本点, 初始第二个聚类中心为离它最远的点, 第三个为离它俩最远的。
2. 多初始化几遍, 选所有这些聚类中损失函数(到聚类中心和)最小的。其中损失函数的定义如下。假定
k-means的输入需要知道聚类个数,对于大量的数据,我们如何知道应该分为几类合理呢?而且k值选的不好确实会出现下面的状况,例如数据实际上划分为2类比较合理,如果硬性的划分为1类,或者3类,就没有很好的效果。
选择方法:“肘点” 法。选取不同的K值,画出损失函数曲线。
这里分析之后可以取k=2,因为2之后的损失函数变化不大。肘点法是教科书上经常介绍的方法,但是实际工作中,肘点法却不见得好用。
【实际案例】:有80w个商品的图片,希望实现聚类,每100个数据为一类。
直观思路:80w/100,约为8000个类,然后设置k=8000,把像素值展开跑实验,没有优化默认跑十遍,
实验数据要跑两三天。
优化思路:把商家的文本描述,比如颜色,长短等,先按文本聚200个类,然后并行的对这200各类按
照上述方式实验,三个小时可以完成。
聚类个数k怎么定呢?肘点法太耗时了。建议先定估计一个值,聚类后观察每个簇的元素个数,若有一些
簇元素很少,考虑降低k,如果比较平均,在考虑增加k。若某个簇元素个数很多,可以考虑单
独对这个簇再聚类。
嗯,这也是海量数据数理的常用方法——分治法。
下图表示了不同的K取值对图像分割的影响(聚类很多时候也是业务相关的)。
1. 属于“硬聚类” , 每个样本只能有一个类别。 其他的一些聚类方法(GMM或者模糊K-means允许“软聚类”)。
2. K-means对异常点的“免疫力” 很差, 我们可以通过一些调整,比如中心不直接取均值, 而是找均值最近的样本点代替——k-medoids算法。
3. 对于团状的数据点集区分度好, 对于带状(环绕)等“非凸”形状不太好。 (用谱聚类或者做特征映射)
K-means里面的K太难确定了,有的同学会有疑惑“无监督的聚类还需要指定k呀?有没有不需要指定k的聚类呢?“,下面来看看层次聚类。层次聚类是教科书上必讲的内容,比较容易理解,层次聚类就是通过对数据集按照某种方法进行层次分解,直到满足某种条件为止。按照分类原理的不同,可以分为凝聚和分裂两种方法。
凝聚型:比如有五个样本,先把每一个样本看做一簇,然后选择最近的两个样本归为一簇,得到4个簇,然后4个簇中选两个最近的簇作为一簇,直到所有的样本聚在一起就停止。可以想象整个过程会很慢。
算法中比较重要的是计算cluster R和cluster S之间的距离,介绍三种方法:
1. 最小连接距离法
高斯模型,给定均值和方差,将一个事物分解为基于高斯概率密度函数(正态分布曲线)形成的模型。
GMM的劣势:
1. 初始化要慎重, 不然可能掉到局部最优里去
2. 需要手工指定K(高斯分布)的个数
3. 对于我们提到的“非凸” 分布数据集, 也无能为力
一句话总结GMM:根据当前的参数指定概率分布,根据概率分布重新估计参数。
演示了python做文本聚类的例子,主要包括以下内容:
1. 句子的分词和stemming
2. 得到的次做tf-idf编码到向量空间
3. 用余弦举例或欧式距离计算两个文本之间的举例
4. k-means聚类
5. 用multidimensional scaling对结果数据降维(数据可视化)
6. 画出聚类的结果
7. 做层次聚类
8. 画出层次聚类的结果
用到的类库包括:np、pd、BeautifulSoup、feature_extraction等。
NLTK可以做自然语言处理的工作,去掉英语中”a”,”the”等停用词。
stemming:把意义相同的词关联到一起,比如”study”,”studying”等。
……
下面是k-means聚类和层次聚类得到的结果:
完整的代码和数据集在QQ群共享。
标签:
原文地址:http://blog.csdn.net/joycewyj/article/details/51732708