根据菜菜的课程进行整理,方便记忆理解
代码位置如下:
概述
无监督学习与聚类算法
有监督学习
- 算法:
- 决策树,随机森林,逻辑回归
- 数据格式:
- 模型在训练的时候,即需要特征矩阵X,也需要真实标签y
无监督学习
- 模型在训练的时候,即需要特征矩阵X,也需要真实标签y
- 算法
- PCA降维
- 聚类算法
- 数据格式
- 训练的时候只需要特征矩阵X,不需要标签
聚类算法又叫做“无监督分类”,其目的是将数据划分成有意义或有用的组(或簇)。这种划分可以基于我们的业务需求或建模需求来完成,也可以单纯地帮助我们探索数据的自然结构和分布。
- 在商业中,如果我们手头有大量的当前和潜在客户的信息,我们可以使用聚类将客户划分为若干组,以便进一步分析和开展营销活动,最有名的客户价值判断模型RFM,就常常和聚类分析共同使用。
- 聚类可以用于降维和矢量量化(vector quantization),可以将高维特征压缩到一列当中,常常用于图像,声音,视频等非结构化数据,可以大幅度压缩数据量。
| 聚类 | 分类 | |
|---|---|---|
| 核心 | 将数据分成多个组 探索每个组的数据是否有联系 | 从已经分组的数据中去学习 把新数据放到已经分好的组中去 |
| 学习类型 | 无监督,无需标签进行训练 | 有监督,需要标签进行训练 |
| 典型算法 | K-Means,DBSCAN,层次聚类,光谱聚类 | 决策树,贝叶斯,逻辑回归 |
| 算法输出 | 聚类结果是不确定的 不一定总是能够反映数据的真实分类 同样的聚类,根据不同的业务需求 可能是一个好结果,也可能是一个坏结果 | 分类结果是确定的 分类的优劣是客观的 不是根据业务或算法需求决定 |
sklearn中的聚类算法
聚类算法在sklearn中有两种表现形式
- 一种是类(和我们目前为止学过的分类算法以及数据预处理方法们都一样),需要实例化,训练并使用接口和属性来调用结果。
- 另一种是函数(function),只需要输入特征矩阵和超参数,即可返回聚类的结果和各种指标。
- 输入数据 需要注意的一件重要事情是,该模块中实现的算法可以采用不同类型的矩阵作为输入。 所有方法都接受形状
[n_samples,n_features]的标准特征矩阵,这些可以从sklearn.feature_extraction模块中的类中获得。对于亲和力传播,光谱聚类和DBSCAN,还可以输入形状[n_samples,n_samples]的相似性矩阵,我们可以使用sklearn.metrics.pairwise模块中的函数来获取相似性矩阵。
KMeans
KMeans是如何工作的
- 簇与质心
- KMeans算法将一组N个样本的特征矩阵X划分为K个无交集的簇,直观上来看是簇是一组一组聚集在一起的数据,在一个簇中的数据就认为是同一类。簇就是聚类的结果表现。
- 簇中所有数据的均值通常被称为这个簇的"质心"(centroids)。在一个二维平面中,一簇数据点的质心的横坐标就是这一簇数据点的横坐标的均值,质心的纵坐标就是这一簇数据点的纵坐标的均值。同理可推广至高维空间。
- 簇的个数K是一个超参数
- 核心任务
- 根据我们设定好的K,找出K个最优的质心,并将离这些质心最近的数据分别分配到这些质心代表的簇中去。
| 顺序 | 过程 |
|---|---|
| 1 | 随机抽取K个样本作为最初的质心 |
| 2 | 开始循环: |
| 2.1 | 将每个样本点分配到离他们最近的质心,生成K个簇 |
| 2.2 | 对于每个簇,计算所有被分到该簇的样本点的平均值作为新的质心 |
| 3 | 当质心的位置不再发生变化,迭代停止,聚类完成 |
那什么情况下,质心的位置会不再变化呢?当我们找到一个质心,在每次迭代中被分配到这个质心上的样本都是一致的,即每次新生成的簇都是一致的,所有的样本点都不会再从一个簇转移到另一个簇,质心就不会变化了。 这个过程在可以由下图来显示,我们规定,将数据分为4簇(K=4),其中白色X代表质心的位置:
簇内误差平方和的定义和解惑
被分在同一个簇中的数据是有相似性的,而不同簇中的数据是不同的,当聚类完毕之后,我们就要分别去研究每个簇中的样本都有什么样的性质,从而根据业务需求制定不同的商业或者科技策略。聚类算法也是同样的目的,我们追求簇内差异小,簇外差异大。而这个“差异“,由样本点到其所在簇的质心的距离来衡量。
对于一个簇来说,所有样本点到质心的距离之和越小,我们就认为这个簇中的样本越相似,簇内差异就越小。而距离的衡量方法有多种,令表示簇中的一个样本点, 表示该簇中的质心,n表示每个样本点中的特征数目,i表示组成点的每个特征,则该样本点到质心的距离可以由以下距离来度量:
如我们采用欧几里得距离,则一个簇中所有样本点到质心的距离的平方和为:
-
m为一个簇中样本的个数
-
j是每个样本的编号
-
这个公式被称为簇内平方和(cluster Sum of Square),又叫做Inertia。
-
一个数据集中的所有簇的簇内平方和相加,就得到了整体平方和(Total Cluster Sum of Square),又叫做total inertia。
- Total Inertia越小,代表着每个簇内样本越相似,聚类的效果就越好。因此KMeans追求的是,求解能够让Inertia最小化的质心。实际上,在质心不断变化不断迭代的过程中,总体平方和是越来越小的。我们可以使用数学来证明,当整体平方和最小的时候,质心就不再发生变化了。如此,K-Means的求解过程,就变成了一个最优化问题。
在KMeans中,我们在一个固定的簇数K下,最小化总体平方和来求解最佳质心,并基于质心的存在去进行聚类。两个过程十分相似,并且,整体距离平方和的最小值其实可以使用梯度下降来求解。因此,有许多博客和教材都这样写道:簇内平方和/整体平方和是KMeans的损失函数。
Kmeans有损失函数吗?
记得我们在逻辑回归中曾有这样的结论:损失函数本质是用来衡量模型的拟合效果的,只有有着
求解参数需求的算法,才会有损失函数。Kmeans不求解什么参数,它的模型本质也没有在拟合数据,而是在对数据进行一种探索。所以如果你去问大多数数据挖掘工程师,甚至是算法工程师,他们可能会告诉你说,K-Means不存在什么损失函数,Inertia更像是Kmeans的模型评估指标,而非损失函数。但我们类比过了Kmeans中的Inertia和逻辑回归中的损失函数的功能,我们发现它们确实非常相似。所以,从“求解模型中的某种信息,用于后续模型的使用“这样的功能来看,我们可以认为Inertia是Kmeans中的损失函数,虽然这种说法并不严谨。
对比来看,在决策树中,我们有衡量分类效果的指标准确度accuracy,准确度所对应的损失叫做泛化误差,但我们不能通过最小化泛化误差来求解某个模型中需要的信息,我们只是希望模型的效果上表现出来的泛化误差很小。因此决策树,KNN等算法,是绝对没有损失函数的。
Inertia是基于欧几里得距离的计算公式得来的。实际上,也可以使用其他距离,每个距离都有自己对应的Inertia。在过去的经验中,我们总结出不同距离所对应的质心选择方法和Inertia,在Kmeans中,只要使用了正确的质心和距离组合,无论使用什么样的距离,都可以达到不错的聚类效果:
| 距离度量 | 质心 | Inertia |
|---|---|---|
| 欧几里得距离 | 均值 | 最小化每个样本点到质心的欧式距离之和 |
| 曼哈顿距离 | 中位数 | 最小化每个样本点到质心的曼哈顿距离之和 |
| 余弦距离 | 均值 | 最小化每个样本点到质心的余弦距离之和 |
在sklearn当中,我们无法选择使用的距离,只能使用欧式距离
KMeans算法的时间复杂度
- 使用算法复杂度度量算法
- KMeans算法是一个计算成本很大的算法
- KMeans算法的平均复杂度是O(k * n * T) ,其中k是我们的超参数,所需要输入的簇数,n是整个数据集中的样本量,T是所需要的迭代次数(相对的,KNN的平均复杂度是O(n) )。在最坏的情况下,KMeans的复杂度可以写作,其中n是整个数据集中的样本量,p是特征总数。
- 在实践中,比起其他聚类算法,k-means算法已经快了,但它一般找到Inertia的局部最小值。 这就是为什么多次重启它会很有用。