目录
Clustering
K-Means Algorithm
Optimization Objective
Random Initialization
Choosing the Number of Clusters
Motivation
Motivation I&II:Data Compression
Principal Component Analysis
Principal Component Analysis Problem Formulation
Principal Component Analysis Algorithm
Applying PCA
Reconstruction from Compressed Representation
Choosing the Number of Principal Components
Advice for Applying PCA
ex-7
实验结果I:K-means聚类图像的颜色
Part 3: K-Means Clustering
Part 4: K-Means Clustering on Pixels
Part 5: Image Compression(选做:换成自己的图片试试)
编辑
实验结果II:PCA压缩人脸图片
Part 3: Dimension Reduction
Part 5: PCA on Face Data: Eigenfaces
Part 7: Visualization of Faces after PCA Dimension Reduction
Part 8: Optional (ungraded) Exercise: PCA for Visualization
代码阅读I
ex7
runkMeans
kMeansInitCentroids
代码阅读II
ex7_pca
其他总结
pdf tips
一些疑惑和想法
聚类是非监督式学习的一种问题,非监督式学习的特点是是给出数据但无标签,通俗来说就是有x值无y。
k-means算法是最常使用的聚类算法,它工作的通常流程如下:
0. K-means是一种迭代式算法,主要做两个工作 cluster assignment step(簇分配)和move centroid step(质心移动)。
1. cluster assignment:初始化cluster centroid(簇质心),想要把数据集划分为几类就初始化几个cluster centroid。然后遍历所有samples,根据它们距离cluster centroid的远近,划分到不同的质心。
2. move centroid:将1中得到的所有分类计算其坐标的平均值,并把该类的质心移动到这个新的平均值坐标。
重复步骤1和2,直到cluster assignment的坐标不再发生明显变化。
ps:如果一个cluster centroid没有任何x被归类到它,最通常的做法是去除该cluster centroid使得变成K-1 Means算法,或者为了保持K类,也可以随机初始这个簇质心。
符号规定如下:
第一步是调整不同xi对应的ci,通过这种方式来减少J
第二步是调整mu的位置,来minimize J
通常的做法是任意选择samples里面的K个,以及,多次随机初始化cluster centroid有助于避免local optima,在K值较小的时候(如小于等于10)比较有效,K值大的时候可能初次计算就得到Best了。
选一个合适的K,通常手工选,没有特别好的自动化算法。
Elbow Method:形似手肘的拐点,通过从小到大尝试不同的K来找到,但是有可能拐点不存在。总的来说值得一试,但是不是对所有的问题都适合。
或者根据实际问题来决定,看问题的目的/需求需要多少K。
主要介绍关于Dimensionality Reduction(降维),适用于有大量features,这有助于减少计算机资源的使用,加速算法运算。介绍了一些小例子来展示这个处理步骤的好处。
处理的目标是让所有数据的投影距离最小:
1. 预处理
2. 计算covariance matrix协方差矩阵
3. svd(singular value decomposition):奇异值分解
svd得到的U矩阵的列即为我们所需的u1/u2/uk
4. 选作用大的几个ui得到U reduce,于是得到z
当没保存所有的uk时,PCA是一种有损耗压缩算法,可以从压缩后的数据再转换回原始数据相近似的数据。通过矩阵操作:
明显得到的Xapprox的维度比之前低。
如何选择那些ui?选择最大的保留数据方差的,通常用variance比例来叙述而不是 k的具体个数,因为k的个数效果和原本n有多大有关:
具体计算过程如下:
S是一个对角线矩阵,其中保存了每个uk所对应的的sum(Sii),不需要循环计算Xapprox,只需要循环取出S的对角元素来计算 。
tips1. 具体步骤如下,以图像识别为例,生成U只需要training set,cv和test集应用U来处理就行:
tips2. 对于不同使用PCA的目的,k的选择也不同:
tip3. Bad use 使用PCA来避免overfitting:
并不是说PCA完全没效果,而是Overfitting问题最好用regularization。因为PCA并不区分它所处理的数据,只看variance,可能会丢失关键信息。且Regularization的结果不会比PCA差。
tip4. Bad use 上来就用PCA
应该先使用原始数据做Design,当原始数据的ML system效果差时,再考虑PCA。
K = 16,max_iters = 10 时的四次不同初始化
对max_iters = 10不同初始化处理十次,得到最小的误差为0.162408,这个结果比max_iters = 30一次得到的误差0.162862还要小,初始值对聚类算法的影响确实很大。
以及尝试拐点:
看起来并不是很有用,实际处理过程中发现K取16~20效果最好。
这里K取2,效果还挺好看的
蓝色为正则后的数据,红色为K=1投影后再恢复的数据
展示的是U(:, 1:36)'
展示的是K=100后压缩再恢复的数据,计算得variance占比0.9319。PS:计算得K=130时variance占比0.95。
利用K-means方法取K=16,并抽样1000个像素,XYZ坐标为像素rgb的值,根据他们对应的质心染色。
plotDataPoints(Z(sel, :), idx(sel), K);
Z:X_norm 3维投影后得到的2维 idx: 像素对应的质心
%% ============= Part 4: K-Means Clustering on Pixels ===============
% 这部分把图片的所有像素的颜色进行聚类,得到[centroids, idx]
% 部分代码注释:
A = double(imread('bird_small.png'));
A = A / 255;
% 预处理,使颜色值范围在0~1
img_size = size(A);
% 结果为:128 128 3,分别代表图片的长、宽、颜色rgb
X = reshape(A, img_size(1) * img_size(2), 3);
% X的size为(128*128, 3)
K = 16;
max_iters = 10;
% 试试不同的值
% 以上的代码对不同size的其他图片也适用
%% ================= Part 5: Image Compression ======================
% 这部分把像素替换成centroids中最相近颜色
X_recovered = centroids(idx,:);
% 相当于for循环映射,适用于idx尺寸为m*1
% for i=1:length(idx)
% X_recovered(i, :) = centroids(idx(i), :);
% endfor
subplot(1, 2, 1);
imagesc(A);
% imagesc (IMG): 展示matrix IMG as a color image.
title('Original');
function [centroids, idx] = runkMeans(X, initial_centroids, max_iters, plot_progress)
按照之前的教学,for迭代处理max_iters次数:
1. findClosestCentroids找到所有X对应的簇质心
2. computeCentroids得到新的质心位置并更新
每个循环画出对应图像,遇到的新函数有
### function plotDataPoints
palette = hsv(K + 1);
% hsv (N):
% 返回N组rgb值,size为Nx3,用于画图。
colors = palette(idx, :);
% idx为X中300个数据所分别对应的质心i,这样直接得到300x3的每个数据对应颜色
scatter(X(:,1), X(:,2), 15, colors);
% scatter (X, Y, S, C) 根据X、Y、maker大小、颜色画一个二维图
randidx = randperm(size(X, 1));
% randperm (N, M)
% 返回一行[1, N]的值的随机排列,如果M存在就返回M个,如果M不存在则返回N个(M<=N)
%% =============== Part 2: Principal Component Analysis ===============
% U的每一列都代表一个u方向,S则是对角矩阵
% 乘上S则线段长短表示其方向占方差的比例
hold on;
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);
hold off;
1. 注意,收敛的解决方案可能并不总是理想的,并且取决于质心的初始设置。 因此,在实践中,K-means 算法通常使用不同的随机初始化运行几次。然后在这些不同初始化中选有最低成本函数值(失真)的。
2. computeCentroids和findClosestCentroids可以不用loop,怎么做?看到这个问答后,我决定暂时不去尝试简化loop。
You're going to have to create a 3D matrix, and implement some tricky software to work in 3D, and it's really not worth the effort.
I recommend you work in 2D and use a for-loop over the centroids.
1.之前一直没有去思考,为什么要使用bsxfun去代替octave原生的矩阵操作:参考这个问答