本文给出了k聚类算法的简单实现
数据下载地址链接:https://pan.baidu.com/s/1iLLWZ73ErShuDOByWEMFEQ
提取码:5chg
import numpy as np
import matplotlib.pyplot as plt
#将文件数据存入数组
def LoadDataSet(filename):
fr = open(filename)
rowdata = fr.readlines()
length = len(rowdata)
dataset = np.zeros((length, 2)) #构造n行 2 列矩阵
index=0
for line in rowdata:
line = line.strip() #将每行变成现在这样 1.658985 4.285136
curline = line.split('\t') #将每行变成现在这样 ['1.658985', '4.285136']
dataset[index, :] = curline
index += 1
return dataset
#距离计算函数
def ArrayDistance(VecA,VecB):
return np.sqrt(np.sum(np.power((VecA-VecB),2)))
#随机生成簇,维度要与数据集一致
def SetCluster(dataset,k): #随机生成k个簇
Dimension = dataset.shape[1] #得到列
cluster = np.mat(np.zeros((k,Dimension))) #生成一个簇的容器
for i in range(Dimension): #生成簇 不过要在所有数据的区域内
datarange = float(max(dataset[:,i]) - min(dataset[:,i])) #最大值与最小值的差距
cluster[:,i] = datarange * np.random.rand(k,1) + min(dataset[:,i])
return cluster
#通过算法进行数据分析,本文使用的是k-均值算法,得到新簇
def KMeans(dataset, k): # k为簇的个数
datalength = len(dataset) # 获取数据集样本个数
cluster = SetCluster(dataset, k) # 随机生成簇
SampleToCluster = np.mat(np.zeros((datalength, 2))) # 此矩阵用标记向量属于哪一个簇中
clusterIsChange = True # 标记最新的变化
while clusterIsChange:
clusterIsChange = False
for i in range(datalength): # 遍历每个数据样本判断此数据样本应该属于哪个簇
mindis = np.inf
minindex = -1
for j in range(k):
distance = ArrayDistance(dataset[i, :], cluster[j, :])
if mindis > distance: mindis = distance; minindex = j
if (SampleToCluster[i, 0] != minindex): clusterIsChange = True; # 最新的分配是否有变化
SampleToCluster[i, :] = minindex, mindis # 更新分配矩阵
for i in range(k):
ptsInClust = dataset[np.nonzero(SampleToCluster[:, 0].A == i)[0]] # 获取第i个簇中的所有的向量
cluster[i, :] = np.mean(ptsInClust, axis=0) # 按列求平均得到全新的第i个簇
return cluster, SampleToCluster
a = LoadDataSet('D:\python_exc\kjldata.txt') #载入数据
aa , bb = KMeans(a,4) #K-均值算法
print(aa)
#进行绘图 数据可视化
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(a[:,0].tolist(),a[:,1].tolist(),20,15.0*bb[:,0].reshape(1,80).A[0])
ax.scatter(aa[:,0].tolist(),aa[:,1].tolist(),marker='x',color='r')
plt.show()