数模M02-Kmeans聚类
KMeans聚类法
一、Kmeans内容
Video:~Bilibili-ln异教徒 Kmeans
随机生成k个聚类中心点
其中k值的确定可以采用“手肘法”,通过分析不同k值下误差平方和(SSE)的值的变化,选取其”肘部“作为合适的聚类数目
其中$C_i$是第i个类,p是$C_i$中的样本点,$m_i$是$C_i$的质心($C_i$中所有样本点的均值),SSE是所有样本的聚类误差,代表了聚类效果的好坏。通过找寻SSE的值的下降幅度剧烈减小的位置来判断合适的k取值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22function SSE = funcSSE(data,total) % data为数据,total为要划分的类别总数
n = size(data,2); % data的ColCount
for i = 2:total
k = i;
[label,c] = kmeans(data,k);
temp = 0;
for j = 1:i % 按照分类数量遍历
loc = find(label == j) % 找到每个类别所对应的行标(Row),形成一个Arr
for j2 = 1:n % 按照Col遍历
temp = temp + sum((data(loc,j2)-c(j,j2)).^2)
% 通过loc得到一个row区域内的所有label与c索引相同的数据
% 依次loc所对应数据块中的每一列与c同列的数据相减并求点成的平方
% 随后sum求和处理后每一列loc数据的和并且与先前的其他列数据结果相加
% 将每一个label相同的data和c的结果再相加,全部用temp承接数值
% 实际上是将原本每一数据点同其c的减法求平方(距离)过程纵向化了
% 用于矩阵运算的遍历,以及其最终得到的结果就是每个数据每个坐标的距离
% 所以可以用这种简单的方法Coding
end
end
SSE(i-1) = temp % 令SSE这个Arr的数值仍然从Index=1开始
end
end
根据聚类中心点,将数据分为k类。分类的原则是数据离哪个中心点最近就将他分为哪一类别
距离的判断采用欧式距离(欧几里得距离):
令各类中心为 $\mu_j$ ,计算各个数据到各类中心点的距离为$(x-\mu_j)^2$
根据分好的类别的数据,重新计算聚类的类别中心点
不断重复上述的两步,直到中心点不再变化,得到聚类结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23clear
clc
%% 数据导入
data = xlsread('./k-means.xlsx');
%% SSE手肘法判断
km = 10; % 所需的k最大测试值
SSE = funcSSE(data,km);
plot(2:km,SSE)
k = 5; % 选择 k=5
%% Kmeans聚类
[label,center] = kmeans(data,k)
%% DispPlot
figure
scatter(0,data(label==1),'cyan')
hold on
scatter(0,data(label==2),'b')
scatter(0,data(label==3),'g')
scatter(0,data(label==4),'y')
scatter(0,data(label==5),'black')
for i = 1:k
plot([-0.1,0.1],[center(i),center(i)],'r')
end
xlim([-1,1])
二、Python可使用代码
1 | import numpy as np |
1 | plt.rcParams['font.family'] = 'Consolas' |
1 | # 随机数据 |
1 | plt.scatter(x, y) |
1 | # 手肘法判断图 |
1 | from sklearn.cluster import KMeans |
1 | colorg1 = ['#1f77b4', '#2ca02c', '#ff7f0e', '#7f7f7f', '#9467bd'] |
1 | df_cat.to_csv(r'./kmoutput.csv') |
三、Python展开Kmeans聚类
1 | # 生成测试数据 |
评论