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 MD5文件生成码
Jan 12 Python
理解Python中函数的参数
Apr 27 Python
python正则表达式之作业计算器
Mar 18 Python
Python中函数参数设置及使用的学习笔记
May 03 Python
python re模块的高级用法详解
Jun 06 Python
python训练数据时打乱训练数据与标签的两种方法小结
Nov 08 Python
Python之使用adb shell命令启动应用的方法详解
Jan 07 Python
pandas去重复行并分类汇总的实现方法
Jan 29 Python
python中通过selenium简单操作及元素定位知识点总结
Sep 10 Python
Django对接支付宝实现支付宝充值金币功能示例
Dec 17 Python
基于numpy中的expand_dims函数用法
Dec 18 Python
Python如何截图保存的三种方法(小结)
Sep 01 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
Opcache导致php-fpm崩溃nginx返回502
2015/03/02 PHP
PHP中trait使用方法详细介绍
2017/05/21 PHP
php下的原生ajax请求用法实例分析
2020/02/28 PHP
在JavaScript并非所有的一切都是对象
2013/04/11 Javascript
js获取系统的根路径实现介绍
2013/09/08 Javascript
jquery属性选择器not has怎么写 行悬停高亮显示
2013/11/13 Javascript
jQuery防止click双击多次提交及传递动态函数或多参数
2014/04/02 Javascript
js的参数有长度限制吗?发现不能超过2083个字符
2014/04/20 Javascript
js实现(全选)多选按钮的方法【附实例】
2016/03/30 Javascript
纯JS焦点图特效实例(可一个页面多用)
2016/12/07 Javascript
IntersectionObserver API 详解篇
2016/12/11 Javascript
Angular 4.x中表单Reactive Forms详解
2017/04/25 Javascript
微信小程序 自动登陆PHP源码实例(源码下载)
2017/05/08 Javascript
JS实现简单的选择题测评系统代码思路详解(demo)
2017/09/03 Javascript
Vue2.0用户权限控制解决方案
2017/11/29 Javascript
详解html-webpack-plugin用法全解
2018/01/22 Javascript
vue实现图片预览组件封装与使用
2019/07/13 Javascript
vue祖孙组件之间的数据传递案例
2020/12/07 Vue.js
[51:32]Optic vs Serenity 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
python登录QQ邮箱发信的实现代码
2013/02/10 Python
python使用pymysql实现操作mysql
2016/09/13 Python
python广度优先搜索得到两点间最短路径
2019/01/17 Python
Python OpenCV中的resize()函数的使用
2019/06/20 Python
keras中epoch,batch,loss,val_loss用法说明
2020/07/02 Python
python pip如何手动安装二进制包
2020/09/30 Python
Python json解析库jsonpath原理及使用示例
2020/11/25 Python
将HTML5 Canvas的内容保存为图片借助toDataURL实现
2013/05/20 HTML / CSS
Artist Guitars新西兰:乐器在线商店
2017/09/17 全球购物
美国机场停车位预订:About Airport Parking
2018/03/26 全球购物
好莱坞百老汇御用王牌美妆:Koh Gen Do 江原道
2018/04/03 全球购物
美国亚洲时尚和美容产品的一站式网上商店:Stylevana
2019/09/05 全球购物
财务经理岗位职责
2013/11/09 职场文书
购房委托书范本
2014/09/18 职场文书
行政上诉状范文
2015/05/23 职场文书
浅谈Python数学建模之固定费用问题
2021/06/23 Python
我家女友可不止可爱呢 公开OP主题曲无字幕动画MV
2022/04/11 日漫