KMeans算法

1. \(k\)均值算法原理

给定一个数据集\(D=\{x_1,x_2,...,x_m\}\)\(k\)均值算法针对聚类所得划分\(C=\{C_1,C_2,...,C_K\}\)最小化平方误差

\[ E = \sum_{i=1}^{k}\sum_{x\in{C_i}} \begin{Vmatrix} {x-\mu_i} \end{Vmatrix}_2^2 \]

其中,\(\mu_i=\frac{1}{\mid{C_i}\mid}\sum_{x\in{C_i}}x\)是簇\(C_i\)的均值向量。刻画了簇内样本围绕簇均值向量的紧密程度,\(E\)值越小则簇内样本相似度越高。

2. 算法伪代码

  1. 输入数据集\(D\)
  2. 确定聚类簇数\(k\)
  3. 从数据集中选择\(k\)个样本作为初始聚类中心;
  4. 根据距离最小原则,将每个数据分配个相应的簇心;
  5. 计算平方误差
  6. 更新每个簇的簇心;
  7. 停止条件:平方误差不再变化. 否则,重复4,5,6.

3. 算法代码实现

clc
clear 
%% input data
load two_cluster.txt

%% 数据预处理
target = two_cluster(:, 1);
data = two_cluster(:, [2,3]);
%% 原始数据分布可视化
figure
scatter(data(:,1), data(:,2));
%% parameters setting
k = 2; % 类别数目
N_iter = 1000; % 最大迭代次数
expose = true;
errors = zeros(k, 1);
%% 初始化聚类中心
n = length(target);
loc = randperm(n); % 打乱数据序列

centroids = data([loc(1),loc(2)],:); % 随机选取2个簇心
%% main
labels = zeros(n, 1);
for it=1:N_iter
    %% classifation and label
    for i=1:n
        dists = sqrt(sum((data(i,:) - centroids).^2, 2)); % 计算距离
        [distMin, idx] = min(dists); % 寻找距离每个簇心的最小距离
        labels(i,:) = idx;
    end
    for j=1:2
       %% calculation erros
        errors(j, :) = sum(sqrt(sum((data((j==labels), :) - centroids(j, :)).^2, 2)),1);
    end
    %% ouput
    if expose
        disp(sum(errors));
    end
    for j=1:2
       %% update centers
        centroids(j,:) = mean(data((j==labels),:),1);
    end
end
%% 聚类后的数据可视化
figure
scatter(data((labels==1),1),data((labels==1),2), 'r*');
hold on
scatter(data((labels==2),1),data((labels==2),2), 'ko');
posted @ 2021-06-01 22:43  编码雪人  阅读(201)  评论(0编辑  收藏  举报