聚类
聚类算法,一般情况下将给定的数据集划分为若干个不相交的子集,每个子集称为一个簇,即将数据集划分为几类。在这种情况下,可能会对一些潜在的概念进行划分,用周志华《机器学习》中的话来讲,聚类算法可能会将原本的西瓜数据集潜在地划分为浅色瓜、深色瓜、有籽瓜、无籽瓜等,虽然你原本将其分为好瓜和坏瓜。值得注意的是,这些概念对于聚类算法而言是事先未知的,即聚类算法会自动地把数据集划分为簇结构,每个簇的名称和含义需要使用者来命名和把握。
一、Kmeans聚类
1.1 原理
属于原型聚类的一种,较为简单给。定样本集
D
=
{
x
1
,
x
2
,
.
.
.
,
x
m
}
D=\{x_1,x_2,...,x_m\}
D={x1,x2,...,xm},对于聚类,可以划分为簇
C
=
{
C
1
,
C
2
,
.
.
,
C
k
}
C = \{C_1,C_2,..,C_k\}
C={C1,C2,..,Ck},即将原数据划分为
k
k
k类,然后最小化平方误差:
E
=
∑
i
=
1
k
∑
x
∈
C
i
∣
∣
x
−
μ
i
∣
∣
2
2
\large E =\displaystyle\sum_{i=1}^k\displaystyle\sum_{x\in C_i}||x-\mu_i||^2_2
E=i=1∑kx∈Ci∑∣∣x−μi∣∣22
其中
μ
i
=
1
∣
C
i
∣
∑
x
∈
C
i
x
\large \mu_i=\frac{1}{|C_i|}\sum_{x\in C_i}x
μi=∣Ci∣1∑x∈Cix是簇
C
i
C_i
Ci的均值向量
上述公式不好求解,一般我们通过迭代的方式近视化求解,大致过程如下:
- 从数据集 D D D中随机选取 k k k个样本作为 k k k个簇的初始均值(簇中心)
- 计算每个样本跟每个簇均值的距离,将样本放入距离最近的簇中
- 根据每个簇中的样本,重新计算每个簇的均值
- 判断,如果新的均值等于之前的均值,则停止迭代,否者以新均值继续循环2-3
- 查看最后结果绘图
即根据每个簇的均值不断构建新的簇来迭代,直到每个簇的均值不变为止。
1.2 代码实现
使用了周志华《机器学习》p202表9.1西瓜数据集4.0,已经处理成CSV格式,请自取:
https://pan.baidu.com/s/1ecLAbe_ZP75u1h7Ig9KVRw
提取码:c2sh
数据集预览(共计30条,此处略去):
代码实现:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
data = pd.read_csv('xigua3.0.csv')
feature = ['密度','含糖率']
data = data[feature]
K = 3
#随机选取簇初始化
C_list = data.sample(K).values
data = data.values
while True:
cur_cluster = [[] for _ in range(K)] #用于存储每个簇的元素
for i in range(len(data)):
choose = {} #字典形式存放每个元素对于每个簇的距离,以此来判断该放入哪个簇
for j in range(K):
diff = np.mean((data[i]-C_list[j])**2)
choose[j] = diff
choose = sorted(choose.items(),key=lambda kv:(kv[1],kv[0]))
cur_cluster[choose[0][0]].append(data[i]) #将元素放入对应簇
flag = True#用于判断是否结束循环
#计算每个簇的均值并置为新的中心点,若均值与之前相等则结束循环
for i in range(K):
c = np.mean(cur_cluster[i],axis=0)
for j in range(c.shape[0]):
if c[j] != C_list[i][j]:
flag = False
C_list[i] = c
break
if flag:
break
color = np.random.random((3,K)) #随机颜色
#得到最终的分类结果并绘图
for i in range(K):
C = cur_cluster[i] #每一簇的元素
x = [i[1] for i in C]
y = [i[0] for i in C]
plt.scatter(x,y,c = color[i],label = 'C'+str(i)) #随机颜色
plt.legend()
plt.xlabel('midu')
plt.ylabel('hantang')
plt.show()
最终结果:
注意,由于每次抽取的初始样本不同,所以每次运行的结果也不相同
注意,由于每次抽取的初始样本不同,所以每次运行的结果也不相同
如果有兴趣,可以自行存储每一个迭代过程的聚类情况绘图,这里不再赘述