基于密度峰值的聚类(DPCA)

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

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-8 -*-
# -*- python3.5
import numpy as np
import matplotlib.pyplot as plt
import sklearn.datasets as ds
import matplotlib.colors
min_distance = 4.6           # 邻域半径
points_number = 40          # 随机点个数
# 计算各点间距离、各点点密度(局部密度)大小
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][0]-data[n][0])+np.square(data[i][1]-data[n][1]))
    print('距离数组:\n',distance_all,'\n')
    # 计算得到各点的点密度
    for i in range(points_number):
        x = 0
        for n in range(points_number):
            if distance_all[i][n] > 0 and distance_all[i][n]< min_distance:
                x = x+1
            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(211)
    plt.scatter(data[:,0],data[:,1],c=laber)
    plt.title(u'原始数据分布')
    plt.sca(ax1)
    for i in range(points_number):
        plt.text(data[:,0][i],data[:,1][i],laber[i])
    # 聚类后分布
    ax2 = fig.add_subplot(212)
    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=0)
    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()

代码运行效果如下图:

其他相关
第1239章 风物长宜放眼量

第1239章 风物长宜放眼量

作者: 天天见闻 时间:2022-02-24 阅读: 542
刘枫语重心长的说:“风物长宜放眼量!在座的各位不仅仅要着眼于全省,更是要放眼整个小江流域,集全流域的物产与政治、经济资源为我所用。在这个过渡地带,更是沿海产业转移的过度区域,在这个过渡区间,我们有着很多的机遇,如果不能把握这千载难逢的机遇,那是我们这些官员的失职!“风物长宜放眼量”出自太祖的一词,“牢骚太胜防肠断,风物长宜放眼量。...
少年派大结局第二部什么时候播?会不会有《中年派》《老年派》

少年派大结局第二部什么时候播?会不会有《中年派》《老年派》

作者: 天天见闻 时间:2022-02-26 阅读: 999
少年派有第二部吗?少年派第二季什么时候播出?近日电视剧少年派大结局播出,网友十分关心少年派主演人物结局如何,下面来看看吧。目前还没有关于电视剧《少年派》拍续集的消息,不过也有网友表示,这剧这么火,少年时期拍完了,后续会不会有《中年派》《老年派》呢?《少年派》算得上是一次突破少年派2什么时候上映,题材新颖少年派2什么时候上映,高中生还能有感情的萌芽。...
三角函数公式大全表格

三角函数公式大全表格

作者: 天天见闻 时间:2022-02-26 阅读: 970
换句话说三角函数公式大全表格,只有两个正因数的自然数即为素数。中国古代数学家称直角三角形为勾股形,较短的直角边称为勾三角函数公式大全表格,另一直角边称为股,斜边称为弦,所以勾股定理也称为勾股弦定理。...
有关兴趣爱好的演讲稿

有关兴趣爱好的演讲稿

作者: 天天见闻 时间:2022-02-28 阅读: 628
每个人都有自己的兴趣爱好,这些兴趣爱好给我们带来了无限的快乐,装点了我们的生活,是我们一生的好伙伴。相信每个人都有自己的兴趣爱好,有人喜欢画画兴趣爱好,他们把一张张枯燥的白纸渲染成一幅幅色彩斑斓的艺术作品;有人热爱足球,他们在球场上奔跑,尽情挥洒汗水,无比欢乐;有人喜欢读书,他们吃的是“精神食粮”,早已陶醉在心灵的盛宴中。...
享年95岁!漫威之父斯坦·李去世 美队、钢铁侠、蜘蛛侠、NASA纷纷发文悼念

享年95岁!漫威之父斯坦·李去世 美队、钢铁侠、蜘蛛侠、NASA纷纷发文悼念

作者: 天天见闻 时间:2022-02-28 阅读: 838
一手创作出世界上最著名的超级英雄漫画人物,包括蜘蛛侠、钢铁侠、绿巨人、黑豹、复仇者联盟和X战警的漫画家斯坦·李去世了,享年95岁。李还创造了漫威的第一个黑人超级英雄——黑豹,其2018年的同名电影在全球超过13亿美元票房,以及著名的复仇者黑寡妇、鹰眼和神盾局老板尼克·弗瑞。得知斯坦·李去世后,扮演超级英雄的明星也纷纷发文悼念。死侍瑞安·雷诺兹的悼念也一如死侍的风格,“该死的……斯坦。...
战雷20集

战雷20集

作者: 天天见闻 时间:2022-03-01 阅读: 557
战雷20集战雷:新兵为见军长砸军长的车,怎料军长不追究战雷:士兵排查战争留下老雷,怎想触发装置,一条胳膊没了父女两被困雷阵,竟是用战时诡雷的方法布置,警察拆不了…战雷06:工兵营跟预备营比赛排雷,新兵一人挑一队,结果还赢了战雷:老兵排雷不穿防护服,一人单挑一个雷场,新兵全成迷弟战雷02:新兵不想训练,装吐血送进医务室,差点把连长给吓哭...
我来说两句

年度爆文