参考自:

  • 《机器学习》
  • 机器学习&数据挖掘笔记_16(常见面试之机器学习算法思想简单梳理)
  • K-Means Clustering
  • 斯坦福大学公开课 :机器学习课程

简介

K-均值是最普及的聚类算法,算法接受一个未标记的数据集,然后将数据集聚类成不同的组。

K-均值是一个迭代算法,假设我们想要将数据聚类成n个组,其方法为:

  1. 首先选择K个随机的点,称其为聚类中心
  2. 对于数据集中的每一个数据,按照距离K个中心点的距离,将其与距离最近的中心点关联起来,与同一个中心点关联的所有点聚成一个类
  3. 计算每一个组的平均值,将该组所关联的中心点移动到平均值的位置
  4. 重复步骤2-3,直到中心点不再变化

这个过程中分两个主要步骤,第一个就是第二步,将训练集中的样本点根据其与聚类中心的距离,分配到距离最近的聚类中心处,接着第二个就是第三步,更新类中心,做法是计算每个类的所有样本的平均值,然后将这个平均值作为新的类中心值,接着继续这两个步骤,直到达到终止条件,一般是指达到设定好的迭代次数。

当然在这个过程中可能遇到有聚类中心是没有分配数据点给它的,通常的一个做法是删除这种聚类中心,或者是重新选择聚类中心,保证聚类中心数还是初始设定的K个

优化目标

K-均值最小化问题,就是最小化所有的数据点与其所关联的聚类中心之间的距离之和,因此K-均值的代价函数(又称为畸变函数)为:

J(c(1),c(2),…,c(m),μ1,μ2,…,μm)=1m∑mi=1||x(i)−μc(i)||2

J(c^{(1)},c^{(2)},…,c^{(m)},μ_1,μ_2,…,μ_m)=\frac{1}{m}∑_{i=1}^m||x^(i)−μ_{c^(i)}||^2
其中 μc(i)\mu_{c^{(i)}}代表与 x(i)x^{(i)}最近的聚类中心点。

所以我们的优化目标是找出是的代价函数最小的和c(1),c(2),…,c(m)和μ1,μ2,…,μm和c^{(1)},c^{(2)},\ldots,c^{(m)}和\mu_1,\mu_2,\ldots,\mu_m:

minc(1),c(2),…,c(m),μ1,μ2,…,μmJ(c(1),c(2),…,c(m),μ1,μ2,…,μm)

min_{c^{(1)},c^{(2)},\ldots,c^{(m)}, \mu_1,\mu_2,\ldots,\mu_m}J(c^{(1)},c^{(2)},\ldots,c^{(m)},\mu_1,\mu_2,\ldots,\mu_m)
回顾K-均值迭代算法的过程可知,第一个循环就是用于减小 c(i)c^{(i)}引起的代价,而第二个循环则是用于减小 μiμ_i引起的代价,因此, 迭代的过程一定会是每一次迭代都在减小代价函数,不然便是出现了错误。

随机初始化

在运行K-均值算法之前,首先需要随机初始化所有的聚类中心点,做法如下:

  1. 首先应该选择K<mK,即聚类中心点的个数要小于所有训练集实例的数量
  2. 随机选择KK个训练实例,然后令KK个聚类中心分别于这K个训练实例相等

K-均值的一个问题在于,它有可能会停留在一个局部最小值处,而这取决于初始化的情况。

为了解决这个问题,通常需要多次运行K-均值算法,每一次都重新进行随机初始化,最后再比较多次运行K-均值的结果,选择代价函数最小的结果。这种方法在K较小(2-10)的时候还是可行的,但是如果K较大,这种做法可能不会有明显地改善。

优缺点

优点

  1. k-means算法是解决聚类问题的一种经典算法,算法简单、快速
  2. 对处理大数据集,该算法是相对可伸缩的和高效率的,因为它的复杂度大约是O(nkt)O(nkt),其中nn是所有对象的数目,kk是簇的数目,tt是迭代的次数。通常k<<nk。这个算法通常局部收敛
  3. 算法尝试找出使平方误差函数值最小的k个划分。当簇是密集的、球状或团状的,且簇与簇之间区别明显时,聚类效果较好。

缺点

  1. k-平均方法只有在簇的平均值被定义的情况下才能使用,且对有些分类属性的数据不适合。
  2. 要求用户必须事先给出要生成的簇的数目k<script type="math/tex" id="MathJax-Element-16">k</script>。
  3. 对初值敏感,对于不同的初始值,可能会导致不同的聚类结果。
  4. 不适合于发现非凸面形状的簇,或者大小差别很大的簇
  5. 对于“噪声”和孤立点数据敏感,少量的该类数据能够对平均值产生极大影响。

代码实现

代码参考自K-Means Clustering。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time    : 2016/10/21 16:35
@Author  : cai实现 K-Means 聚类算法
"""import numpy as np
import matplotlib.pyplot as plt
from scipy.io import loadmat
import os# 寻址最近的中心点
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 = 1000000for j in range(k):# 计算每个训练样本和中心点的距离dist = np.sum((X[i, :] - centroids[j, :]) ** 2)if dist < min_dist:# 记录当前最短距离和其中心的索引值min_dist = distidx[i] = jreturn idx# 计算聚类中心
def compute_centroids(X, idx, k):m, n = X.shapecentroids = 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# 初始化聚类中心
def init_centroids(X, k):m, n = X.shapecentroids = np.zeros((k, n))# 随机初始化 k 个 [0,m]的整数idx = np.random.randint(0, m, k)for i in range(k):centroids[i, :] = X[idx[i], :]return centroids# 实现 kmeans 算法
def run_k_means(X, initial_centroids, max_iters):m, n = X.shape# 聚类中心的数目k = initial_centroids.shape[0]idx = np.zeros(m)centroids = initial_centroidsfor i in range(max_iters):idx = find_closest_centroids(X, centroids)centroids = compute_centroids(X, idx, k)return idx, centroidsdataPath = os.path.join('data', 'ex7data2.mat')
data = loadmat(dataPath)
X = data['X']initial_centroids = init_centroids(X, 3)
# print(initial_centroids)
# idx = find_closest_centroids(X, initial_centroids)
# print(idx)# print(compute_centroids(X, idx, 3))idx, centroids = run_k_means(X, initial_centroids, 10)
# 可视化聚类结果
cluster1 = X[np.where(idx == 0)[0], :]
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()# 载入一张测试图片,进行测试
imageDataPath = os.path.join('data', 'bird_small.mat')
image = loadmat(imageDataPath)
# print(image)A = image['A']
print(A.shape)# 对图片进行归一化
A = A / 255.# 重新调整数组的尺寸
X = np.reshape(A, (A.shape[0] * A.shape[1], A.shape[2]))
# 随机初始化聚类中心
initial_centroids = init_centroids(X, 16)
# 运行聚类算法
idx, centroids = run_k_means(X, initial_centroids, 10)# 得到最后一次的最近中心点
idx = find_closest_centroids(X, centroids)
# map each pixel to the centroid value
X_recovered = centroids[idx.astype(int), :]
# reshape to the original dimensions
X_recovered = np.reshape(X_recovered, (A.shape[0], A.shape[1], A.shape[2]))# plt.imshow(X_recovered)
# plt.show()

完整代码例子和数据可以查看Kmeans练习代码。

机器学习算法总结--K均值算法相关推荐

  1. k均值算法 二分k均值算法_如何获得K均值算法面试问题

    k均值算法 二分k均值算法 数据科学访谈 (Data Science Interviews) KMeans is one of the most common and important cluste ...

  2. k均值算法 二分k均值算法_使用K均值对加勒比珊瑚礁进行分类

    k均值算法 二分k均值算法 Have you ever seen a Caribbean reef? Well if you haven't, prepare yourself. 您见过加勒比礁吗? ...

  3. 数据挖掘--“聚类”详解、K-means、K-平均值算法、K均值算法

    一. 什么是聚类 二. 聚类步骤 三. 聚类算法有哪些 1 层次聚类算法 2 划分聚类算法 3 基于密度的聚类算法 4 基于网格的聚类算法 5 基于模型的聚类算法 一. 什么是聚类? 物以类聚,人以群 ...

  4. 5 模式识别-动态聚类算法(K均值算法、迭代自组织的数据分析ISOData算法)

    武汉理工大学资源 郭志强 动态聚类算法:先选取初始的中心(每个类别的初始中心),然后把所有的样本进行聚类分析,聚类完成后,就去判断这个聚类结果合不合理(满不满足设计指标要求),如果合理就输出聚类结果( ...

  5. K均值算法【K-means】

    一.K-Means算法流程 K均值算法是学习无监督学习的第一个算法,这个算法理解和实现都比较简单,算法的目的是将数据分成K组. 为了达到这个目的,算法首先随机初始化k个数据点(聚类中心),然后遍历所有 ...

  6. 基于改进人工蜂群算法的K均值聚类算法(附MATLAB版源代码)

    其实一直以来也没有准备在园子里发这样的文章,相对来说,算法改进放在园子里还是会稍稍显得格格不入.但是最近邮箱收到的几封邮件让我觉得有必要通过我的博客把过去做过的东西分享出去更给更多需要的人.从论文刊登 ...

  7. k均值算法python实现(吴恩达机器学习作业)

    k均值算法python实现(吴恩达机器学习作业) 题目要求 数据集 读取mat文件 K-means 实现 结果 问题 题目要求 采用K均值算法对样本进行聚类. 编写K均值算法源代码,对ex7data2 ...

  8. 机器学习实战-61:K均值聚类算法(K-Means)

    K均值聚类算法(K-Means) 深度学习原理与实践(开源图书)-总目录,建议收藏,告别碎片阅读! 机器学习分为监督学习.无监督学习和半监督学习(强化学习).无监督学习最常应用的场景是聚类(clust ...

  9. 百面机器学习—7.K均值算法、EM算法与高斯混合模型要点总结

    文章目录 一.总结K均值算法步骤 二.如何合理选择K值? 三.K均值算法的优缺点是什么? 四.如何对K均值算法进行调优? 五.EM算法解决什么问题? 六.EM算法流程是什么? 六.EM算法能保证收敛嘛 ...

最新文章

  1. 人造神经元计算速度超过人脑
  2. lnmp集成开发环境安装pdo_dblib扩展
  3. UA OPTI512R 傅立叶光学导论14 Wiener-Khinchine定理,Rayleigh定理与矩定理
  4. 致正煎熬的科研人:一个工具让你快速“KO”学术文献!
  5. C++提取PDF页成BMP图片
  6. java的安装和配置
  7. Java try catch语句详解
  8. 爬虫-访问登陆可见的页面-利用session类-补实例
  9. CRF(条件随机场) 学习总结
  10. 华为全面启航计算战略:“鲲鹏+昇腾”双引擎
  11. Python风格总结:错误和异常
  12. PHP中cURL的curl_getinfo函数返回的CURLINFO_HTTP_CODE是0
  13. 汽车零部件开发工具OSEK NM协议栈源代码及配置功能
  14. Poco库使用:单元测试
  15. 无线基础知识学习(一)
  16. 邮储社招Java笔试题_2019年及历年中国邮政储蓄银行社招笔试题和参考答案6套
  17. 通过Hyper-V的方式快速安装Linux虚拟机
  18. Java实战 SpringBoot 网站开发 留言管理、网站后台留言管理模块、后台网站用户运营数据管理开发。
  19. 技术、产业、人才三管齐下,数字人民币渐行渐近 | 产业区块链发展周报
  20. 这个“安装macOS High sierra”应用程序副本已损坏,不能用来安装macOS

热门文章

  1. java.util.set cannot be assigned from null_Java中有关Null的9件事
  2. python控制灯_Python 控制树莓派 GPIO 输出:控制 LED 灯
  3. php中perl配置,Windows下 Apache、PHP和Perl的安装配置
  4. android程序名称,Android应用程序名称带上标
  5. 如何让body背景图自适应浏览器窗口大小
  6. 【树莓派学习笔记】六、启用摄像头、实时视频、录像和截图
  7. Makefile中 变量赋值含义
  8. char[]:strlen和sizeof的区别
  9. 前端学习(3310):redux的state hook对象
  10. javascript学习系列(5):数组中的reduce方法