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笔记(1) 关于我们应不应该继续学习python
Oct 24 Python
python实现域名系统(DNS)正向查询的方法
Apr 19 Python
详解python中executemany和序列的使用方法
Aug 12 Python
Python实现的简单模板引擎功能示例
Sep 02 Python
利用Python将时间或时间间隔转为ISO 8601格式方法示例
Sep 05 Python
python 每天如何定时启动爬虫任务(实现方法分享)
May 21 Python
Python tkinter的grid布局及Text动态显示方法
Oct 11 Python
python爬取网易云音乐评论
Nov 16 Python
Django实现将views.py中的数据传递到前端html页面,并展示
Mar 16 Python
Python+Appium实现自动化测试的使用步骤
Mar 24 Python
python topk()函数求最大和最小值实例
Apr 02 Python
Pytorch使用shuffle打乱数据的操作
May 20 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
Smarty模板快速入门
2007/01/04 PHP
微信支付开发教程(一)微信支付URL配置
2014/05/28 PHP
PHP等比例压缩图片的实例代码
2018/07/26 PHP
PHP实现基于3DES算法加密解密字符串示例
2018/08/24 PHP
PHP使用openssl扩展实现加解密方法示例
2020/02/20 PHP
基于jquery的jqDnR拖拽溢出的修改
2011/02/12 Javascript
调用HttpHanlder的几种返回方式小结
2013/12/20 Javascript
jQuery中val()方法用法实例
2014/12/25 Javascript
Jquery幻灯片特效代码分享--打开页面随机选择切换方式(3)
2015/08/15 Javascript
JS实现黑色大气的二级导航菜单效果
2015/09/18 Javascript
jquery 实现输入邮箱时自动补全下拉提示功能
2015/10/04 Javascript
javascript实现抽奖程序的简单实例
2016/06/07 Javascript
js编写三级联动简单案例
2016/12/21 Javascript
js中document.referrer实现移动端返回上一页
2017/02/22 Javascript
vue实现一个移动端屏蔽滑动的遮罩层实例
2017/06/08 Javascript
javascript获取指定区间范围随机数的方法
2017/09/08 Javascript
vue-cli与webpack处理静态资源的方法及webpack打包的坑
2018/05/15 Javascript
trackingjs+websocket+百度人脸识别API实现人脸签到
2018/11/26 Javascript
详解VUE单页应用骨架屏方案
2019/01/17 Javascript
全面了解Python环境配置及项目建立
2016/06/30 Python
Python实现的选择排序算法示例
2017/11/29 Python
Python实现将字符串的首字母变为大写,其余都变为小写的方法
2019/06/11 Python
Python生态圈图像格式转换问题(推荐)
2019/12/02 Python
Python使用Tkinter实现滚动抽奖器效果
2020/01/06 Python
Python字典深浅拷贝与循环方式方法详解
2020/02/09 Python
简单了解Java Netty Reactor三种线程模型
2020/04/26 Python
Python 使用双重循环打印图形菱形操作
2020/08/09 Python
M1芯片安装python3.9.1的实现
2021/02/02 Python
C和C++经典笔试题附答案解析
2014/08/18 面试题
理工大学毕业生自荐信范文
2014/02/22 职场文书
新兵入伍心得体会
2014/09/04 职场文书
设立有限责任公司出资协议书
2014/11/01 职场文书
2015年调度员工作总结
2015/04/30 职场文书
护士爱岗敬业心得体会
2016/01/25 职场文书
mysql死锁和分库分表问题详解
2021/04/16 MySQL
CSS实现鼠标悬浮动画特效
2023/05/07 HTML / CSS