C均值聚类

聚类是指事先不知道样本的类别,而利用样本的先验知识来构造“分类器”,是一种无监督学习。常用的聚类算法有分裂聚类法和动态聚类法等。

C均值聚类是一种动态聚类方法,概要为:第一步,选定某种距离作为样本间的相似性度量;第二步,确定评价聚类结果的准则函数;第三步,给出某种初始分类,用迭代法找出使准则函数取极值的最好聚类结果。

设待聚类的模式特征矢量集为\{ \overrightarrow{x_1} , \overrightarrow{x_2}, ..., \overrightarrow{x_N} \},聚类数目C是事先设定的。算法的思想为取定C个类别和选取C个初始聚类中心,按最小距离原则将各模式分配到C类中的某一类,之后不断地计算聚类中心、调整各模式类别,最终使各模式到其聚类团类别中心的距离平方之和最小。算法步骤如下:
1) 任选C个模式特征矢量作为初始聚类中心:\overrightarrow{z_1}^{(0)} , \overrightarrow{z_2}^{(0)}, ..., \overrightarrow{z_c}^{(0)},令k=0。
2) 将待聚类的模式特征矢量集\{ \overrightarrow{x_i} \}中的模式逐个按最小距离原则分划给c个类团中的某一类,即
:如果d_{il}^{(k)}=\min _j[d_{ij}^{k}](i=1,2,...,N)\overrightarrow{x_i} \in G_l^{(k+1)}d_{ij}^{(k+1)}式中表示\overrightarrow{x_i}G_l^{(k+1)}的中心\overrightarrow{x_j^{(k)}}的距离,上角标表示迭代次数。于是产生新聚类G_j^{(k+1)}(j=1,2,..,c)
3) 计算重新分类后的各类心

\overrightarrow{z_j^{k+1}}=\frac{1}{n_j^{(k+1)}} \sum_{\overrightarrow{x_i} \in G_j^{(k+1)}} \overrightarrow{x_i},(j=1,2,...,c)
式中n_j^{(k+1)}为聚类团G_j^{k+1}中所含模式的个数。
4) 如果\overrightarrow{z_j^{(k+1)}} = \overrightarrow{z_j^{(k)}},j=1,2, ..., c,则结束,否则k=k+1,转至2。

function [idx, C, innerSumD, outerSumD] = cmeans(X, k, PlotOrNot)
%=======================================================
%function [idx, C, innerSumD, outerSumD] = cmeans(X, k, PlotOrNot)
%C均值聚类
%input: X:Original Data(n*l,n:variables, l:observation)
%       k:number of clusters in the data(positive integer)
%       PlotOrNot: true plot figures of cluster, false not plot
%output: idx:cluster indices(row vector)
%        C:cluster centroid locations
%        innerSumD:within-cluster sums of point-to-centroid distances
%        outerSumD:sum distances between cluster
%Envirment:MATLABR2018b
%=======================================================

%% 1. 初始化类中心
[n, l] = size(X);
idx = ones(1, l);
idx(2) = 2;
m = zeros(n, k);
DrawColor = rand(k, 3);
iterations = 0;                 % 迭代次数
ind = randperm(l);
for i = 1 : k
    m(:, i) = X(:, ind(i));
end

%% 2.使用Cmeans算法进行迭代聚类
idx1 = zeros(1, l);
tempD = zeros(k, l);
while sum(idx1 == idx) ~= l
    iterations = iterations + 1;
    innerSumD(iterations) = 0;
    outerSumD(iterations) = sum(sqrt((sum((m - mean(m, 2)) .^ 2))), 2);
    if PlotOrNot
        figure();
        title(sprintf('第%d次聚类结果', iterations));
        hold on;
    end
    for i = 1 : k
        innerSumD(iterations) = innerSumD(iterations) + ...
            sum(sqrt(sum((X(:, idx == i) - m(:, i)) .^ 2)), 2) / l;
        if PlotOrNot
            scatter(X(1, find(idx == i)), X(2, find(idx == i)), ...
                'MarkerFaceColor', DrawColor(i, :), 'MarkerEdgeColor', DrawColor(i, :));
        end
    end
    if PlotOrNot
        f = getframe;
        imwrite(f.cdata, sprintf('第%d次聚类结果.png', iterations));
    end
    for i = 1 : k
        tempD(i, 1: l) = sqrt(sum((X - m(:, i)) .^ 2, 1));
    end
    idx1 = idx;
    [~, idx] = min(tempD);
    for i = 1 : k
        m(:, i) = mean(X(:, find(idx == i)), 2);
    end
end
C = m;

if PlotOrNot
    figure(), hold on;
    plot(innerSumD, 'r-', 'LineWidth', 3);
    plot(outerSumD, 'b--', 'LineWidth', 3);
    plot(outerSumD ./ innerSumD, 'g-.', 'LineWidth', 3);
    legend('聚类团内距离和', '聚类团间距离和', '聚类团间距离和/聚类团内距离和');
    title('聚类准则示意图');
    f = getframe;
    imwrite(f.cdata, '聚类准则示意图.png');
end

end

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值