# 源数据处理
from numpy import *
import matplotlib.pyplot as plt
# 加载数据
data = open('data.txt')
# 源数据列表
datas = []
for line in data.readlines():
# 行数据拆分
# 格式为['1.65', '4.28']
axisData = line.strip().split('\t')
# 列表数据转为float类型
# [1.65, 4.28]
axisDatass = map(float, axisData)
# 存储数据
datas.append(axisDatas)
# 源数据矩阵
datasMat = mat(datas)
# 获取源数据维度
m = shape(datasMat[0])
n = shape(datasMat[1])
# 生成聚类矩阵
# 存储聚类结果,第一列为元素所在组,第二列为元素到中心点的距离
clusterAssment = mat(zeros((m, n)))
# 生成中心点矩阵,4为种类,2为源数据列数
centroids = mat(zeros((4, 2)))
# 获取源数据最大值与最小值坐标
minJ0 = min(datasMat[:, 0])
minJ1 = min(datasMat[:, 1])
maxJ0 = max(datasMat[:, 0])
maxJ1 = max(datasMat[:, 1])
rangeJ0 = float(maxJ0 - minJ0)
rangeJ1 = float(maxJ1 - minJ1)
# 随机生成中心点
centroids[:, 0] = minJ0 + rangeJ0 * random.rand(4, 1)
centroids[:, 1] = minJ1 + rangeJ1 * random.rand(4, 1)
# 迭代标志位
clusterChanged = True
while clusterChanged:
clusterChanged = False
for i in range(20):
minDistance = inf
minIndex = -1
for j in range(4):
# 计算中心点与各点的距离
distance = sqrt(sum(power(centroids[j,:] - datasMat[i, :], 2)))
if distance < minDistance:
# 更新距离,找到最小距离
minDistance = distance
# 依据最小距离聚类,记录所在的组号
minIndex = j
# 若聚类发生改变,继续迭代
if clusterAssment[i, 0] != minIndex:
clusterChanged = True
# 结果:分类结果
clusterAssment[i, :] = minIndex, minDistance**2
# 结果:中心点
for center in range(4):
pointsCluster = datasMat[nonzero(clusterAssment[:, 0].A == center)[0]]
centroids[center, :] = mean(pointsCluster, axis=0)
# 打印聚类结果:中心点及聚类结果
print("Center of points: {}".format(centroids))
print("Cluster result: {}".format(clusterAssment))
# 源数据各点的分类及到中心点的距离
# 第一列为组别,第二列为各点到中心点的距离
# 获取第一列为组别标签
label = clusterAssment[:, 0].tolist()
# 绘图点形状及颜色,依据组别绘制不同颜色
mark = ['or', 'ob', 'og', 'oy', '^r', '+r', 'sr', 'dr', '<r', 'pr']
# 中心点形状及颜色
color = ['*r', '*b', '*g', '*y']
j = 0
for i in range(4):
plt.plot(centroids[i,0], centroids[i, 1],color[i] ,markersize=12)
# label为列表形式[[0.0],[1.0]]
# 使用需要提取数字,并转为int
for i in label:
plt.plot(datasMat[j,0], datasMat[j, 1], mark[int(i[0])], markersize=5)
j += 1
# plt.scatter()
plt.show()