无监督学习算法
第八章,聚类算法
一、K-means(k均值)算法
1.K-means(k均值)算法:将一堆数据分成K类
举例:将二维平面的数据分成2部分
预处理:在平面上随机选两个点(聚类中心)
K均值是一个迭代方法 它要做两件事情
- 簇分配:每个数据里选好的两个点哪个近,就将他分到那一类里
- 移动聚类中心:每个聚类中心移动到分配给它的那些点的均值处
注意:如果有个聚类中心没有分配到点,一般情况是将它删除(如果就是要K个分类,可以再给他随机初始化一个点)
2.k均值算法优化目标
其中c(i)表示:第i个点被分到第c(i)类中;μi表示第i个聚类中心的值
可以想象K均值的两步都会减小J函数
3.K-means(k均值)算法会得到局部最优值:取决于随机初始化的值,比如
一般的初始化方法是从数据集中随机选取K个作为聚类中心,并且因为局部最优值的问题,要多次运行这个K-means算法(一般50-1000次),选取最优的。
当K<10时,多运行几次会比较好。
4.选取K:没有好的算法来做。大部分情况手动,或者看实际情况,看后续需要。
肘部法则:不一定有用,下图中图1可以选K=3,图2不好选
二、dimensionality reduction降维
1. 删除重复的特征,将aD->bD(a>b)
2.Principal Component AnalysisPCA 主成分分析法
原因:对于一个问题,当有很多特征时,比如上千,特征之间就会有相关性,甚至重复。所以需要进行压缩,或者说修改特征使每一个特征保持独立性。
寻找一个低维的面,数据投射在上面,使得原数据与投射点的距离差(投影误差)的平方和的总和达到最小值。
算法步骤:
先要特征缩放和均值归一化。(注意:一定要归一化,不然PCA会产生不想要的结果。 缩放最好也用)
奇异值分解
只使用它的U,生成的U的格式如下,选取前k个列,就是所要求的k个的向量。
(X是n*m)
z为新获得的压缩的X即结果。
3.主成分分析法的k值的选择
如果k=n,上面的等式=0
直观方法:
遍历k从1-n
缺点:每次遍历都要用一次PCA算法。
优化方法,使用svd函数(图片右边):
4.由压缩的求原来的:(我推了下好像不对啊)
5.使用注意
6.降维的作用:
节省磁盘、内存空间;加快算法速度;可视化。
7.主成分分析法不能用来避免过拟合,因为没有考虑到y值进行的降维,可能会将一些信息扔掉,应该用正则化来避免。
8.对于一个新的问题,不要一上来就是用PCA来降维,应该线运行一个没有PCA的算法,如果出现运行很慢,内存太大,磁盘空间问题,或者需要降到2,3D来可视化时才有必要使用PCA,否则就不要使用。
代码:
一、K均值
1.簇分配
function idx = findClosestCentroids(X, centroids) K = size(centroids, 1); m=size(X,1); idx = zeros(m, 1); v=zeros(K,1); minv=1; for i=1:m for j=1:K v(j)=(X(i,:)-centroids(j,:)) * (X(i,:)-centroids(j,:))'; end; [minv,idx(i)]=min(v); end; end;
2.移动聚类中心
function centroids = computeCentroids(X, idx, K) [m n] = size(X); centroids = zeros(K, n); num=zeros(K, 1); for i=1:m centroids(idx(i),:)+=X(i,:); num(idx(i))++; end; for i=1:K centroids(i,:)=centroids(i,:) ./ num(i); end; end
3.K均值算法
function [centroids, idx] = runkMeans(X, initial_centroids, ... max_iters, plot_progress) if ~exist('plot_progress', 'var') || isempty(plot_progress) plot_progress = false; end if plot_progress figure; hold on; end [m n] = size(X); K = size(initial_centroids, 1); centroids = initial_centroids; previous_centroids = centroids; idx = zeros(m, 1); for i=1:max_iters % Output progress fprintf('K-Means iteration %d/%d... ', i, max_iters); if exist('OCTAVE_VERSION') fflush(stdout); end % For each example in X, assign it to the closest centroid idx = findClosestCentroids(X, centroids); % Optionally, plot progress here if plot_progress plotProgresskMeans(X, centroids, previous_centroids, idx, K, i); previous_centroids = centroids; fprintf('Press enter to continue. '); %pause; end % Given the memberships, compute new centroids centroids = computeCentroids(X, idx, K); end if plot_progress hold off; end end
4.上端代码调用的plotProgresskMeans:画中心的改变状态
function plotProgresskMeans(X, centroids, previous, idx, K, i) plotDataPoints(X, idx, K); plot(centroids(:,1), centroids(:,2), 'x','MarkerEdgeColor','k', 'MarkerSize', 10, 'LineWidth', 3); for j=1:size(centroids,1) drawLine(centroids(j, :), previous(j, :)); end title(sprintf('Iteration number %d', i)) end
5.上端代码调用的plotDataPoints
function plotDataPoints(X, idx, K)%每个点的颜色不一样 palette = hsv(K + 1); colors = palette(idx, :); scatter(X(:,1), X(:,2), 15, colors); end
6.随机初始化代码
function centroids = kMeansInitCentroids(X, K) centroids = zeros(K, size(X, 2)); randidx=randperm(size(X,1)); centroids=X(randidx(1:K),:); end
7.整体代码
clear ; close all; clc load('ex7data2.mat'); %plot(X(:,1),X(:,2),'rx') K = 3; % 3 Centroids initial_centroids = [3 3; 6 2; 8 5]; %centroids=initial_centroids; idx = findClosestCentroids(X, initial_centroids); %fprintf(' %d', idx(1:3)); centroids = computeCentroids(X, idx, K); %fprintf(' %f %f ' , centroids'); K = 3; max_iters = 10; initial_centroids = [3 3; 6 2; 8 5]; %[centroids, idx] = runkMeans(X, initial_centroids, max_iters, true); clear ; close all; clc A = double(imread('bird_small.png')); A = A / 255; img_size = size(A); X = reshape(A, img_size(1) * img_size(2), 3); K = 16; max_iters = 10; initial_centroids = kMeansInitCentroids(X, K); [centroids, idx] = runkMeans(X, initial_centroids, max_iters); idx = findClosestCentroids(X, centroids); X_recovered = centroids(idx,:);%好的用法 X_recovered = reshape(X_recovered, img_size(1), img_size(2), 3); % Display the original image subplot(1, 2, 1); imagesc(A); title('Original'); % Display compressed image side by side subplot(1, 2, 2); imagesc(X_recovered); title(sprintf('Compressed, with %d colors.', K));
二、PCA降维
1.归一化、缩放
function [X_norm, mu, sigma] = featureNormalize(X) mu = mean(X); X_norm = bsxfun(@minus, X, mu); sigma = std(X_norm); X_norm = bsxfun(@rdivide, X_norm, sigma); end
2.PCA算法求U
function [U, S] = pca(X) [m, n] = size(X); U = zeros(n); S = zeros(n); sigma=(X' * X)/m; [U,S,T]=svd(sigma); end
3.利用U求Z
function Z = projectData(X, U, K) Z = zeros(size(X, 1), K); Z=X*U(:,1:K); end
4.恢复数据,由Z得出X
function X_rec = recoverData(Z, U, K) X_rec = zeros(size(Z, 1), size(U, 1)); X_rec=Z*(U(:,1:K)'); end
5.整体
clear ; close all; clc load ('ex7data1.mat'); %plot(X(:, 1), X(:, 2), 'bo'); %axis([0.5 6.5 2 8]); axis square; [X_norm, mu, sigma] = featureNormalize(X); [U, S] = pca(X_norm); %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; %plot(X_norm(:, 1), X_norm(:, 2), 'bo'); %axis([-4 3 -4 3]); axis square K = 1; Z = projectData(X_norm, U, K); fprintf('Projection of the first example: %f ', Z(1)); %恢复 X_rec = recoverData(Z, U, K); fprintf('Approximation of the first example: %f %f ', X_rec(1, 1), X_rec(1, 2)); hold on; %plot(X_rec(:, 1), X_rec(:, 2), 'ro'); %for i = 1:size(X_norm, 1) % drawLine(X_norm(i,:), X_rec(i,:), '--k', 'LineWidth', 1); %end hold off clear ; close all; clc load ('ex7faces.mat') % Display the first 100 faces in the dataset %[h,array]=displayData(X(1:100, :)); [X_norm, mu, sigma] = featureNormalize(X); [U, S] = pca(X_norm); displayData(U(:, 1:100)'); K = 100; Z = projectData(X_norm, U, K); fprintf('%d ', size(Z)); X_rec = recoverData(Z, U, K); % Display normalized data subplot(1, 2, 1); displayData(X_norm(1:100,:)); title('Original faces'); axis square; % Display reconstructed data from only k eigenfaces subplot(1, 2, 2); displayData(X_rec(1:100,:)); title('Recovered faces'); axis square;