机器学习系列 - Mean Shift聚类

文章目录

    • 前言
    • 一、原理
      • 前置知识点
      • Mean Shift计算步骤
    • 二、应用举例-图像分割
    • 三、聚类实战-简单实例
    • bandwidth=1
    • bandwidth=2
    • 总结

前言

Mean Shift(均值漂移)是基于密度的非参数聚类算法,其算法思想是假设不同簇类的数据集符合不同的概率密度分布,找到任一样本点密度增大的最快方向(最快方向的含义就是Mean Shift),样本密度高的区域对应于该分布的最大值,这些样本点最终会在局部密度最大值收敛,且收敛到相同局部最大值的点被认为是同一簇类的成员。

Mean Shift在计算机视觉领域的应用非常广,如图像分割,聚类和视频跟踪等。

一、原理

前置知识点

  • 核密度估计: Mean-shift的核心思想是通过估计数据点分布的概率密度函数来发现数据集的聚类结构。它使用核函数(通常是高斯核函数)来对每个数据点的周围区域进行加权,得到一个局部密度估计。

对于每一个数据点 x i x_i xi,其邻域内点密度计算公式如下:
在这里插入图片描述
其中,K是高斯核函数,h是带宽参数,n是数据集的大小,d是数据点的维数

下图是一维数据集的核概率密度,其中虚线表示每个样本的核函数,实线是每个样本的核函数进行叠加,表示数据集的概率密度。该数据集的概率密度只有一个局部最大值,因此,此时mean shift算法的簇类个数是1。
在这里插入图片描述

  • 梯度上升: 在密度估计的基础上,Mean-shift算法通过对密度梯度进行上升来寻找数据点的模态或聚类中心。梯度上升的过程可看作在概率密度函数表面上向着密度增长最快的方向移动。

ps:
数据集密度函数如下:
在这里插入图片描述
对数据集密度函数求导:
在这里插入图片描述
其中, g ( s ) = − k ′ ( s ) g(s)=-k'(s) g(s)=k(s)

  • 迭代过程: 算法通过不断迭代的方式更新每个数据点的位置,直到收敛到一个局部极值点。具体而言,对于每个数据点,通过计算其周围区域内的梯度方向,将点沿梯度方向移动一定的步长。这个步长通常由算法自适应确定。

ps:
公式(2)的第一项为实数值,因此第二项的向量方向与梯度方向一致,得到均值漂移向量(均值漂移向量所指的方向是密度增加最大的方向):
在这里插入图片描述

  • 收敛条件: 迭代过程的收敛条件通常是梯度变为零或变得足够小。当梯度接近零时,说明数据点已经移动到密度估计的峰值位置,此时算法认为达到了聚类中心。

  • 聚类结果: 最终,所有数据点都会收敛到密度估计的峰值位置,形成聚类。如果多个数据点收敛到相同的峰值,它们被认为属于同一个聚类。

Mean Shift计算步骤

  • (1)计算每个样本的均值漂移向量: m h ( x i ) m_h(x_i) mh(xi)
  • (2)对每个样本进行平移: x i = x i + m h ( x i ) x_i=x_i+m_h(x_i) xi=xi+mh(xi)
  • (3)重复步骤(1)(2),直到样本点收敛,即 m h ( x i ) = 0 m_h(x_i)=0 mh(xi)=0
  • (4)收敛到相同点的样本被认为是同一簇类的成员

二、应用举例-图像分割

对下图进行图像分割
在这里插入图片描述
将数据映射到RGB三维空间:
在这里插入图片描述
运行mean shift算法,使用带宽为25的高斯核,下图展示了每个样本收敛到局部最大核密度的过程:
请添加图片描述
每个样本点最终会移动到核概率密度的峰值,移动到相同峰值的样本点属于同一种颜色,图像分割结果如下图所示:

在这里插入图片描述

三、聚类实战-简单实例

from sklearn.cluster import MeanShift
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt# 生成模拟数据
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=1.0, random_state=42)# 创建Mean Shift模型并拟合数据
bandwidth = 1  # 设置带宽,需要根据数据特点调整
bin_seeding = True  # 是否使用直方图种子来初始化均值漂移,它可以加快收敛速度,默认True
ms = MeanShift(bandwidth=bandwidth, bin_seeding=bin_seeding)
ms.fit(X)# 获取聚类结果
labels = ms.labels_
cluster_centers = ms.cluster_centers_# 可视化聚类结果
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.scatter(cluster_centers[:, 0], cluster_centers[:, 1,], marker='o', s=100, color='red')
plt.show()

重要参数:bandwidth,需要根据数据特点调整,如下所示:

ps:如果带宽参数过小,会导致聚类中心过多,如果带宽参数过大,会导致聚类中心过少。因此,在实际应用中,我们需要通过交叉验证等方法来确定带宽参数的取值。

bandwidth=1

在这里插入图片描述

bandwidth=2

在这里插入图片描述

总结

优点:

  • 不需要设置簇类的个数,自动发现潜在的聚类中心,对于高维度和非线性分布的数据集也有很好的适应性
  • 可以处理任意形状的簇类
  • 参数少,算法只需设置带宽这一个参数,带宽影响数据集的核密度估计
  • 算法结果稳定,不需要进行类似K均值的样本初始化

缺点:

  • 聚类结果取决于带宽的设置,带宽设置的太小,收敛太慢,簇类个数过多;带宽设置的太大,一些簇类可能会丢失。
  • 对于较大的特征空间,计算量非常大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/460352.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

考研数据结构笔记(5)

单链表的查找 按位查找(O(n))按值查找(O(n))单链表长度(O(n))小结 基于带头结点的代码 按位查找(O(n)) 按值查找(O(n)) 单链表长度(O(n)) 小结

Linux 问题的故障定位

主要介绍各种问题定位的工具以及会结合案例分析问题 1. 分析问题 What-现象是什么样的 When-什么时候发生 Why-为什么会发生 Where-哪个地方发生的问题 How much-耗费了多少资源 How to do-怎么解决问题 2. cpu 针对应用程序,我们通常关注的是内核CPU调度…

【stomp实战】Springboot+Stomp协议实现聊天功能

本示例实现一个功能,前端通过websocket发送消息给后端服务,后端服务接收到该消息时,原样将消息返回给前端。前端技术栈htmlstomp.js,后端SpringBoot 前端代码 关于stomp客户端的开发,如果不清楚的,可以看…

运维高级篇-分库分表(拆分策略详解)

分库分表 介绍 问题分析 随着互联网及移动互联网的发展,应用系统的数据量也是成指数式增长,若采用单数据库进行数据存 储,存在以下性能瓶颈: IO瓶颈:热点数据太多,数据库缓存不足,产生大量磁盘…

DFS——剪枝

dfs在每个点(状态)的情况比较多,但是节点比较少的时候很常用,我们将每个状态的情况延伸出去,可以画出一棵搜索树。dfs会搜到每一种情况,所以我们实际上可以按照任意顺序来判否。为了优化搜索我们可以在搜索…

深度分析一款新型Linux勒索病毒

前言 DarkRadiation勒索病毒是一款全新的Linux平台下的勒索病毒,2021年5月29日首次在某平台上发布了此勒索病毒的相关的信息,6月中旬趋势科技针对这个新型的勒索病毒进行了相关的分析和报道。 DarkRadiation勒索病毒采用Bash脚本语言编写实现&#xff0…

多普勒效应的一些解释

摘自《多普勒效应教学中的几个疑问》 摘自《面向工科物理学生的多普勒效应讲解》

Zabbix 配置实时开通的LDAP认证-基于AD

介绍 本教程适用于6.4-7.0版本的Zabbix,域控(AD)使用Windows Server 2022搭建,域控等级为 2016。 域控域名为 songxwn.com 最终实现AD用户统一认证,统一改密,Zabbix用户自动添加。(6.4之前不…

1897_野火FreeRTOS教程阅读笔记_链表

1897_野火FreeRTOS教程阅读笔记_链表 全部学习汇总: g_FreeRTOS: FreeRTOS学习笔记 (gitee.com) 之前我自己通过直接啃代码的方式对FreeRTOS也算是有了一点理解了,这次趁着些许闲暇翻看一下野火的FreeRTOS教程。一者算是一种复习;二者可能对自…

Python中使用opencv-python库进行颜色检测

Python中使用opencv-python库进行颜色检测 之前写过一篇VC中使用OpenCV进行颜色检测的博文,当然使用opencv-python库也可以实现。 在Python中使用opencv-python库进行颜色检测非常简单,首选读取一张彩色图像,并调用函数imgHSV cv2.cvtColor…

VScode为什么选择了Electron,而不是QT?

选择Electron而不是QT可能是基于以下几个原因: Web技术的普及和开发者生态系统:Web技术如HTML、CSS和JavaScript在开发者中非常普及,开发者生态系统庞大且活跃。使用Electron可以利用这些熟悉的Web技术和丰富的开发者社区资源。跨平台支持&am…

林浩然与杨凌芸的Java奇遇记:Lambda表达式大冒险

林浩然与杨凌芸的Java奇遇记:Lambda表达式大冒险 Lin Haoran and Yang Lingyun’s Java Adventure: The Grand Expedition of Lambda Expressions 在Java编程世界的一隅,住着一对编程界的“才子佳人”,男主角名叫林浩然,女主角唤作…