目录
K均值
无监督学习的数据没有标签,希望计算机自行学习其中的知识。比如聚类模型会通过数据的内在性质,把数据划分为不同的关系紧密的子集。而K均值就是一个聚类模型。
聚类模型的用途:
- 市场分割
数据库中有各种客户的信息,希望将他们按照市场的不同进行划分,这样就能对不同的市场制定不同的销售策略或根据市场的不同进行服务改进。 - 社会网络分析
关注一些群体和他们的社交网和一些其他信息(如哪些人是你用邮件联系最频繁的人,而这些人用邮件联系最频繁的人又是谁),以此找到一个密切关联的群体。 - 组织计算机集群以及更好地组织数据集
在数据中心中,计算机集群经常协同工作,可以用K均值来重新组织资源,重新布局网络,优化数据中心以及通信数据。 - 了解银河系的构成
然后用这些构成信息来了解一些天文学的知识。
K均值算法
语言描述
假设我们有绿色的这些数据点,希望把这些数据点分为两个子集,应该怎么做?
- 随机生成两个点,这两点就叫聚类中心。生成两个点是因为想要分为两个聚类;
- 遍历数据,计算它们离两个聚类中心的距离,并把它们分配到距离最近的聚类中心。比如,图中红色的圆点离红色的聚类中心(红色的叉)比距离蓝色的聚类中心更近;
- 移动聚类中心。分别计算两种颜色的点的均值位置,并把新的聚类中心设置为计算出来的均值位置;
- 重复第二第三步,直到聚类中心不再移动,也就是说数据点的颜色不再改变;
如果在上述过程中出现一个没有点的聚类中心怎么办?最常见的做法是直接移除那个聚类中心。
但有时候的确需要K个聚类而不是K-1个聚类,那么就可以重新初始化这个聚类中心。
伪代码描述
算法的输入有两个:K(想要分几类)和训练数据,而且约定不使用x0=1。
ci代表xi离第i个聚类中心最近;
μk代表第k个聚类中心。
解决分离不佳的簇
有时候,我们遇到的数据并不都像左边的数据点那样各个聚类间有明显的分割,而是像右边的数据点一样看上去不容易分离。但是K均值算法依旧能够取得不错的结果。
K均值的损失函数
假设xi和第5个聚类中心最近,那么ci=5,μci=μ5。
K均值的优化目标:找到合适的ci和μk,使得xi和它被分到的聚类的中心(μci)的距离最近。
可以证明在K均值算法中,第一步把xi分到离它最近的聚类中心,其实就是调整ci使得损失函数最小化;
第二步中重新计算新的聚类中心,其实就是调整μk使得损失函数最小化。
K均值初始化
Q:如何初始化K均值?
A:随机选择K个训练数据点作为初始化的聚类中心。
Q:K均值在不同的初始值下会有不同的结果,也就是说可能会陷入局部最优。如何避免陷入局部最优?
A:解决这个问题的方法是进行多次初始化。
一般来说,可以进行50到1000次随机初始化,然后计算每次的损失J,选择损失最小的模型。
多次随机初始化在K比较小的时候比较有用,比如K在2到10左右时,但是,如果K很大,比如成百上千,那么多次随机初始化可能并不会有太大的改善。
如何选择K
并没有一个很好的方法选择K,比如下图中的数据,有的人会把它分成两个聚类,也有人会把它分成四个聚类。
肘部法则:画出损失函数J随K的改变而改变的图,选择从急速下降到平缓下降的点(比如左边图中的K=3),但是有时候得到的图是右边的样子,并没有一个明确的点可供选择,这时候肘部法则就没什么用了。
总而言之,肘部法则是一个值得尝试的方法,但是不能期望它能解决所有问题。
通过下游目标确定。有时候,人们运用K均值算法是有一个目标的,比如可以考虑:如果把T-shirt分为3个尺码,它会买得怎么样?把它分为5个尺码会得到更高的销售量吗?这样就得到了K的数值。
主成分分析
另一种无监督学习是降维,降维不仅能使数据占用更少的内存,还能加速算法。
用途1:去除冗余特征
假设现在有一个二维的数据,两个维度的数据都是代表物体的长度,其中一维用厘米表示,另一个维度用英寸表示。我们可以让它们合并成一个特征。
这个例子有点勉强,但是在实际应用中,如果有成百上千个特征,就不容易知道哪些特征是冗余的。
假设有三个工程小组,第一个工程小组给你200个特征,第二个工程小组给你300个特征,第三个工程小组给你500个特征,总共有1000个特征。这时候就容易产生冗余数据。
这是一个三维数据点投影到二维平面的例子。
用途2:可视化数据
假设我们有关于各个国家的数据,每个国家有50个特征,我们怎么样才能看出这些国家之间的关联呢?
我们不可能画出50维的数据,但是如果我们能够把这50维的数据降到2维,并且保留数据的主要特征,那么我们就可以在二维的平面把它们画出来了。当然,直接看这个二维的数据可能并不知道每个特征表示的是什么。
当你把它们都画出来后,有可能就能知道每一维大概代表什么。
直观来理解主成分分析
主成分分析想要找到一个低维空间,使得数据点和它们在低维空间上投影的距离最短。
所以算法会选择投影到红色的线上而不是粉红色的线。
主成分分析与线性回归的区别
主成分分析看起来和线性回归很像,但是它们实际上是不同的:
线性回归中有一个特殊的分量y,而主成分分析中,每一个分量都是平等的。
而且线性回归中,数据到预测的y的距离是垂直于x轴的;而主成分分析中数据到投影点的距离是垂直于低维平面的。
在进行主成分分析之前,要对数据进行特征缩放(房子的面积和房间的数量相差较大)和归一化处理。
主成分分析想求的数据有两个:低维空间的坐标轴和数据点投影到低维空间后的坐标。
假设我们要把数据从n维降到k维,首先要求数据X间的协方差矩阵,然后对这个协方差矩阵进行奇异值分解,分解后能得到三个矩阵U,S,V,然后把U的前k个列向量取出来,记为Ureduce。
Ureduce就是降维后的空间坐标轴,降维后的数据坐标Z=UreduceTX
如何从降维后的数据重现原数据?
X≈Xapprox=UreduceZ,可以看到重现的数据完全是在一条直线上的。
选择要降到几维(K)
分别计算投影误差平方的平均值和数据的方差的平均值,我们会选择一个使得下图中的式子成立的k。也就是说,希望降维后的数据依旧保持原数据99%以上的方差。
一个直接的想法就是,从小到大选择k,计算Ureduce,Z,Xapprox等,然后计算上面的等式是否成立,直到找到使等式成立的最小的k。
但是这个方法比较麻烦,有一个更简便的方法是计算下图右边的这个式子是否成立。比如说k=3时,计算奇异值分解得到的S的对角线上前3个元素的和比上对角线上所有元素的和,看看它是否大于等于99%,如果满足,k=3就是我们所要求的k。
降维用于加速算法
假设一个分类问题的输入X有10000维,我们可以把X拿出来,降维到1000维,然后用这个1000维的数据去进行训练。
注意,降维所需的矩阵Ureduce应该是在训练集里学到的,不应该使用验证集和测试集去学习Ureduce。当然,训练完的Ureduce验证集和测试集都是可以用的。
主成分分析的误用
主成分分析的一个误用是用于防止过拟合,这并不是正确的用法,并不是说这样做的结果不好,而是说主成分分析不会考虑y的取值,所以有可能丢失一些重要的信息。
一个正确防止过拟合的方法是使用正则化项,这种方法会考虑y的取值,而且效果也比较好。
另一个主成分分析的误用就是,人们在刚开始构造模型的时候就把主成分分析考虑进去,但是建议直接使用原数据进行训练。如果没有必要的理由(运行过慢或者占用内存过大等),就不应该使用主成分分析。
主成分分析应该被用在加速算法或可视化数据上。
编程
K均值
导包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sb
from skimage import io
from scipy.io import loadmat
找到离数据点最近的聚类中心
def find_closest_centroids(X, centroids):
# INPUT:数据X,初始聚类中心centroids
# OUTPUT:数据点应该被分到的类
m = X.shape[0]
k = centroids.shape[0]
idx = np