本文由ChardLau原创,转载请添加原文链接https://www.chardlau.com/mean-shift/

今天的文章介绍如何利用Mean Shift算法的基本形式对数据进行聚类操作。而有关Mean Shift算法加入核函数计算漂移向量部分的内容将不在本文讲述范围内。实际上除了聚类,Mean Shift算法还能用于计算机视觉等场合,有关该算法的理论知识请参考这篇文章

Mean Shift算法原理

下图展示了Mean Shift算法计算飘逸向量的过程:

Mean Shift算法的关键操作是通过感兴趣区域内的数据密度变化计算中心点的漂移向量,从而移动中心点进行下一次迭代,直到到达密度最大处(中心点不变)。从每个数据点出发都可以进行该操作,在这个过程,统计出现在感兴趣区域内的数据的次数。该参数将在最后作为分类的依据。

K-Means算法不一样的是,Mean Shift算法可以自动决定类别的数目。与K-Means算法一样的是,两者都用集合内数据点的均值进行中心点的移动。

算法步骤

下面是有关Mean Shift聚类算法的步骤:

  1. 在未被标记的数据点中随机选择一个点作为起始中心点center;
  2. 找出以center为中心半径为radius的区域中出现的所有数据点,认为这些点同属于一个聚类C。同时在该聚类中记录数据点出现的次数加1。
  3. 以center为中心点,计算从center开始到集合M中每个元素的向量,将这些向量相加,得到向量shift。
  4. center = center + shift。即center沿着shift的方向移动,移动距离是||shift||。
  5. 重复步骤2、3、4,直到shift的很小(就是迭代到收敛),记住此时的center。注意,这个迭代过程中遇到的点都应该归类到簇C。
  6. 如果收敛时当前簇C的center与其它已经存在的簇C2中心的距离小于阈值,那么把C2和C合并,数据点出现次数也对应合并。否则,把C作为新的聚类。
  7. 重复1、2、3、4、5直到所有的点都被标记为已访问。
  8. 分类:根据每个类,对每个点的访问频率,取访问频率最大的那个类,作为当前点集的所属类。

算法实现

下面使用Python实现了Mean Shift算法的基本形式:

import numpy as np
import matplotlib.pyplot as plt # Input data set
X = np.array([
[-4, -3.5], [-3.5, -5], [-2.7, -4.5],
[-2, -4.5], [-2.9, -2.9], [-0.4, -4.5],
[-1.4, -2.5], [-1.6, -2], [-1.5, -1.3],
[-0.5, -2.1], [-0.6, -1], [0, -1.6],
[-2.8, -1], [-2.4, -0.6], [-3.5, 0],
[-0.2, 4], [0.9, 1.8], [1, 2.2],
[1.1, 2.8], [1.1, 3.4], [1, 4.5],
[1.8, 0.3], [2.2, 1.3], [2.9, 0],
[2.7, 1.2], [3, 3], [3.4, 2.8],
[3, 5], [5.4, 1.2], [6.3, 2]
]) def mean_shift(data, radius=2.0):
clusters = []
for i in range(len(data)):
cluster_centroid = data[i]
cluster_frequency = np.zeros(len(data)) # Search points in circle
while True:
temp_data = []
for j in range(len(data)):
v = data[j]
# Handle points in the circles
if np.linalg.norm(v - cluster_centroid) <= radius:
temp_data.append(v)
cluster_frequency[i] += 1 # Update centroid
old_centroid = cluster_centroid
new_centroid = np.average(temp_data, axis=0)
cluster_centroid = new_centroid
# Find the mode
if np.array_equal(new_centroid, old_centroid):
break # Combined 'same' clusters
has_same_cluster = False
for cluster in clusters:
if np.linalg.norm(cluster['centroid'] - cluster_centroid) <= radius:
has_same_cluster = True
cluster['frequency'] = cluster['frequency'] + cluster_frequency
break if not has_same_cluster:
clusters.append({
'centroid': cluster_centroid,
'frequency': cluster_frequency
}) print('clusters (', len(clusters), '): ', clusters)
clustering(data, clusters)
show_clusters(clusters, radius) # Clustering data using frequency
def clustering(data, clusters):
t = []
for cluster in clusters:
cluster['data'] = []
t.append(cluster['frequency'])
t = np.array(t)
# Clustering
for i in range(len(data)):
column_frequency = t[:, i]
cluster_index = np.where(column_frequency == np.max(column_frequency))[0][0]
clusters[cluster_index]['data'].append(data[i]) # Plot clusters
def show_clusters(clusters, radius):
colors = 10 * ['r', 'g', 'b', 'k', 'y']
plt.figure(figsize=(5, 5))
plt.xlim((-8, 8))
plt.ylim((-8, 8))
plt.scatter(X[:, 0], X[:, 1], s=20)
theta = np.linspace(0, 2 * np.pi, 800)
for i in range(len(clusters)):
cluster = clusters[i]
data = np.array(cluster['data'])
plt.scatter(data[:, 0], data[:, 1], color=colors[i], s=20)
centroid = cluster['centroid']
plt.scatter(centroid[0], centroid[1], color=colors[i], marker='x', s=30)
x, y = np.cos(theta) * radius + centroid[0], np.sin(theta) * radius + centroid[1]
plt.plot(x, y, linewidth=1, color=colors[i])
plt.show() mean_shift(X, 2.5)

代码链接

上述代码执行结果如下:

其他

Mean Shift算法还有很多内容未提及。其中有“动态计算感兴趣区域半径”、“加入核函数计算漂移向量”等。本文作为入门引导,暂时只覆盖这些内容。

机器学习:Mean Shift聚类算法的更多相关文章

  1. mean shift聚类算法的MATLAB程序

    mean shift聚类算法的MATLAB程序 凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1. mean shift 简介 mean shift, 写的 ...

  2. 机器学习六--K-means聚类算法

    机器学习六--K-means聚类算法 想想常见的分类算法有决策树.Logistic回归.SVM.贝叶斯等.分类作为一种监督学习方法,要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别 ...

  3. Mahout机器学习平台之聚类算法具体剖析(含实例分析)

    第一部分: 学习Mahout必需要知道的资料查找技能: 学会查官方帮助文档: 解压用于安装文件(mahout-distribution-0.6.tar.gz),找到例如以下位置.我将该文件解压到win ...

  4. 机器学习:K-Means聚类算法

    本文来自同步博客. 前面几篇文章介绍了回归或分类的几个算法,它们的共同点是训练数据包含了输出结果,要求算法能够通过训练数据掌握规律,用于预测新输入数据的输出值.因此,回归算法或分类算法被称之为监督学习 ...

  5. 机器学习中K-means聚类算法原理及C语言实现

    本人以前主要focus在传统音频的软件开发,接触到的算法主要是音频信号处理相关的,如各种编解码算法和回声消除算法等.最近切到语音识别上,接触到的算法就变成了各种机器学习算法,如GMM等.K-means ...

  6. 【Python机器学习实战】聚类算法(1)——K-Means聚类

    实战部分主要针对某一具体算法对其原理进行较为详细的介绍,然后进行简单地实现(可能对算法性能考虑欠缺),这一部分主要介绍一些常见的一些聚类算法. K-means聚类算法 0.聚类算法算法简介 聚类算法算 ...

  7. 机器学习sklearn19.0聚类算法——Kmeans算法

    一.关于聚类及相似度.距离的知识点 二.k-means算法思想与流程 三.sklearn中对于kmeans算法的参数 四.代码示例以及应用的知识点简介 (1)make_blobs:聚类数据生成器 sk ...

  8. 机器学习入门-DBSCAN聚类算法

    DBSCAN 聚类算法又称为密度聚类,是一种不断发张下线而不断扩张的算法,主要的参数是半径r和k值 DBSCAN的几个概念: 核心对象:某个点的密度达到算法设定的阈值则其为核心点,核心点的意思就是一个 ...

  9. 机器学习之K-Mean聚类算法

    知识点: # coding = utf-8 import numpy as np import pandas as pd from sklearn.cluster import KMeans &quo ...

随机推荐

  1. Java使用Selenium几个例子

    零.姿势 Selenium分为两个版本:Selenium RC和Selenium Webdriver.现在用Selenium Webdriver比较多. Selenium是一套工具,而不仅仅是一个操纵 ...

  2. Python 随机数 random

    1. Python seed() 函数     seed() 方法改变随机数生成器的种子,可以在调用其他随机模块函数之前调用此函数. seed( )是不能直接访问的,需要导入 random 模块,然后 ...

  3. 【LeetCode】153. Find Minimum in Rotated Sorted Array (3 solutions)

    Find Minimum in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you ...

  4. Outlook如何定时发邮件

    http://jingyan.baidu.com/article/c843ea0b63e15377931e4a0e.html 更多文章: Outlook定时发送邮件问题-http://blog.sin ...

  5. Windows下面安装和配置Solr 4.9(三)支持中文分词器

    首先将下载解压后的solr-4.9.0的目录里面F:\tools\开发工具\Lucene\solr-4.9.0\contrib\analysis-extras\lucene-libs找到lucene- ...

  6. iOS - PairProgramming 结对编程

    1.PairProgramming 结对编程(Pair-Programming)可能是近年来最为流行的编程方式.所谓结对编程,也就是两个人写一个程序,其中,一个人叫 Driver,另一个人叫 Obse ...

  7. 让thinkphp 支持ftp上传到远程,ftp删除

    让thinkphp真正的支持FTP上传.删除. 原创by default7#zbphp.com,如需转载请保留作者信息. /** * This is not a free software, All ...

  8. ArcMap导入数据到ArcSDE报000597或者000224的错误

    这两天碰到不同用户提出的不同的问题,可是分析之后发现导致该问题的解决办法是同一个原因. -------------------------------------------------------- ...

  9. MDK5在调试中崩溃,提示“IDE已停止工作”

    出问题的原因是路径名太长,换个深度浅一点的路径就好了. 要注意,更换路径之后,要全部重新编译,否则调试的时侯MDK还会找旧路径的源代码.(嗯,MDK毛病是很多!)

  10. xcode cocos2dx 3.x mac工程 当assert(cond)触发断点,但cond却为0

    xcode cocos2dx 3.x mac工程 当发生assert(cond)触发断点,但查看cond值却为0的诡异情况时,clean再重新build就好了.