您的位置:首页 > 其它

Stanford ex7: K-means Clustering and Principal Component Analysis

2016-04-10 19:57 369 查看
代码资源地址:http://download.csdn.net/detail/lijunweiyhn/9491877

第七次实验主要做的是K-means聚类算法和PCA的实验。在这次实验中,第一部分是K-means部分,主要是熟悉K-means算法并用它对图像进行压缩;另外一部分是PCA的实验,将利用这个技术找到一个脸部照片的在较低维度的映射,或则说是代表。

%%=====================正文第一部分=======================%%

%%=====================K-means算法及其应用=======================%%

Part 1: Find Closest Centroids

这一小部分,是找到最近中心点。

首先设定中心点个数为3,然后设定了几个初始的中心点。

看样子是人工随机设置的:initial_centroids = [3 3; 6 2; 8 5];

之后用函数findClosestCentroids第一次寻找X里面的样本点属于哪一类。

在函数findClosestCentroids里,说一下pdist2这个函数,这里的用法是一次抽一个样本点(一行两列),而初始化的中心矩阵centroids是一个3行2列的矩阵,一行代表一个中心点。pdist2是计算这个样本点到每个中心点的欧式距离,并保存。之后C是所有距离中最小的那个距离,而idx是一个300行1列的记录数组,例如第一次idx(1)=1。表示第一个点属于第一类,即离第一个中心点最近。

Part 2: Compute Means

在完成了这个第一遍聚类后,现在,每个点都有了归属,那么,现在就要重新计算这个中心点的位置。

方法是:

for i=1:K

centroids(i,:) = mean( X( find(idx==i) , :) ); % 举个列子,当k=1时,把所有第一类的x找出来,对x坐标 end
%和y坐标%分别相加求平均,分别相加求平均

Part 3: K-Means Clustering

之前的两个函数分别计算了中心和对每个样本进行了最近距离计算和分类。现在,可以拿这两个函数来演示无监督的K-means聚类算法了。同样的设定三个类别(K=3),之前演示的时候只进行了一次迭代,现在设定迭代次数为10。依然初始化中心点,还是那3个。

接下来就是运行runkMeans函数了,代码不难看懂,想说的是画图时候的几行代码:

palette = hsv(K + 1); %生成一个饱和度是4*3的矩阵

colors = palette(idx, :);

idx是原样本数的一个vector,举个例子,假设他是

1.0000 0 0

0.5000 1.0000 0

0 1.0000 1.0000

0.5000 0 1.0000

palette(idx, :); 执行后是什么效果呢,假设idx=[1;1;2;2],那么colors计算出来就是

1.0000 0 0

1.0000 0 0

0.5000 1.0000 0

0.5000 1.0000 0

简单理解,就是生成K种颜色,然后对应类别画同一种颜色。

% Plot the data

scatter(X(:,1), X(:,2), 15, colors); 很明显的,X的size和colors的size在row上相同,对应画出颜色的点。大小15

Part 4: K-Means Clustering on Pixels

这一部分给出了一个K-means的应用例子——对图片进行压缩。把24位色彩的图像压缩成16位色彩的图像,首先是读入图片(一张128*128大小的图片)。这里需要注意的是,matlab读入图片后,是一个三维的数据,第三维代表的是RGB中R,G,B的色彩强度值,而前两维度代表是对应色彩下坐标点的强度值大小。

X = reshape(A, img_size(1) * img_size(2), 3);

这个代码的意思是,把A矩阵打散按要求布局形成X。这个规则就 是将整张图片的像素点,按先行后列for循环展开成3列,故第一列有128*128个数据,对应R强度值,后两列分别代表G强度值跟B强度值。

应实验要求,要将上千种颜色压缩为16种颜色,很显然K=16,并且我们人工设置迭代次数为10。之后初始化16个中心点,运用函数为kMeansInitCentroids,下面简单介绍kMeansInitCentroids里面两行代码:

randidx = randperm(size(X, 1)); %把展开成16384维的X数据随机打乱次序

centroids = X(randidx(1:K), :); %然后只取前16个作为初始中心点

接下来运行的就是之前的runkMeans函数,执行完成后,返回最后的中心点以及每个点所属于的类(K=16)。

[centroids, idx] = runkMeans(X, initial_centroids, max_iters);% X和initial_centroids都是16384*3

回顾时候经常会疑惑,initial_centroids和X都是128*128行,3列的数据,为什么计算出来idx是一列呢?因为findClosestCentroids调用的pdist2函数是把每一个样本与中心点做欧式距离计算,说白了,就是每一维都计算。所以计算出来后不管你有多少维度,与哪个初始化点距离最小,就属于它那一类。

Part 5: Image Compression

图像的压缩部分,16个中心类即是16种色彩。

X_recovered = centroids(idx,:); 按照idx里面对每个点分好的类进行颜色归纳,之后用

X_recovered = reshape(X_recovered, img_size(1), img_size(2), 3)重新形成分类后的矩阵。

用imagesc显示即可。这里的X_recovered 色彩数据是分布在0-1之间的,并没有去归一化。

到这里, K-Means及其应用就告一段落了,接下来是PCA实验部分。

%%=====================正文第二部分=======================%%

%%=====================PCA及其应用=======================%%

Part 1: Load Example Dataset

顾名思义,载入数据,并且把坐标轴的范围重设,并显示数据。

Part 2: Principal Component Analysis

先对X这个小的数据集进行标准化处理,处理的方法是,对每一列,求他们的均值和标准差,把每个数据减去均值再除以标准差。这样一来,对每一列来说,均值为0,标准差为1,我们称这个过程为Normalize,也就是数据的标准化。

PCA由两部分的计算组成,首先,是计算数据的协方差矩阵。然后,用Octave或则matlab的svd函数来计算特征向量U1,U2...Un,并且这些特征向量是随着数据变动而变化的。

用matlab的函数svd直接计算特征向量U和对角矩阵S。这一部分画出的线代表数据最大变化的方向。在进行PCA函数前,数据经过了标准化处理,我们用matlab的svd函数求的是Sigma = 1/m * X'* X 这个协方差矩阵的svd。求出来后U是特征向量矩阵,S是对应的对角阵,对角线上每一个数值就是对应特征向量的特征值,并且从大大小排序过。

之后画线操作:

drawLine(mu, mu + 1.5 * S(1,1) * U(:,1)', '-k', 'LineWidth', 2);

drawLine(mu, mu + 1.5 * S(2,2) * U(:,2)', '-k', 'LineWidth', 2);

这个我也没看懂,大概线段的意思是数据最大变化的方向。

Part 3: Dimension Reduction

这一部分做的是降维,将要把数据投影到最先的K个特征向量上。

首先还是把数据画出来,虽然经过了标准化处理让均值跟方差分别为0跟1,但是整个数据集的形状并没有改变。做数据的投影Z = projectData(X_norm, U, K);。 这里K=1,表示投影到1维上面;而U是用svd函数计算出来的特征向量;X_norm是经过标准化处理的数据,50个样本,2维。何为投影。我把经过标准化的X与前K列的特征向量矩阵相乘即是投影,50*2 与 前一列的 2*1的特征向量相乘,得50*1的投影结果。

projectData:

在实验中,X经过处理还是50*2的数据,而前K=1列的U特征向量Size为2*1,相乘后得到Z,Size为50*1。现在理一理,X是什么是清楚的,U是什么?U是特征向量矩阵,Size为2*2,谁的特征向量矩阵,原dataset X经过标准化处理后得到的X_norm的协方差矩阵的特征向量矩阵。有点绕,不过就是这样。

其实这里可以简单的理解为,我求个协方差矩阵的特征向量矩阵,然后按照排序好的特征值对特征向量矩阵进行列重排,完了之后用原标准化之后数据矩阵和该矩阵相乘,就达到了降维的目的。

recoverData:

X_rec是需要重建的数据,Size为50*2。U_reduce是U矩阵的第一列,Size为2*1,Z是降维后的数据,为50*1。故X_rec = Z * U_reduce'; Size为50*2。求的X_rec是原数据经过标准化后的approximation。

Part 4: Loading and Visualizing Face Data

载入数据,画出脸部。跟神经网络画出数字那部分相似,区别在于,这里只取前面100张,而且是固定前100。所用函数一样。5000个样本,每个样本1024维,也就是说照片是32*32规格的。

Part 5: PCA on Face Data: Eigenfaces

把一张照片做PCA降维处理。先对数据集做标准化处理,然后对数据集做pca。得到U是特征矩阵,S是对应的特征值对角矩阵。原数据是5000*1024,那么协方差矩阵就是1024*1024, 经过svd后,U为1024*1024。取前36个向量,每一列代表一个特征脸,做转置后用displayData显示。

Part 6: Dimension Reduction for Faces

把计算得到的特征向量矩阵取前100,做降维和重建数据矩阵,并对比显示。其实,原数据,经过标准化后的原数据,还有重形成的数据,都是不一样的,可以都列出来观察效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: