1、背景介绍

  密度峰值算法(Clustering by fast search and find of density peaks)由Alex Rodriguez和Alessandro Laio于2014年提出,并将论文发表在Science上。Science上的这篇文章《Clustering by fast search and find of density peaks》主要讲的是一种基于密度的聚类方法,基于密度的聚类方法的主要思想是寻找被低密度区域分离的高密度区域。 密度峰值算法(DPCA)基于这样的假设:(1)类簇中心点的密度大于周围邻居点的密度;(2)类簇中心点与更高密度点之间的距离相对较大。因此,DPCA主要有两个需要计算的量:第一,局部密度;第二,与高密度点之间的距离。

2、局部密度

  数据对象的局部密度定义为:

其中,表示截断距离,这个公式的含义是说找到与第个数据点之间的距离小于截断距离的数据点的个数,并将其作为第i个数据点真的密度。

3、定义聚类中心距离

  密度峰聚类算法的巧妙之处:就是在于聚类中心距离 δi的选定。根据局部密度的定义,我们可以计算出上图中每个点的密度,依照密度确定聚类中心距离 δi。

1.首先将每个点的密度从大到小排列: ρi > ρj > ρk > ….;密度最大的点的聚类中心距离与其他点的聚类中心距离的确定方法是不一样的;
2.先确定密度最大的点的聚类中心距离–i点是密度最大的点,它的聚类中心距离δiδi等于与i点最远的那个点n到点i的直线距离 d(i,n);
3. 再确定其他点的聚类中心距离——其他点的聚类中心距离是等于在密度大于该点的点集合中,与该点距离最小的的那个距离。例如i、j、k的密度都比n点的密度大,且j点离n点最近,则n点的聚类中心距离等于d(j,n); 
4. 依次确定所有的聚类中心距离δ

4、聚类效果

  将所有点的聚类中心密度都统计出来后,将其值按 δi和pi作为坐标轴作图可以得到如图所示结果。可以看到图中1,10两个聚类中心同时远离坐标轴。普通点则是靠近p轴,异常点靠近 δ轴。

5、基于python的实现:

  python代码如下,其中要引入numpy等一些包,pycharm中引入包还是比较简单的。

# -*- coding:utf- -*-
# -*- python3.
import numpy as np
import matplotlib.pyplot as plt
import sklearn.datasets as ds
import matplotlib.colors min_distance = 4.6 # 邻域半径
points_number = # 随机点个数 # 计算各点间距离、各点点密度(局部密度)大小
def get_point_density(datas,labers,min_distance,points_number):
# 将numpy.ndarray格式转为list格式,并定义元组大小
data = datas.tolist()
laber = labers.tolist()
distance_all = np.random.rand(points_number,points_number)
point_density = np.random.rand(points_number) # 计算得到各点间距离
for i in range(points_number):
for n in range(points_number):
distance_all[i][n] = np.sqrt(np.square(data[i][]-data[n][])+np.square(data[i][]-data[n][]))
print('距离数组:\n',distance_all,'\n') # 计算得到各点的点密度
for i in range(points_number):
x =
for n in range(points_number):
if distance_all[i][n] > and distance_all[i][n]< min_distance:
x = x+
point_density[i] = x
print('点密度数组:', point_density, '\n')
return distance_all, point_density # 计算点密度最大的点的聚类中心距离
def get_max_distance(distance_all,point_density,laber):
point_density = point_density.tolist()
a = int(max(point_density))
# print('最大点密度',a,type(a)) b = laber[point_density.index(a)]
# print("最大点密度对应的索引:",b,type(b)) c = max(distance_all[b])
# print("最大点密度对应的聚类中心距离",c,type(c)) return c # 计算得到各点的聚类中心距离
def get_each_distance(distance_all,point_density,data,laber):
nn = []
for i in range(len(point_density)):
aa = []
for n in range(len(point_density)):
if point_density[i] < point_density[n]:
aa.append(n)
# print("大于自身点密度的索引",aa,type(aa))
ll = get_min_distance(aa,i,distance_all, point_density,data,laber)
nn.append(ll)
return nn # 获得:到点密度大于自身的最近点的距离
def get_min_distance(aa,i,distance_all, point_density,data,laber):
min_distance = []
"""
如果传入的aa为空,说明该点是点密度最大的点,该点的聚类中心距离计算方法与其他不同
"""
if aa != []:
for k in aa:
min_distance.append(distance_all[i][k])
# print('与上各点距离',min_distance,type(nn))
# print("最小距离:",min(min_distance),type(min(min_distance)),'\n')
return min(min_distance)
else:
max_distance = get_max_distance(distance_all, point_density, laber)
return max_distance def get_picture(data,laber,points_number,point_density,nn):
# 创建Figure
fig = plt.figure()
# 用来正常显示中文标签
matplotlib.rcParams['font.sans-serif'] = [u'SimHei']
# 用来正常显示负号
matplotlib.rcParams['axes.unicode_minus'] = False # 原始点的分布
ax1 = fig.add_subplot()
plt.scatter(data[:,],data[:,],c=laber)
plt.title(u'原始数据分布')
plt.sca(ax1)
for i in range(points_number):
plt.text(data[:,][i],data[:,][i],laber[i]) # 聚类后分布
ax2 = fig.add_subplot()
plt.scatter(point_density.tolist(),nn,c=laber)
plt.title(u'聚类后数据分布')
plt.sca(ax2)
for i in range(points_number):
plt.text(point_density[i],nn[i],laber[i]) plt.show() def main():
# 随机生成点坐标
data, laber = ds.make_blobs(points_number, centers=points_number, random_state=)
print('各点坐标:\n', data)
print('各点索引:', laber, '\n') # 计算各点间距离、各点点密度(局部密度)大小
distance_all, point_density = get_point_density(data, laber, min_distance, points_number)
# 得到各点的聚类中心距离
nn = get_each_distance(distance_all, point_density, data, laber)
print('最后的各点点密度:', point_density.tolist())
print('最后的各点中心距离:', nn) # 画图
get_picture(data, laber, points_number, point_density, nn)
"""
距离归一化:就把上面的nn改为:nn/max(nn)
""" if __name__ == '__main__':
main()

代码运行效果如下图:

基于密度峰值的聚类(DPCA)的更多相关文章

  1. 聚类-DBSCAN基于密度的空间聚类

    1.DBSCAN介绍 DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪声的基于密度的聚类方法)是一种基于密度 ...

  2. 密度峰值聚类算法(DPC)

    密度峰值聚类算法(DPC) 凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1. 简介 基于密度峰值的聚类算法全称为基于快速搜索和发现密度峰值的聚类算法(cl ...

  3. 简单易学的机器学习算法——基于密度的聚类算法DBSCAN

    一.基于密度的聚类算法的概述     最近在Science上的一篇基于密度的聚类算法<Clustering by fast search and find of density peaks> ...

  4. sklearn聚类模型:基于密度的DBSCAN;基于混合高斯模型的GMM

    1 sklearn聚类方法详解 2 对比不同聚类算法在不同数据集上的表现 3 用scikit-learn学习K-Means聚类 4 用scikit-learn学习DBSCAN聚类 (基于密度的聚类) ...

  5. 密度峰值聚类算法原理+python实现

    ​ 密度峰值聚类(Density peaks clustering, DPC)来自Science上Clustering by fast search and find of density peaks ...

  6. 基于密度聚类的DBSCAN和kmeans算法比较

    根据各行业特性,人们提出了多种聚类算法,简单分为:基于层次.划分.密度.图论.网格和模型的几大类. 其中,基于密度的聚类算法以DBSCAN最具有代表性.  场景 一 假设有如下图的一组数据, 生成数据 ...

  7. 基于密度的聚类之Dbscan算法

    一.算法概述 DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法.与划分和层次 ...

  8. 聚类:层次聚类、基于划分的聚类(k-means)、基于密度的聚类、基于模型的聚类

    一.层次聚类 1.层次聚类的原理及分类 1)层次法(Hierarchicalmethods)先计算样本之间的距离.每次将距离最近的点合并到同一个类.然后,再计算类与类之间的距离,将距离最近的类合并为一 ...

  9. 【机器学习】DBSCAN Algorithms基于密度的聚类算法

    一.算法思想: DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法.与划分和层 ...

随机推荐

  1. [ SSH框架 ] Spring框架学习之三(AOP开发和注解的使用)

    一.Spring 使用 AspectJ 进行 AOP 的开发:注解的方式 1.1 引入相关的jar包 1.2 引入spring的配置文件 <?xml version="1.0" ...

  2. Python迭代和解析(5):搞懂生成器和yield机制

    解析.迭代和生成系列文章:https://www.cnblogs.com/f-ck-need-u/p/9832640.html 何为生成器 生成器的wiki页:https://en.wikipedia ...

  3. H5 和 CSS3 新特性

    博客地址:https://ainyi.com/52 H5 新特性 语义化标签:header.footer.section.nav.aside.article 增强型表单:input 的多个 type ...

  4. 第43章 添加更多API端点 - Identity Server 4 中文文档(v1.0.0)

    您可以向托管IdentityServer4的应用程序添加更多API端点. 您通常希望通过它们所托管的IdentityServer实例来保护这些API.这不是问题.只需将令牌验证处理程序添加到主机(请参 ...

  5. HttpClient post提交数据,返回json

    // string data = "{\"uid\":515,\"timestamp\":\"2018 - 5 - 25 19:05:00\ ...

  6. [PHP] 抽象类abstract的回顾

    1.abstract定义为抽象的类不能被实例化. 2.它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的. 3.被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实 ...

  7. 阿里巴巴TXD前端小报 - 2019年3月刊

    原文:前端小报 - 201903月刊 Fundebug经授权转载,版权归原作者所有. [Alibaba-TXD 前端小报]- 热门前端技术快报,聚焦业界新视界:不知不觉 2019 年已经过去了 1/4 ...

  8. CRM之分页

    分页简介 分页功能在网页中是非常常见的一个功能,其作用也就是将数据分割成多个页面来进行显示. 使用场景: 当取到的数据量达到一定的时候,就需要使用分页来进行数据分割. 当我们不使用分页功能的时候,会面 ...

  9. 关于Xcode9.0版本模拟器Reset重置操作变更

  10. Java内存管理的进一步理解-模拟过程图解

    Java内存管理的进一步理解-模拟过程图解--转载 java的内存管理分为: 1.堆内存:2.栈内存:3.方法区:4.本地方法区 /* 1:方法区      方法区存放装载的类数据信息包括:      ...