聚类算法属于无监督学习,其中最常见的是均值聚类,scikit-learn中,有两种常用的均值聚类算法:
一种是有名的K-means(也就是K-均值)聚类算法,这个算法几乎是学习聚类必会提到的算法;
另一个是均值偏移聚类,它与K-means各有千秋,只是针对的应用场景不太一样,但是知名度远不如K-Means。

本篇介绍如何在scikit-learn中使用这两种算法。

1. 算法概述

1.1. K-Means

K-means算法起源于1967年,由James MacQueen和J. B. Hartigan提出。
它的基本原理是是将n个点划分为K个集群,使得每个点都属于离其最近的均值(中心点)对应的集群。

K-Means算法主要包含2个部分:

  1. 距离公式:通常采用欧几里得距离来计算数据点与质心之间的距离

\(d(X_i, C_j) = ||X_i - C_j||^2\) 其中,\(X_i\)是数据点,\(C_j\)是质心。

  1. 目标函数:目标是最小化所有数据点与所属簇的质心之间的距离平方和

\(J = \sum_{j=1}^k \sum_{i=1}^{N_j} ||X_i - C_j||^2\) 其中,\(N_j\)表示第\(j\)个簇中的样本数量。

1.2. 均值漂移

均值漂移算法最早是由Fukunaga等人在1975年提出的。
它的基本原理是对每一个数据点,算法都会估算其周围点的密度梯度,然后沿着密度上升的方向移动该点,直至达到密度峰值。

均值漂移算法主要有3个步骤:

  1. 用核函数估计数据点的密度:常用的核函数比如高斯核,

\(K(x) = \exp(-||x||^2 / (2h^2))\) 其中,\(h\)为带宽参数,控制核的宽度。

  1. 均值漂移向量:也就是对于每个数据点,计算其周围点的密度梯度
  2. 迭代更新:根据均值漂移向量,每个数据点会沿着密度上升的方向移动,更新自己的位置

2. 创建样本数据

利用scikit-learn中的样本生成器,创建一些用于聚类的数据。

import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs X, y = make_blobs(n_samples=1000, centers=5)
plt.scatter(X[:, 0], X[:, 1], marker="o", c=y, s=25) plt.show()


生成了包含5个类别的1000条样本数据。

3. 模型训练

首先,划分训练集和测试集。

from sklearn.model_selection import train_test_split

# 分割训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

按照8:2的比例划分了训练集和测试集。

3.1. K-Means

对于K-Means算法来说,需要指定聚类的数目,通过观察数据,我们指定聚类的数目5。
这里的样本数据比较简单,能够一下看出来,实际情况下并不会如此容易的知道道聚类的数目是多少,
常常需要多次的尝试,才能得到一个比较好的聚类数目,也就是K的值。

基于上面的数据,我们设置5个簇,看看聚类之后的质心在训练集和测试集上的表现。

from sklearn.cluster import KMeans

# 定义
reg = KMeans(n_clusters=5, n_init="auto") # 训练模型
reg.fit(X_train, y_train) # 绘制质心
_, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))
markers = ["x", "o", "^", "s", "*"]
centers = reg.cluster_centers_ axes[0].scatter(X_train[:, 0], X_train[:, 1], marker="o", c=y_train, s=25)
axes[0].set_title("【训练集】的质心位置") axes[1].scatter(X_test[:, 0], X_test[:, 1], marker="o", c=y_test, s=25)
axes[1].set_title("【测试集】的质心位置") for idx, c in enumerate(centers):
axes[0].plot(c[0], c[1], markers[idx], markersize=10)
axes[1].plot(c[0], c[1], markers[idx], markersize=10) plt.show()

3.2. 均值漂移

均值漂移聚类,事先是不用指定聚类的数目的,通过调整它的bandwidth参数,
可以训练出拥有不同数目质心的模型。

下面,设置了bandwidth=5,训练之后得到了拥有3个质心的模型。

from sklearn.cluster import MeanShift

# 定义
reg = MeanShift(cluster_all=False, bandwidth=5) # 训练模型
reg.fit(X, y) # 绘制质心
_, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))
markers = ["x", "o", "^", "s", "*"]
centers = reg.cluster_centers_
print(len(centers)) axes[0].scatter(X_train[:, 0], X_train[:, 1], marker="o", c=y_train, s=25)
axes[0].set_title("【训练集】的质心位置") axes[1].scatter(X_test[:, 0], X_test[:, 1], marker="o", c=y_test, s=25)
axes[1].set_title("【测试集】的质心位置") for idx, c in enumerate(centers):
axes[0].plot(c[0], c[1], markers[idx], markersize=10)
axes[1].plot(c[0], c[1], markers[idx], markersize=10) plt.show()


它把左下角的3类比较接近的样本数据点算作一类。
通过调整 bandwidth参数,也可以得到和 K-Means 一样的结果,
有兴趣的话可以试试,大概设置 bandwidth=2 左右的时候,可以得到5个质心,与上面的K-Means算法的结果类似。

4. 总结

K-Means和均值漂移聚类都是强大的聚类工具,各有其优缺点。

K-Means 的优势是简单、快速且易于实现,当数据集是密集的,且类别之间有明显的分离时,效果非常好;
不过,它需要预先设定簇的数量k,且对初始质心的选择敏感,所以,对于不是凸形状或者大小差别很大的簇,效果并不好。

而均值漂移聚类的优势在于不需要预先知道簇的数量,可以自适应地找到数据的“模式”,对噪声和异常值也有很好的鲁棒性。
不过,与K-Means相比,它需要选择合适的带宽参数,对高维数据可能不太有效,且计算复杂度较高。

最后,对于这两种均值聚类算法来说,选择哪种取决于数据的性质和应用的需求。

【scikit-learn基础】--『监督学习』之 均值聚类的更多相关文章

  1. Python基础『一』

    内置数据类型 数据名称 例子 数字: Bool,Complex,Float,Integer True/False; z=a+bj; 1.23; 123 字符串: String '123456' 元组: ...

  2. Python基础『二』

    目录 语句,表达式 赋值语句 打印语句 分支语句 循环语句 函数 函数的作用 函数的三要素 函数定义 DEF语句 RETURN语句 函数调用 作用域 闭包 递归函数 匿名函数 迭代 语句,表达式 赋值 ...

  3. K均值聚类算法

    k均值聚类算法(k-means clustering algorithm)是一种迭代求解的聚类分析算法,其步骤是随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个 ...

  4. 『cs231n』计算机视觉基础

    线性分类器损失函数明细: 『cs231n』线性分类器损失函数 最优化Optimiz部分代码: 1.随机搜索 bestloss = float('inf') # 无穷大 for num in range ...

  5. Scikit Learn: 在python中机器学习

    转自:http://my.oschina.net/u/175377/blog/84420#OSC_h2_23 Scikit Learn: 在python中机器学习 Warning 警告:有些没能理解的 ...

  6. 『TensorFlow』批处理类

    『教程』Batch Normalization 层介绍 基础知识 下面有莫凡的对于批处理的解释: fc_mean,fc_var = tf.nn.moments( Wx_plus_b, axes=[0] ...

  7. [原创] 【2014.12.02更新网盘链接】基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装

    [原创] [2014.12.02更新网盘链接]基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装 joinlidong 发表于 2014-11-29 14:25:50 ...

  8. (原创)(三)机器学习笔记之Scikit Learn的线性回归模型初探

    一.Scikit Learn中使用estimator三部曲 1. 构造estimator 2. 训练模型:fit 3. 利用模型进行预测:predict 二.模型评价 模型训练好后,度量模型拟合效果的 ...

  9. 『TensorFlow』专题汇总

    TensorFlow:官方文档 TensorFlow:项目地址 本篇列出文章对于全零新手不太合适,可以尝试TensorFlow入门系列博客,搭配其他资料进行学习. Keras使用tf.Session训 ...

  10. 『TensorFlow』梯度优化相关

    tf.trainable_variables可以得到整个模型中所有trainable=True的Variable,也是自由处理梯度的基础 基础梯度操作方法: tf.gradients 用来计算导数.该 ...

随机推荐

  1. Python面试——基础面试题

    文章目录 1.Python 和 Java.PHP.C.C#.C++等其他语言的对比? C语言既有高级语言的特点,又具有汇编语言的特点,它是结构式语言.C语言应用指针:可以直接进行靠近硬件的操作,但是C ...

  2. 研发三维GIS系统笔记/框架改造/智能指针重构框架-003

    1. 使用智能指针重构系统 原有的系统都是裸指针,在跨模块与多线程中使用裸指针管理起来很麻烦,尤其是多任务系统中会出现野指针 1 class CELLTileTask :public CELLTask ...

  3. 漏洞扫描与安全加固之Apache Axis组件

    一.Apache Axis组件高危漏洞自查及整改 Apache Axis组件存在由配置不当导致的远程代码执行风险. 1. 影响版本 Axis1 和Axis2各版本均受影响 2. 处置建议 1)禁用此服 ...

  4. Java面向对象编程的三大特性:封装、继承、多态。

    一.封装 封装的核心在于私有化(private),大部分情况下,来封装对象的属性,很少有封装方法的.通过将对象的属性封装,提供对外的公共方法来访问属性是最常见的方式. public static cl ...

  5. 【源码解读(一)】EFCORE源码解读之创建DBContext查询拦截

    引言 在网上很少看到有关于系统讲解EFCore源码的,可能大概也许是因为EFCore的源码总体是没有asp.net web的源码流程清晰,正如群友所说,EFCore的源码大致看起来有点凌乱,与其说凌乱 ...

  6. Java开发面试--群面专区

    目录 一.群面背景 二.群面流程 三.群面角色 四.群面细节 五.群面礼仪 六.群面话术 七.个人演讲 八.群面题型 群面也称无领导小组~ 候选人们被要求在一个相对自由的环境中展示他们的能力,并在没有 ...

  7. 使用JNA读取dll文件

    由于项目需要进行读卡操作,需要使用java进行读取dll文件 设备:德卡T10 1. 引入POM文件 <dependency> <groupId>net.java.dev.jn ...

  8. Redis常用命令-实战篇

    目录 写在前面 连接操作命令 持久化 远程服务控制 对value操作的命令 操作字符串String命令 List Set Hash 写在前面 java 操作 redis 太常见了,基本上有需要的系统, ...

  9. Python 用户输入和字符串格式化指南

    Python 允许用户输入数据.这意味着我们可以向用户询问输入.在 Python 3.6 中,使用 input() 方法来获取用户输入.在 Python 2.7 中,使用 raw_input() 方法 ...

  10. Electron原生菜单

    .markdown-body { color: rgba(56, 56, 56, 1); font-size: 15px; line-height: 30px; letter-spacing: 2px ...