博主只是初学机器学习的新人一枚,这篇博客旨在分享一下吴恩达机器学习课程编程练习7的答案,同时也是相当于自己对这一章的内容做一个回顾,让自己理解的更加的透彻,理性讨论,不喜勿喷
本练习的主题是K-means Clustering and Principal Component Analysis,即K均值聚类算法和主要成分分析。因此这篇文章也分两部分来讨论,根据作业文件的步骤来分别对K均值聚类算法和PCA进行讨论原理以及如何实现。
-
K-means Clustering algorithm(K均值聚类算法)
首先需要说明的是,K均值聚类算法与我们前面学习的线性回归、逻辑回归、神经网络、SVM均是不同的,这四种算法所处理的数据都是有标签的,也就是label data,即对于数据X来说,一般会有对应的Y与之相匹配,而不管是线性回归或者是逻辑回归,其实质都是X、Y之间的关系去进行拟合、预测或者分类等操作,这种我们称之为监督学习算法,而K均值聚类算法是一种无监督学习算法,也就是说其处理的数据集是没有标签的(unlabel data),数据集是单纯的{X1,X2,X3 … Xn,Xn+1},而算法的目的就是根据这些点之间存在的某些联系来讲这些点进行分类。
由于数据没有标签,因此在进行分类时分类数目就需要我们自己来确定,如果是实际的应用问题,一般根据K值代表的意义来进行分类,而对于一般的数据,在后文将会介绍如何选取一个合适的K值。我们先来看下面一张图:
在这张图中,我们根据目视情况大致决定将数据分为三类,因此我们在这里随机选取了三个点作为我们的初始聚类点,并根据数据点和聚类点距离的不同将数据点标以不同的颜色,接下来我们来执行算法的第一步,计算每个数据点与聚类点的距离并将其分类(实质上图上显示的已经是分类结束了的情况):distance = zeros(K,1); [m,~] = size(X); try for i = 1:m for j = 1:K % compute the distance distance(j) = norm(X(i,:) - centroids(j,:)); end min_dis = min(min(distance)); min_idx = find(min_dis == distance); idx(i) = min_idx(1); end catch ErrorInfo disp(i); disp(distance); disp(min_idx); disp(idx(i));
其中,X是原数据集,centroids是我们初始化的聚类中心点,而idx则表示对应的X中的点距离几号聚类点最近,例如idx(i) = 1,则表示X中第i个点距离1号聚类点最近,而后面我们就可以根据这个标号来进行数据集的分类和下一步的计算。
注意:我这里使用的try…catch… 是因为我在调试的过程中发现了一个问题,也就是可能会出现一个数据集点正好处在两个或者两个以上聚类点的中心位置,这样它和这n个中心点的距离就是一样的,这时候如果我们按照一般的思维去对他进行分类就会出错,因此我这里对于这种情况直接将这个点划分到这些点中的第一个(并不知道这样处理是否正确,暂时留坑,如果后面碰到更好的解决办法再回来填坑)。
上面我们完成了根据点距离中心的距离关系对点进行分类的问题,下面我们就需要进行算法的第二部,根据上面的分类情况,来重新更新中心点的位置,也就是通过上面分类后的数据点,来重新算出每一类数据的中心点,公式和说明如下:
也就是说,根据上一步我们把整个数据集分成了K类,∑xi是对其中第i类的所有数据求和,随后除以这个类中包含的数据个数,求取这一类数据的中心点坐标作为新的中心点,然后根据新的中心点来重复上一步的数据分类,再更新中心点,再分类…实质上,K均值算法就是一个迭代的过程,知道找到最后的中心点,下面是更新中心点的代码实现和整个算法迭代到最后的结果:for i = 1:K centroids(i,:) = ones(size(find(i == idx),1),1)' * X(i == idx,:); centroids(i,:) = centroids(i,:) / size(find(i == idx),1); end
注:这里是迭代次数为10次的结果。现在,我们已经介绍了整个K均值聚类算法的实现过程,实质上,整个算法只有两步:1)点分类 2)点更新,通过对这两步的反复迭代就可以实现最后的目标。实际上,在执行这个算法时我们还应该注意到另外一个问题,也就是中心点随机初始化的问题,有些时候可能因为初始中心点选的不合适,最后会导致结果出现局部最优解而不是全局最优解,为了避免这种情况出现,我们对中心点的初始化执行随机初始化操作,同时可能对K均值聚类算法执行多次以求达到最优的结果。
-
Principal Component Analysis(PCA)主要成分分析
PCA实质上是一种数据分析方法,旨在通过降维的思想,将多维数据转换为低维度的数据。有时候我们要进行学习的数据可能很大,有很多变量,这样的数据固然包含了很多的信息,可以在最大程度上让我们的结果准确,但是需要注意到的是,越是复杂的数据在进行处理时也会越麻烦,但是盲目的舍弃一部分数据显然是不可取的,因为这可能会舍弃掉一部分关键的信息,这时候,就需要一种合适的方法去对这些数据进行分析并预处理,好简化我们下一步的操作,而PCA就是这样一种方法。本文主要讲述PCA的实现部分,关于更细节的原理讲解,可以参考一下博文(侵删):主成分分析(PCA):原理详解。
同K均值一样,PCA也是分为两步,下面我们来分别说明:
一:
计算协方差矩阵
首先计算协方差矩阵,公式如下:
要注意,在这里,∑代表的不是求和,而是一个nn的矩阵,X是一个mn维的数组,m是样本数。
二:
计算主要成分
计算了协方差矩阵后,我们可以直接计算主要成分,使用matlab自带的SVD函数可以完成这一步骤,公式如下:
其中,U中包含了主要成分,而U则是一个对角矩阵,在我们选择K时会用到S。
通过上面的两个步骤,我们已经得到了一个包含主要成分的矩阵,下面可以通过矩阵的变换来获得变换后的数据:U_reduce = U(:,1:K); Z = X * U_reduce;
例如这里,Z就是一个将X变换为K为的数据集,当然,可以降维,自然可以“升维”,也就是将数据还原:
U_reduce = U(:,1:K); X_rec = Z * U_reduce';
以上就是PCA的全部内容。
填坑
在文中,有三个地方没有交代清楚,第一个是K均值聚类算法中的K取值如何选取;第二个是这K个中心点在初始化时应该如何初始化;第三个地方是PCA中选取K(也就是降维后的数据维度)如何选取,下面分别来谈一下,其实都是吴老师课程中的内容。
一:中心点个数K如何选取?
在选取中心点个数时,除了我前面提到过的根据实际问题来分析,比如服装厂家对衣服的尺寸市场需求进行分析,他可能会将衣服的尺寸分为S,M,L,XL,XXL,这样,我们就可以取K=5,也就是将整个市场的数据分为五类,看哪一类的需求最大对应的来更改生产计划之类,除此之外,对于一般的数据来说,我们可以执行一个叫做Elbow method(肘部准则)的选取方法,主要是利用代价函数J来选取,如图所示:
简单来说,就是选取J斜率变化最大的那个转折点,目的就是用最小的K值来获得最好的令J减小的效果,但是注意,这种方法也不是常常能奏效,如下面这种情况:
这种情况下显然就不存在明显的肘部,因此在选取K值时我们应该灵活应用上面的方法来选取合适的K值。
二:
中心点如何初始化?
总的来说,中心点的初始化遵循一下三个准则一般能取得较好的效果:
1)K的个数应该小于m(样本数);
2)中心点的选取应该从样本中随机选取;
3)令中心点的坐标和样本数据重合。
三:
PCA中的K值如何选取?
PCA中的K值在选取时,应该遵循最大方差准则,一般来说,结果应该保留有99%的方差,用公式来表示,也就是
用实际的来表示就是:
1 - ∑ki=1Sii / ∑ni=1Sii <= 0.01
其中,Sii是前文提到的S矩阵中第i行、第i列上的元素。