K-Means算法(实例)
程序员文章站
2022-05-20 19:49:51
...
K-Means算法实例:
本文的是上一篇的实例部分
以下代码均是在Matlab中实现。
1.初始化中心点
function centroids = kMeansInitCentroids(X, K)
centroids = zeros(K, size(X, 2));% 初始化centroids为一个K by n 的矩阵
m = size(X,1);
rands = randperm(m,K);% 从1到m中随机选取K个数
centroids = X(rands,:);% 从X中,选取K个点作为初始中心点
end
randperm的用法,戳此处
2.计算最近的中心点
function idx = findClosestCentroids(X, centroids)
K = size(centroids, 1);
idx = zeros(size(X,1), 1);%idx 就是前面说到的c(i) m by 1
m = size(X,1);
for i = 1:m;% 对所有点进行遍历,计算时采用矩阵形式比较方便
subs = centroids - X(i,:);% 一个点到到三个中心点的向量
distance2 = sum(subs.^2,2);%计算这三个向量模长的平方
[temp,idx(i)] = min(distance2);%选取距离最近的
end
end
min的用法,戳此处
3.更新中心点
function centroids = computeCentroids(X, idx, K)
[m n] = size(X);
centroids = zeros(K, n);
Xy = [X idx];
%我们知道idx是用来标记每一个点属于哪个中心点所在的类,所有Xy就相当于一个包含标签值的数据集了
for k = 1:K;
index = find(Xy(:,n+1)==k);%在Xy中找到第k类数据的行号
% Xy(:,n+1)==k 意思是说,Xy中第n+1列(此处为第3列)数值等于k
temp = X(index,:);%在X中选出对应的行,也就是选出某一类中所有的点
s = sum(temp);%进行向量相加(对应列分量相加)
centroids(k,:) = s./size(index,1);%更新
end
end
4.代价计算
function J = costFunction(X,idx,centroids,K)
J = 0;
[m,n] = size(X);
Xy = [X idx];
for i = 1:K;
index = find(Xy(:,n+1)==i);
temp = X(index,:);%找到属于同一类的所有点
subs = temp - centroids(i,:);%构成一个向量
s = sum(sum(subs.^2));%计算每一个向量的模长的平方,并将所有的模长的平方相加
J = J+s; % 累加每一个类别对应的代价
end
%J = J/100;
end
5.调用
load('ex7data2.mat');
[m,n] = size(X);
K = 3;
centroids = zeros(K,n);
centroids = kMeansInitCentroids(X,K);
iterations = 10;
idx = zeros(m,1);
J_history = zeros(iterations,1);%保存每一次迭代所产生的代价值
for i = 1: iterations;
idx = findClosestCentroids(X,centroids);
J_history(i) = costFunction(X,idx,centroids,K);
centroids = computeCentroids(X,idx,K);
end;
figure(1);
plot(J_history);
xlabel('iterations');
ylabel('costFuntion J');