K-Means 算法
1.呈现
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
import datetime
import mathfrom sklearn.linear_model
import LinearRegression
from sklearn.cluster import KMeans
matplotlib.rcParams['font.family']='kaiti'
df=np.genfromtxt('kmeans.txt',delimiter='')
正常导包 和文件的读取
先来看一下点的分布决定k的值
暂时k=4
这是第一部分代码:先建立4个初始的质点center_point,
调用primary_center 函数(如下) 利用numpy.random.uniform 随机取4个值作为初始的质点
之后构建了一个表data_array,第一个列放入所属的簇 第二个列放入所属的簇与自己的误差
然后定义了一个最小距离 mindist对于一个index 遍历4 次找到最小的值 存储minlist 中间调用了另一个函数data_primary_center_distance(如下),目的是计算距离该点与质点的距离。
第二个if循环其实质是对于data_array的第一列存入所属的簇
没经历80次循环后 更新4个质点 取平均值代替原有质点
def kmeans(df,k):
index=df.shape[0]
center_point=primary_center(df,k)
data_array=np.zeros((index,2))
#先构建一个80 *2 的列表
#第一个列放入所属的簇 第二个列放入所属的簇与自己的误差
m=True
#m是用来控制循环的
while m:
m=False
for i in range(index):
mindist=10000.0
minindex=0
#定义一个最小距离
#对于每一个index 遍历4编 与 初始质点进行比较
# 取最小的 mindist=distance
for j in range(k):
distance=data_primary_center_distance(center_point[j,:],df[i,:])
if distance<mindist:
mindist=distance
data_array[i,1]=mindist
minindex=j
if minindex!=data_array[i,0]:
m=True
data_array[i,0]=minindex
# 4 个质点都比较后 选择最小的mindist 存储在在data_array 的第一列里存储 所属的簇
# 更新质点
# print(data_array)
for j in range(k):
data_index=np.nonzero(data_array[:,0]==j)
# numpy.nonzero是用来返回一个多维数组中不为0的元素的下标,
# 这个下标包含两个维度,可以想象成行和列的索引。也就是说,它的返回值是一个包含两个数组的元组
# print(data_index)
data=df[data_index]
# print(data)
center_point[j,:]=np.mean(data,axis=0)
# 对于相同簇的index 取平均值 重新设置四个质点
# print(center_point)
return center_point,data_array
center_point,data_array=kmeans(df,k)
# print(center_point)
def primary_center(df,k):
index=df.shape[0]
columns=df.shape[1]
center_points=np.zeros((k,columns))
for i in range(4):
center_point_index=int(np.array(np.random.uniform(0,index)))
# print(center_point)
# 随机选择4个质点
center_points[i,:]=df[center_point_index,:]
# print(center_points)
return center_points
def data_primary_center_distance(data,center_point):
return np.sqrt(sum((center_point-data)**2))
2 show
展示部分 有时候plt.show 后分布不均匀 多试几次就行 代码还可以改进
def show_kmeans(center_point,k,df,data_array):
for i in range(df.shape[0]):
color_index=int(data_array[i,0])
mark= ['*r', '*b', '*g', '*k', '^b', '+b', 'sb', 'db', '<b', 'pb']
# print(color_index)取出data_array 里面的第一列值 ————所属簇
plt.plot(df[i,0],df[i,1],mark[color_index])
# plt.show()
for j in range(k):
plt.plot(center_point[j,0],center_point[j,1],mark[j],markersize=20)
plt.show()
show_kmeans(center_point,k,df,data_array)
3.sklearn
掉包就比较简单,也不会出现分布不均匀的情况,sklearn 是个好东西
之后我又对k取3,5,6 发现效果不好 改变n_cluster=k
```python
model=KMeans(n_clusters=k)
model.fit(df)
centers=model.cluster_centers_
print(centers)
result=model.predict(df)
print(result)mark = ['or', 'ob', 'og', 'oy']
for i,d in enumerate(df):
plt.plot(d[0],d[1],mark[result[i]])mark_list = ['*r', '*b', '*g', '*y']
for i,center in enumerate(centers):
plt.plot(center[0],center[1],mark_list[i],markersize=20)
plt.show()