Python机器学习之K-Means聚类实现详解


Posted in Python onFebruary 22, 2018

本文为大家分享了Python机器学习之K-Means聚类的实现代码,供大家参考,具体内容如下

1.K-Means聚类原理

K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。其基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。
算法大致流程为:(1)随机选取k个点作为种子点(这k个点不一定属于数据集);(2)分别计算每个数据点到k个种子点的距离,离哪个种子点最近,就属于哪类;(3)重新计算k个种子点的坐标(简单常用的方法是求坐标值的平均值作为新的坐标值;(4)重复2、3步,直到种子点坐标不变或者循环次数完成。

2.数据及其寻找初步的聚类中心

数据为Matlab加载格式(mat),包含X变量,数据来源为(大家可以去这下载),X为300*2维变量,由于是2维,所以基本上就是在平面坐标轴上的一些点中进行聚类。

我们首先构建初步寻找聚类中心(centroids,质心)函数,再随机设置初始质心,通过欧氏距离初步判断X的每一个变量属于哪个质心。代码为:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sb
from scipy.io import loadmat

def find_closest_centroids(X, centroids):
  m = X.shape[0]
  k = centroids.shape[0] #要聚类的类别个数
  idx = np.zeros(m) 
  
  for i in range(m):
    min_dist = 1000000 #迭代终止条件
    for j in range(k):
      dist = np.sum((X[i,:] - centroids[j,:]) ** 2) 
      if dist < min_dist:
        # 记录当前最短距离和其中心的索引值
        min_dist = dist
        idx[i] = j
  
  return idx
data = loadmat('D:\python\Python ml\ex7data2.mat')
X = data['X']
initial_centroids = np.array([[3, 3], [6, 2], [8, 5]])

idx = find_closest_centroids(X, initial_centroids)
idx[0:3]

在这里先生成m(这里为300)个0向量,即idx,也就是假设X的每个变量均属于0类,然后再根据与初始质心的距离计算dist = np.sum((X[i,:] - centroids[j,:]) ** 2),初步判断每个变量归属哪个类,最终替代idx中的0.

3.不断迭代寻找质心的位置并实现kmeans算法

上述idx得到的300维向量是判断X中每个变量的归属类别,在此基础上,再对初始质心集群位置不断调整,寻找最优质心。

def compute_centroids(X, idx, k):
  m, n = X.shape
  centroids = np.zeros((k, n))
  
  for i in range(k):
    indices = np.where(idx == i)
    centroids[i,:] = (np.sum(X[indices,:], axis=1) / len(indices[0])).ravel()
  #这里简单的将该类中心的所有数值求平均值作为新的类中心
return centroids
compute_centroids(X, idx, 3)

根据上述函数,来构建kmeans函数实现K-means聚类算法。然后根据得到的每个变量归属类别与质心坐标,进行可视化。

def run_k_means(X, initial_centroids, max_iters):
  m, n = X.shape
  k = initial_centroids.shape[0]
  idx = np.zeros(m)
  centroids = initial_centroids
  
  for i in range(max_iters):
    idx = find_closest_centroids(X, centroids)
    centroids = compute_centroids(X, idx, k)
  
  return idx, centroids
idx, centroids = run_k_means(X, initial_centroids, 10)
cluster1 = X[np.where(idx == 0)[0],:] #获取X中属于第一个类别的数据集合,即类别1的点
cluster2 = X[np.where(idx == 1)[0],:]
cluster3 = X[np.where(idx == 2)[0],:]

fig, ax = plt.subplots(figsize=(12,8))
ax.scatter(cluster1[:,0], cluster1[:,1], s=30, color='r', label='Cluster 1')
ax.scatter(cluster2[:,0], cluster2[:,1], s=30, color='g', label='Cluster 2')
ax.scatter(cluster3[:,0], cluster3[:,1], s=30, color='b', label='Cluster 3')
ax.legend()
plt.show()

得到图形如下:

Python机器学习之K-Means聚类实现详解

image.png

4.关于初始化质心的设置

我们前边设置的初始质心:[3, 3], [6, 2], [8, 5],是事先设定的,并由此生成idx(每一变量归属类别的向量),这是后边进行kmeans聚类的基础,实际上对于二维以上数据,由于无法在平面坐标轴展示,很难一开始就设定较好的初始质心,另外,初始质心的设定也可能会影响算法的收敛性。所以需要我们再构造个初始化质心设定函数,来更好地设置初始质心。

def init_centroids(X, k):
  m, n = X.shape
  centroids = np.zeros((k, n)) #初始化零矩阵
  idx = np.random.randint(0, m, k) #返回0-m之间的整数值
  
  for i in range(k):
    centroids[i,:] = X[idx[i],:]
  
return centroids
init_centroids(X, 3)

这里所生成的初始质心位置,其实就是从X的数据中随机找3个变量作为初始值。在此基础上,令initial_centroids = init_centroids(X, 3),然后代入前边的code中,重新运行一遍即可。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现问号表达式(?)的方法
Nov 27 Python
零基础写python爬虫之urllib2中的两个重要概念:Openers和Handlers
Nov 05 Python
Python装饰器的执行过程实例分析
Jun 04 Python
TensorFlow 合并/连接数组的方法
Jul 27 Python
使用Template格式化Python字符串的方法
Jan 22 Python
python读csv文件时指定行为表头或无表头的方法
Jun 26 Python
使用python写的opencv实时监测和解析二维码和条形码
Aug 14 Python
python 中的[:-1]和[::-1]的具体使用
Feb 13 Python
Pytorch损失函数nn.NLLLoss2d()用法说明
Jul 07 Python
python 实现简易的记事本
Nov 30 Python
python 模块重载的五种方法
Apr 24 Python
python库Tsmoothie模块数据平滑化异常点抓取
Jun 10 Python
python实现远程通过网络邮件控制计算机重启或关机
Feb 22 #Python
python实现微信发送邮件关闭电脑功能
Feb 22 #Python
python使用itchat实现手机控制电脑
Feb 22 #Python
Python实现利用163邮箱远程关电脑脚本
Feb 22 #Python
Python3.4实现远程控制电脑开关机
Feb 22 #Python
python实现微信远程控制电脑
Feb 22 #Python
Python标准库笔记struct模块的使用
Feb 22 #Python
You might like
phpMyAdmin 链接表的附加功能尚未激活的问题
2010/08/01 PHP
Yii2框架中日志的使用方法分析
2017/05/22 PHP
显示、隐藏密码
2006/07/01 Javascript
javascript onmouseout 解决办法
2010/07/17 Javascript
js中document.getElementByid、document.all和document.layers区分介绍
2011/12/08 Javascript
Extjs改变树节点的勾选状态点击按钮将复选框去掉
2013/11/14 Javascript
jquery ajax 局部无刷新更新数据的实现案例
2014/02/08 Javascript
让javascript加载速度倍增的方法(解决JS加载速度慢的问题)
2014/12/12 Javascript
利用jQuery和CSS将背景图片拉伸
2015/10/16 Javascript
基于jquery实现全屏滚动效果
2015/11/26 Javascript
jQuery div拖拽用法实例
2016/01/14 Javascript
js精准的倒计时函数分享
2016/06/29 Javascript
jQuery实现的简单拖拽功能示例
2016/09/13 Javascript
js捕捉键盘事件和按键键值的方法
2016/10/10 Javascript
Vue.js创建Calendar日历效果
2016/11/03 Javascript
jQuery实现的仿百度,仿谷歌搜索下拉框效果示例
2016/12/30 Javascript
vueJs实现DOM加载完之后自动下拉到底部的实例代码
2018/08/31 Javascript
JavaScript常见事件对象与操作实例总结
2019/01/05 Javascript
JS实现查找数组中对象的属性值是否存在示例
2019/05/24 Javascript
使用nodeJS中的fs模块对文件及目录进行读写,删除,追加,等操作详解
2020/02/06 NodeJs
sharp.js安装过程中遇到的问题总结
2020/04/02 Javascript
跟老齐学Python之坑爹的字符编码
2014/09/28 Python
Python中使用第三方库xlutils来追加写入Excel文件示例
2015/04/05 Python
利用Python绘制数据的瀑布图的教程
2015/04/07 Python
Python中的各种装饰器详解
2015/04/11 Python
Vue的el-scrollbar实现自定义滚动
2018/05/29 Python
常用python爬虫库介绍与简要说明
2020/01/25 Python
中国领先的专业家电网购平台:国美在线
2016/12/25 全球购物
初中考试作弊检讨书
2014/02/01 职场文书
求职意向书范文
2014/04/01 职场文书
房屋买卖协议书
2014/04/10 职场文书
校园绿化美化方案
2014/06/08 职场文书
农村党建工作汇报材料
2014/10/27 职场文书
企业财务管理制度范本
2015/08/04 职场文书
使用Selenium实现微博爬虫(预登录、展开全文、翻页)
2021/04/13 Python
vue二维数组循环嵌套方式 循环数组、循环嵌套数组
2022/04/24 Vue.js