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定时器使用示例分享
Feb 16 Python
零基础写python爬虫之使用urllib2组件抓取网页内容
Nov 04 Python
常见的在Python中实现单例模式的三种方法
Apr 08 Python
python决策树之C4.5算法详解
Dec 20 Python
python实现共轭梯度法
Jul 03 Python
Pytorch中实现只导入部分模型参数的方式
Jan 02 Python
Django 项目通过加载不同env文件来区分不同环境
Feb 17 Python
使用Python matplotlib作图时,设置横纵坐标轴数值以百分比(%)显示
May 16 Python
PyCharm vs VSCode,作为python开发者,你更倾向哪种IDE呢?
Aug 17 Python
Python requests接口测试实现代码
Sep 08 Python
Pytorch GPU内存占用很高,但是利用率很低如何解决
Jun 01 Python
详解Python flask的前后端交互
Mar 31 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+jQuery实现自动补全功能源码
2013/05/15 PHP
PHP获取表单所有复选框的值的方法
2014/08/28 PHP
php中数组最简单的使用方法
2020/12/27 PHP
prototype 源码中文说明之 prototype.js
2006/09/22 Javascript
调用js时ie6和ie7,ff的区别
2009/08/19 Javascript
jquery tab插件制作实现代码
2010/06/22 Javascript
JavaScript中的property和attribute介绍
2011/12/26 Javascript
JS事件Event元素(兼容IE,Firefox,Chorme)
2012/11/01 Javascript
jquery 追加tr和删除tr示例代码
2013/09/12 Javascript
在Node.js应用中读写Redis数据库的简单方法
2015/06/30 Javascript
js 获取当前web应用的上下文路径实现方法
2016/08/19 Javascript
vue.js 表格分页ajax 异步加载数据
2016/10/18 Javascript
[原创]jQuery实现合并/追加数组并去除重复项的方法
2018/04/11 jQuery
微信小程序常见页面跳转操作简单示例
2019/05/01 Javascript
javascript实现日历效果
2019/06/17 Javascript
ES6 Iterator遍历器原理,应用场景及相关常用知识拓展详解
2020/02/15 Javascript
ReactRouter的实现方法
2021/01/25 Javascript
Python调用C/C++动态链接库的方法详解
2014/07/22 Python
Python本地与全局命名空间用法实例
2015/06/16 Python
python 读写中文json的实例详解
2017/10/29 Python
python实现报表自动化详解
2017/11/16 Python
详解如何设置Python环境变量?
2019/05/13 Python
Python OpenCV 调用摄像头并截图保存功能的实现代码
2019/07/02 Python
python 图像插值 最近邻、双线性、双三次实例
2020/07/05 Python
python中os.remove()用法及注意事项
2021/01/31 Python
HTML如何让IMG自动适应DIV容器大小的实现方法
2020/02/25 HTML / CSS
美国宠物商店:Wag.com
2016/10/25 全球购物
雷蛇美国官网:Razer
2020/04/03 全球购物
护士辞职信模板
2014/01/20 职场文书
《蝙蝠和雷达》教学反思
2014/04/23 职场文书
社区党建工作汇报材料
2014/08/14 职场文书
亚布力滑雪场导游词
2015/02/09 职场文书
自主招生推荐信怎么写
2015/03/26 职场文书
出纳岗位职责范本
2015/03/31 职场文书
交通安全宣传标语(100条)
2019/08/22 职场文书
关于mysql中string和number的转换问题
2022/06/14 MySQL