K-Means算法基本实现

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()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值