机器学习笔记(七)聚类算法(k均值,降维)

无监督学习算法

第八章,聚类算法

一、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 Analysis\PCA 主成分分析法

原因:对于一个问题,当有很多特征时,比如上千,特征之间就会有相关性,甚至重复。所以需要进行压缩,或者说修改特征使每一个特征保持独立性。

寻找一个低维的面,数据投射在上面,使得原数据与投射点的距离差(投影误差)的平方和的总和达到最小值。

算法步骤:

先要特征缩放和均值归一化。(注意:一定要归一化,不然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...\n', 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.\n');
            %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 \n' , 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\n', Z(1));

%恢复
X_rec  = recoverData(Z, U, K);
fprintf('Approximation of the first example: %f %f\n', 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;

 

posted @ 2014-11-27 09:49  baoff  阅读(2107)  评论(0编辑  收藏  举报