一、算法步骤
1、随机选取k个初始中心点;
2、针对数据集中的每个样本点,计算样本点与k个中心点的距离,将样本点划分到离它最近的中心点所对应的类别中;
3、类别划分完成后,重新确定类别的中心点,将类别中所有样本各特征的均值作为新的中心点对应特征的取值,即该类中所有样本的质心;
4、重复上面的2、3步骤,直到到达某个终止条件(迭代次数,每一个簇中的点不再变等·)
二 西瓜书数据集4.0代码
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体为黑体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
def createxcle():
dataset = pd.read_excel('train.xlsx')
label=dataset.columns
return np.array(dataset),label
def Kmean(dataset,k):
#k 个聚类簇数
dataArray=dataset[:,:-1] #二维数组不含判断列
#初始化k个均值向量
index =np.random.randint(0,len(dataset),k) #返回k个随机索引的列表
mu = dataArray[index] #创建初始簇
# [[0.697 0.46 ]
# [0.473 0.376]
# [0.282 0.257]
# [0.639 0.161]
# [0.751 0.489]]
m=len(dataset) #样本数据个数
#划分簇
flag=True
retCluster={} #设置一个空簇集合
while flag:
cluster={} #Ci=空集
for i in range(m):
minDist=np.inf #无穷
minIndex=-1
for j in range(len(mu)):
meanDist=np.sqrt(((dataArray[i] - mu[j]) ** 2).sum()) #计算数据与均值向量的距离
if meanDist<minDist:
minDist=meanDist
minIndex=j #最小的样本值 下标索引
# 把第i个元素划入第j个簇中 用字典的值(它是列表)来保存样本下标索引
if minIndex not in cluster.keys():
cluster[minIndex]=[] #把这个字典中簇的值设置为 空列表[]
cluster[minIndex].append(i)
#2.更新均值向量
updateNums =0 #更新次数统计
for i in range(k):
data =np.array(dataArray[cluster[i]]) #data为每个簇中保存的样本x
print(data,'簇C{}的样本包含{}'.format(i,data))
#计算新均值向量
mu2= data.sum(axis=0)/len(data) #axio案列相加[[0.697 0.46 ] [0.774 0.376] ]
#检验均值向量是否相同
vecDist=np.sqrt(((mu[i]-mu2)**2).sum())
if vecDist!=0:
mu[i]=mu2
updateNums=1
if updateNums==0:
flag=False
retCluster=cluster
return retCluster,mu
def main():
dataSet, label = createxcle()
cluster,mu = Kmean(dataSet,6)
print(cluster,'每个簇')
print(mu,'簇均值')
for key in cluster.keys():
data=np.array(dataSet[cluster[key]])
plt.scatter(data[:, 0], data[:, 1],label=key)
plt.scatter(mu[:, 0], mu[:, 1], s=80, c='r', marker="D")
plt.xlabel('密度',fontsize=20)
plt.ylabel('含糖率',fontsize=20)
plt.legend()
plt.show()
if __name__ == '__main__':
main()
三 运行结果
{0: [0, 1, 22, 26, 29],
1: [2, 3, 4], 3: [5, 10, 15, 19, 20],
5: [6, 8, 11, 12, 18],
2: [7, 9, 13, 14, 16, 17, 21],
4: [23, 24, 25, 27, 28, 30]} 每个簇
[[0.7322 0.4232 ]
[0.59933333 0.26566667]
[0.66971429 0.13114286]
[0.3254 0.2744 ]
[0.4895 0.40416667]
[0.373 0.1408 ]] 簇均值
四 train.xlsx数据
密度 | 含糖率 | 好瓜/坏瓜 |
0.697 | 0.46 | 1 |
0.774 | 0.376 | 1 |
0.634 | 0.264 | 1 |
0.608 | 0.318 | 1 |
0.556 | 0.215 | 1 |
0.403 | 0.237 | 1 |
0.481 | 0.149 | 1 |
0.666 | 0.091 | 1 |
0.437 | 0.211 | 1 |
0.666 | 0.091 | -1 |
0.243 | 0.267 | -1 |
0.245 | 0.057 | -1 |
0.343 | 0.099 | -1 |
0.639 | 0.161 | -1 |
0.657 | 0.198 | -1 |
0.36 | 0.37 | -1 |
0.593 | 0.042 | -1 |
0.719 | 0.103 | -1 |
0.359 | 0.188 | -1 |
0.339 | 0.241 | -1 |
0.282 | 0.257 | -1 |
0.748 | 0.232 | -1 |
0.714 | 0.346 | 1 |
0.483 | 0.312 | 1 |
0.478 | 0.437 | 1 |
0.525 | 0.369 | 1 |
0.751 | 0.489 | 1 |
0.532 | 0.472 | 1 |
0.473 | 0.376 | 1 |
0.725 | 0.445 | 1 |
0.446 | 0.459 | 1 |