python 代码实现k-means聚类分析的思路(不使用现成聚类库)


Posted in Python onJune 01, 2020

一、实验目标

1、使用 K-means 模型进行聚类,尝试使用不同的类别个数 K,并分析聚类结果。

2、按照 8:2 的比例随机将数据划分为训练集和测试集,至少尝试 3 个不同的 K 值,并画出不同 K 下 的聚类结果,及不同模型在训练集和测试集上的损失。对结果进行讨论,发现能解释数据的最好的 K 值。二、算法原理

首先确定k,随机选择k个初始点之后所有点根据距离质点的距离进行聚类分析,离某一个质点a相较于其他质点最近的点分配到a的类中,根据每一类mean值更新迭代聚类中心,在迭代完成后分别计算训 练集和测试集的损失函数SSE_train、SSE_test,画图进行分析。

python 代码实现k-means聚类分析的思路(不使用现成聚类库)

伪代码如下:

num=10 #k的种类
for k in range(1,num):
 随机选择k个质点
 for i in range(n): #迭代n次
 根据点与质点间的距离对于X_train进行聚类
 根据mean值迭代更新质点
 计算SSE_train
 计算SSE_test
画图

 算法流程图:

python 代码实现k-means聚类分析的思路(不使用现成聚类库)

三、代码实现

1、导入库

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split

2、计算距离

def distance(p1,p2):
 return np.sqrt((p1[0]-p2[0])**2+(p1[1]-p2[1])**2)

3、计算均值

def means(arr):
 return np.array([np.mean([p[0] for p in arr]),np.mean([p[1] for p in arr])])

4、二维数据处理

#数据处理
data= pd.read_table('cluster.dat',sep='\t',header=None) 
data.columns=['x']
data['y']=None
for i in range(len(data)): #遍历每一行 
 column = data['x'][i].split( ) #分开第i行,x列的数据。split()默认是以空格等符号来分割,返回一个列表 
 data['x'][i]=column[0] #分割形成的列表第一个数据给x列 
 data['y'][i]=column[1] #分割形成的列表第二个数据给y列
list=[]
list1=[]
for i in range(len(data)):
 list.append(float(data['x'][i]))
 list.append(float(data['y'][i]))
 list1.append(list)
 list=[]
arr=np.array(list1)
print(arr)

python 代码实现k-means聚类分析的思路(不使用现成聚类库)

5、划分数据集和训练集

#按照8:2划分数据集和训练集
X_train, X_test = train_test_split(arr,test_size=0.2,random_state=1)

6、主要聚类实现

count=10 #k的种类:1、2、3...10
SSE_train=[] #训练集的SSE
SSE_test=[] #测试集的SSE
n=20 #迭代次数
for k in range(1,count):
 cla_arr=[] #聚类容器
 centroid=[] #质点
 for i in range(k):
 j=np.random.randint(0,len(X_train))
 centroid.append(list1[j])
 cla_arr.append([])
 centroids=np.array(centroid) 
 cla_tmp=cla_arr #临时训练集聚类容器
 cla_tmp1=cla_arr #临时测试集聚类容器
 for i in range(n): #开始迭代
 for e in X_train: #对于训练集中的点进行聚类分析
 pi=0
 min_d=distance(e,centroids[pi]) 
 for j in range(k):
 if(distance(e,centroids[j])<min_d): 
  min_d=distance(e,centroids[j])
  pi=j
 cla_tmp[pi].append(e) #添加点到相应的聚类容器中
 
 for m in range(k):
 if(n-1==i):
 break
 centroids[m]=means(cla_tmp[m])#迭代更新聚类中心
 cla_tmp[m]=[]
 dis=0
 for i in range(k):  #计算训练集的SSE_train
 for j in range(len(cla_tmp[i])):
 dis+=distance(centroids[i],cla_tmp[i][j])
 SSE_train.append(dis)
 
 col = ['HotPink','Aqua','Chartreuse','yellow','red','blue','green','grey','orange'] #画出对应K的散点图
 for i in range(k):
 plt.scatter([e[0] for e in cla_tmp[i]],[e[1] for e in cla_tmp[i]],color=col[i])
 plt.scatter(centroids[i][0],centroids[i][1],linewidth=3,s=300,marker='+',color='black')
 plt.show()
 
 for e in X_test:  #测试集根据训练集的质点进行聚类分析
 ki=0
 min_d=distance(e,centroids[ki])
 for j in range(k):
 if(distance(e,centroids[j])<min_d):
 min_d=distance(e,centroids[j])
 ki=j
 cla_tmp1[ki].append(e)
 for i in range(k):  #计算测试集的SSE_test
 for j in range(len(cla_tmp1[i])):
 dis+=distance(centroids[i],cla_tmp1[i][j])
 SSE_test.append(dis)

python 代码实现k-means聚类分析的思路(不使用现成聚类库)

7、画图

SSE=[] #计算测试集与训练集SSE的差值
for i in range(len(SSE_test)):
 SSE.append(SSE_test[i]-SSE_train[i])

x=[1,2,3,4,5,6,7,8,9]
plt.figure()
plt.plot(x,SSE_train,marker='*')
plt.xlabel("K")
plt.ylabel("SSE_train")
plt.show() #画出SSE_train的图

plt.figure()
plt.plot(x,SSE_test,marker='*')
plt.xlabel("K")
plt.ylabel("SSE_test")
plt.show() #画出SSE_test的图

plt.figure()
plt.plot(x,SSE,marker='+')
plt.xlabel("K")
plt.ylabel("SSE_test-SSE_train")
plt.show() #画出SSE_test-SSE_train的图

python 代码实现k-means聚类分析的思路(不使用现成聚类库)

python 代码实现k-means聚类分析的思路(不使用现成聚类库)

四、实验结果分析

可以看出SSE随着K的增长而减小,测试集和训练集的图形趋势几乎一致,在相同的K值下,测试集的SSE大于训练集的SSE。于是我对于在相同的K值下的SSE_test和SSE_train做了减法(上图3),可知K=4时数据得出结果最好。这里我主要使用肘部原则来判断。本篇并未实现轮廓系数,参考文章:https://3water.com/article/187771.htm

总结

到此这篇关于python 代码实现k-means聚类分析(不使用现成聚类库)的文章就介绍到这了,更多相关python k-means聚类分析内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python简单程序读取串口信息的方法
Mar 13 Python
Python2.x中文乱码问题解决方法
Jun 02 Python
浅析PHP与Python进行数据交互
May 15 Python
对Python中实现两个数的值交换的集中方法详解
Jan 11 Python
python使用PIL实现多张图片垂直合并
Jan 15 Python
python重试装饰器的简单实现方法
Jan 31 Python
在Python中如何传递任意数量的实参的示例代码
Mar 21 Python
Python HTML解析模块HTMLParser用法分析【爬虫工具】
Apr 05 Python
通过python连接Linux命令行代码实例
Feb 18 Python
python实现人脸签到系统
Apr 13 Python
next在python中返回迭代器的实例方法
Dec 15 Python
Python 生成短8位唯一id实战教程
Jan 13 Python
python如何写出表白程序
Jun 01 #Python
python中os包的用法
Jun 01 #Python
python保留格式汇总各部门excel内容的实现思路
Jun 01 #Python
Python如何使用正则表达式爬取京东商品信息
Jun 01 #Python
浅谈pycharm导入pandas包遇到的问题及解决
Jun 01 #Python
python实现密码验证合格程序的思路详解
Jun 01 #Python
Python网络爬虫四大选择器用法原理总结
Jun 01 #Python
You might like
怎样给PHP源代码加密?PHP二进制加密与解密的解决办法
2013/04/22 PHP
PHP APC配置文件2套和参数详解
2014/06/11 PHP
php计算两个坐标(经度,纬度)之间距离的方法
2015/04/17 PHP
PHP实现的抓取小说网站内容功能示例
2019/06/27 PHP
取得传值的函数
2006/10/27 Javascript
JavaScript Memoization 让函数也有记忆功能
2011/10/27 Javascript
JQuery中DOM事件冒泡实例分析
2015/06/13 Javascript
jQuery简单实现彩色云标签效果示例
2016/08/01 Javascript
深入浅析JS是按值传递还是按引用传递(推荐)
2016/09/18 Javascript
Bootstrap table两种分页示例
2016/12/23 Javascript
angular ng-repeat数组中的数组实例
2017/02/18 Javascript
详解axios在node.js中的post使用
2017/04/27 Javascript
JS组件系列之MVVM组件 vue 30分钟搞定前端增删改查
2017/04/28 Javascript
jQuery实现select下拉框获取当前选中文本、值、索引
2017/05/08 jQuery
vue实现百度搜索下拉提示功能实例
2017/06/14 Javascript
vue获取DOM元素并设置属性的两种实现方法
2017/09/30 Javascript
jQuery实现点击DIV同时点击CheckBox,并为DIV上背景色的实例
2017/12/18 jQuery
JavaScript判断变量名是否存在数组中的实例
2017/12/28 Javascript
解决layui table表单提示数据接口请求异常的问题
2019/09/24 Javascript
探究Python多进程编程下线程之间变量的共享问题
2015/05/05 Python
简单学习Python time模块
2016/04/29 Python
Python计时相关操作详解【time,datetime】
2017/05/26 Python
Python语言描述最大连续子序列和
2017/12/05 Python
使用Python+selenium实现第一个自动化测试脚本
2020/03/17 Python
浅谈html5增强的页面元素
2016/06/14 HTML / CSS
Hunter Boots美国官方网站:赫特威灵顿雨靴
2018/06/16 全球购物
网络教育毕业生自我鉴定
2013/10/10 职场文书
教师找工作推荐信
2013/11/23 职场文书
会计岗位职责范本
2014/03/07 职场文书
政府绩效管理实施方案
2014/05/04 职场文书
五月的鲜花活动方案
2014/08/21 职场文书
社区综治工作汇报
2014/10/27 职场文书
居委会工作总结2015
2015/05/18 职场文书
css3实现背景图片半透明内容不透明的方法示例
2021/04/13 HTML / CSS
用基于python的appium爬取b站直播消费记录
2021/04/17 Python
Python如何导出导入所有依赖包详解
2021/06/08 Python