精华内容
下载资源
问答
  • 主要介绍了Python聚类算法之凝聚层次聚类的原理与具体使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • 欢迎关注公众号:大邓和他的Python层次分析属于聚类分析的一种,scipy有这方面的封装包。linkage函数从字面意思是链接,层次分析就是不断链接的过程,最终从n条数据,经过不断链接,最终聚合成一类,算法就此停止。...

    欢迎关注

    公众号:大邓和他的Python

    层次分析属于聚类分析的一种,scipy有这方面的封装包。

    linkage函数从字面意思是链接,层次分析就是不断链接的过程,最终从n条数据,经过不断链接,最终聚合成一类,算法就此停止。

    dendrogram是用来绘制树形图的函数。

    from scipy.cluster.hierarchy import linkage, dendrogram

    import matplotlib.pyplot as plt

    import pandas as pd

    seeds_df = pd.read_csv('seeds-less-rows.csv')

    seeds_df.head()

    #移除文本数据列

    varieties = list(seeds_df.pop('grain_variety'))

    varieties

    运行结果

    ['Kama wheat',

    'Kama wheat',

    'Kama wheat',

    'Rosa wheat',

    'Rosa wheat',

    'Rosa wheat',

    'Rosa wheat',

    'Rosa wheat',

    'Canadian wheat',

    'Canadian wheat',

    'Canadian wheat',

    'Canadian wheat',

    'Canadian wheat',

    'Canadian wheat']

    查看下数据的shape

    samples = seeds_df.values

    print(samples)

    print('samples的维度',samples.shape)

    运行结果

    [[14.88 14.57 0.8811 5.554 3.333 1.018 4.956 ]

    [14.69 14.49 0.8799 5.563 3.259 3.586 5.219 ]

    [14.03 14.16 0.8796 5.438 3.201 1.717 5.001 ]

    [19.31 16.59 0.8815 6.341 3.81 3.477 6.238 ]

    [17.99 15.86 0.8992 5.89 3.694 2.068 5.837 ]

    [18.85 16.17 0.9056 6.152 3.806 2.843 6.2 ]

    [19.38 16.72 0.8716 6.303 3.791 3.678 5.965 ]

    [17.36 15.76 0.8785 6.145 3.574 3.526 5.971 ]

    [13.32 13.94 0.8613 5.541 3.073 7.035 5.44 ]

    [11.43 13.13 0.8335 5.176 2.719 2.221 5.132 ]

    [11.26 13.01 0.8355 5.186 2.71 5.335 5.092 ]

    [12.46 13.41 0.8706 5.236 3.017 4.987 5.147 ]

    [11.81 13.45 0.8198 5.413 2.716 4.898 5.352 ]

    [11.23 12.88 0.8511 5.14 2.795 4.325 5.003 ]]

    samples的维度 (14, 7)

    使用linkage函数对samples进行层次聚类

    X = linkage(y, method='single', metric='euclidean')

    sacipy中y是距离矩阵,我对此只是傻傻的理解成特征矩阵。 (m*n) m行代表m条记录,n代表n个特征

    返回结果X是(m-1)*4的矩阵。 具体含义请看下面的案例

    mergings = linkage(samples)

    #我们发现mergings比samples少一行

    print('sample维度',samples.shape)

    print('mergings维度',mergings.shape)

    sample维度 (14, 7)

    mergings维度 (13, 4)

    #层次分析可视化,leaf的字体不旋转,大小为10。

    #这里我们不显示每一条数据的具体名字标签(varieties),默认以数字标签显示

    dendrogram(mergings,leaf_rotation=0,leaf_font_size=10)

    plt.show()

    #在图中显示的数字是最细粒度的叶子,相当于每个样本数据点。

    mergings

    运行结果

    array([[ 3. , 6. , 0.37233454, 2. ],

    [11. , 12. , 0.77366442, 2. ],

    [10. , 15. , 0.89804259, 3. ],

    [ 5. , 14. , 0.90978998, 3. ],

    [13. , 16. , 1.02732924, 4. ],

    [ 0. , 2. , 1.18832161, 2. ],

    [ 4. , 17. , 1.28425969, 4. ],

    [ 7. , 20. , 1.62187345, 5. ],

    [ 1. , 19. , 2.02587613, 3. ],

    [ 9. , 18. , 2.13385537, 5. ],

    [ 8. , 23. , 2.323123 , 6. ],

    [22. , 24. , 2.87625877, 9. ],

    [21. , 25. , 3.12231564, 14. ]])

    层次分析图从上到下看,依次是枝和叶。

    第一列和第二列代表类标签,包含叶子和枝子。

    第三列代表叶叶(或叶枝,枝枝)之间的距离

    第四列代表该层次类中含有的样本数(记录数)X = linkage(y, method='single', metric='euclidean')

    method是指计算类间距离的方法,比较常用的有3种:

    (1)single:最近邻,把类与类间距离最近的作为类间距

    (2)average:平均距离,类与类间所有pairs距离的平均

    (3)complete:最远邻,把类与类间距离最远的作为类间距

    我们写曾侧分析法函数,看看不同的method从图中有什么区别

    def hierarchy_analysis(samples,method='single'):

    mergings = linkage(samples, method=method)

    dendrogram(mergings,

    labels=varieties,

    leaf_rotation=45,

    leaf_font_size=10)

    plt.show()

    single

    #single

    hierarchy_analysis(samples,method='single')

    average

    hierarchy_analysis(samples,method='average')

    complete

    hierarchy_analysis(samples,method='complete')

    由于数据量比较少,complete和average方法做出来的图完全一样。

    展开全文
  • 这篇文章主要介绍了Python聚类算法之凝聚层次聚类的原理与具体使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了Python聚类算法之凝聚层次聚类。分享给大家供大家参考,具体如下: 凝聚层次聚类:...

    这篇文章主要介绍了Python聚类算法之凝聚层次聚类的原理与具体使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    本文实例讲述了Python聚类算法之凝聚层次聚类。分享给大家供大家参考,具体如下:

    凝聚层次聚类:所谓凝聚的,指的是该算法初始时,将每个点作为一个簇,每一步合并两个最接近的簇。另外即使到最后,对于噪音点或是离群点也往往还是各占一簇的,除非过度合并。对于这里的“最接近”,有下面三种定义。我在实现是使用了MIN,该方法在合并时,只要依次取当前最近的点对,如果这个点对当前不在一个簇中,将所在的两个簇合并就行:

    单链(MIN):定义簇的邻近度为不同两个簇的两个最近的点之间的距离。
    全链(MAX):定义簇的邻近度为不同两个簇的两个最远的点之间的距离。
    组平均:定义簇的邻近度为取自两个不同簇的所有点对邻近度的平均值。

     scoding=utf-8
    # Agglomerative Hierarchical Clustering(AHC)
    import pylab as pl
    from operator import itemgetter
    from collections import OrderedDict,Counter
    points = [[int(eachpoint.split('#')[0]), int(eachpoint.split('#')[1])] for eachpoint in open("points","r")]
    # 初始时每个点指派为单独一簇
    groups = [idx for idx in range(len(points))]
    # 计算每个点对之间的距离
    disP2P = {}
    for idx1,point1 in enumerate(points):
      for idx2,point2 in enumerate(points):
        if (idx1 < idx2):
          distance = pow(abs(point1[0]-point2[0]),2) + pow(abs(point1[1]-point2[1]),2)
          disP2P[str(idx1)+"#"+str(idx2)] = distance
    # 按距离降序将各个点对排序
    disP2P = OrderedDict(sorted(disP2P.iteritems(), key=itemgetter(1), reverse=True))
    # 当前有的簇个数
    groupNum = len(groups)
    # 过分合并会带入噪音点的影响,当簇数减为finalGroupNum时,停止合并
    finalGroupNum = int(groupNum*0.1)
    while groupNum > finalGroupNum:
      # 选取下一个距离最近的点对
      twopoins,distance = disP2P.popitem()
      pointA = int(twopoins.split('#')[0])
      pointB = int(twopoins.split('#')[1])
      pointAGroup = groups[pointA]
      pointBGroup = groups[pointB]
      # 当前距离最近两点若不在同一簇中,将点B所在的簇中的所有点合并到点A所在的簇中,此时当前簇数减1
      if(pointAGroup != pointBGroup):
        for idx in range(len(groups)):
          if groups[idx] == pointBGroup:
            groups[idx] = pointAGroup
        groupNum -= 1
    # 选取规模最大的3个簇,其他簇归为噪音点
    wantGroupNum = 3
    finalGroup = Counter(groups).most_common(wantGroupNum)
    finalGroup = [onecount[0] for onecount in finalGroup]
    dropPoints = [points[idx] for idx in range(len(points)) if groups[idx] not in finalGroup]
    # 打印规模最大的3个簇中的点
    group1 = [points[idx] for idx in xrange(len(points)) if groups[idx]==finalGroup[0]]
    group2 = [points[idx] for idx in xrange(len(points)) if groups[idx]==finalGroup[1]]
    group3 = [points[idx] for idx in xrange(len(points)) if groups[idx]==finalGroup[2]]
    pl.plot([eachpoint[0] for eachpoint in group1], [eachpoint[1] for eachpoint in group1], 'or')
    pl.plot([eachpoint[0] for eachpoint in group2], [eachpoint[1] for eachpoint in group2], 'oy')
    pl.plot([eachpoint[0] for eachpoint in group3], [eachpoint[1] for eachpoint in group3], 'og')  
    # 打印噪音点,黑色
    pl.plot([eachpoint[0] for eachpoint in dropPoints], [eachpoint[1] for eachpoint in dropPoints], 'ok')  
    pl.show()
    

    运行效果截图如下:在这里插入图片描述

    推荐我们的Python学习扣qun:913066266 ,看看前辈们是如何学习的!从基础的python脚本到web开发、爬虫、django、数据挖掘等【PDF,实战源码】,零基础到项目实战的资料都有整理。送给每一位python的小伙伴!每天都有大牛定时讲解Python技术,分享一些学习的方法和需要注意的小细节,点击加入我们的 python学习者聚集地

    展开全文
  • python实现聚类分析

    千次阅读 2021-04-29 11:31:39
     这里较为详细介绍了聚类分析的各种算法和评价指标,本文将简单介绍如何用python里的库实现它们。 二、k-means算法  和其它机器学习一样,实现聚类分析也可以调用sklearn中的借口。 from sklearn.cluster import ...

    一、简介

    这里较为详细介绍了聚类分析的各种算法和评价指标,本文将简单介绍如何用python里的库实现它们。

    二、k-means算法

     和其它机器学习算法一样,实现聚类分析也可以调用sklearn中的接口。

    from sklearn.cluster import KMeans
    

    2.1 模型参数

    KMeans(
    	# 聚类中心数量,默认为8
        n_clusters=8,
        
        *,
        
        # 初始化方式,默认为k-means++,可选‘random’,随机选择初始点,即k-means
        init='k-means++',
        
        # k-means算法会随机运行n_init次,最终的结果将是最好的一个聚类结果,默认10
        n_init=10,
        
        # 算法运行的最大迭代次数,默认300
        max_iter=300,
        
        # 容忍的最小误差,当误差小于tol就会退出迭代(算法中会依赖数据本身),默认为0.0001
        tol=0.0001,
        
        # 是否将数据全部放入内存计算,可选{'auto', True, False},开启时速度更快但是更耗内存
    	# 'auto' : 当n_samples * n_clusters > 12million,不放入内存,否则放入内存,double精度下大概要多用100M的内存
        precompute_distances='deprecated',
    	
    	# 是否输出详细信息,默认为0
        verbose=0,
        
        # 用于随机产生中心的随机序列
        random_state=None,
    
    	# 是否直接在原矩阵上进行计算
        copy_x=True,
    
    	# 同时进行计算的核数(并发数),n_jobs用于并行计算每个n_init,如果设置为-1,使用所有CPU,若果设置为1,不并行,如果设置小于-1,使用CPU个数+1+n_jobs个CPU
        n_jobs='deprecated',
    
    	# 可选的K-means距离计算算法, 可选{"auto", "full" or "elkan",default="auto"}
    	# full为欧式距离,elkan为使用三角不等式,效率更高,但不支持稀疏矩阵,当为稀疏矩阵时,auto使用full,否则使用elkan
        algorithm='auto',
    )
    

    2.2 常用模型方法

    • fit(X)——对数据X进行聚类
    • predict(X)——对新数据X进行类别的预测
    • cluster_centers_——获取聚类中心
    • labels_——获取训练数据所属的类别,比设置的聚类中心个数少1
    • inertia_——获取每个点到聚类中心的距离和
    • fit_predict(X)——先对X进行训练并预测X中每个实例的类,等于先调用fit(X)后调用predict(X),返回X的每个类
    • transform(X)——将X进行转换,转换为K列的矩阵,其中每行为一个实例,每个实例包含K个数值(K为传入的类数量),第i列为这个实例到第K个聚类中心的距离
    • fit_transform(X)——先进行fit之后进行transform
    • score(X)——输入样本(这里的样本不是训练样本,而是其他传入的测试样本)到他们的类中心距离和,然后取负数

    2.3 实际例子

    # 以two_moons数据为例
    from sklearn.datasets import make_blobs
    # 生成模拟的二维数据, X.shape——>(100, 2)
    X, y = make_blobs(random_state=1)
    
    # 设置为三个聚类中心
    Kmeans = KMeans(n_clusters=3)
    # 训练模型
    Kmeans.fit(X)
    

    2.3.1 获取聚类中心:

    Kmeans.cluster_centers_
    

    输出

    array([[ -1.4710815 ,   4.33721882],
           [ -6.58196786,  -8.17239339],
           [-10.04935243,  -3.85954095]])
    

    2.3.2 获取类别

    Kmeans.labels_
    

    输出:我们设置了3个聚类中心,所以输出3个类别。

    array([0, 2, 2, 2, 1, 1, 1, 2, 0, 0, 2, 2, 1, 0, 1, 1, 1, 0, 2, 2, 1, 2,
           1, 0, 2, 1, 1, 0, 0, 1, 0, 0, 1, 0, 2, 1, 2, 2, 2, 1, 1, 2, 0, 2,
           2, 1, 0, 0, 0, 0, 2, 1, 1, 1, 0, 1, 2, 2, 0, 0, 2, 1, 1, 2, 2, 1,
           0, 1, 0, 2, 2, 2, 1, 0, 0, 2, 1, 1, 0, 2, 0, 2, 2, 1, 0, 0, 0, 0,
           2, 0, 1, 0, 0, 2, 2, 1, 1, 0, 1, 0], dtype=int32)
    

    2.3.3 获取每个点到聚类中心的距离和

    Kmeans.inertia_
    

    输出

    156.28289251170003
    

    三、mini batch k-means算法

     mini batch k-means的用法和k-means类似。

    from sklearn.cluster import MiniBatchKMeans
    

    3.1 模型参数

    MiniBatchKMeans(
        n_clusters=8,
        *,
        init='k-means++',
        max_iter=100,
    
    	# 每次采用数据集的大小
        batch_size=100,
        verbose=0,
    	
    	# 计算训练样本的类
        compute_labels=True,
        random_state=None,
        tol=0.0,
    
    	# 多少次迭代中质心没有变化,算法终止,默认10次
        max_no_improvement=10,
    
    	# 用来候选质心的样本数据集大小,默认为batch_size的三倍
        init_size=None,
    
    	# 用不同的初始化质心运行算法的次数。
    	# 这里和KMeans类意义稍有不同,KMeans类里的n_init是从相同训练集数据中随机初始化质心。
    	# 而MiniBatchKMeans类的n_init则是每次用不一样的采样数据集来跑不同的初始化质心运行。默认为3。
        n_init=3,
    
    	# 某个类别质心被重新赋值的最大次数比例,为了控制算法的运行复杂度。分母为样本总数。如果取值较高的话算法收敛时间可能会增加,尤其是那些暂时拥有样本数较少的质心。默认是0.01。
        reassignment_ratio=0.01,
    )
    

    四、层次聚类算法

     同样使用sklearn接口

    from sklearn.cluster import AgglomerativeClustering
    

    4.1 模型参数

    AgglomerativeClustering(
    	# 聚类中心的数量,默认为2
        n_clusters=2,
        *,
    
    	# 用于计算距离。可以为:’euclidean’,’l1’,’l2’,’mantattan’,’cosine’,’precomputed’,
    	# 如果linkage=’ward’,则affinity必须为’euclidean’
        affinity='euclidean',
    
    	# 用于缓存输出的结果,默认为不缓存
        memory=None,
        connectivity=None,
    
    	# 通常当训练了n_clusters后,训练过程就会停止,但是如果compute_full_tree=True,则会继续训练从而生成一颗完整的树
        compute_full_tree='auto',
    
    	# 计算两个簇之间的距离的方式,可选{'ward', 'complete', 'average', 'single'}
    	# 'ward':挑选两个簇来合并,使得所有簇中的方差增加最小
    	# 'complete':将簇中点之间最大距离最小的两个簇合并
    	# 'average':将簇中所有点之间平均距离最小的两个簇合并
    	# 'single':将簇中点之间最小距离最小的两个簇合并
        linkage='ward',
    
    	# 链接距离阈值,在该阈值以上,簇将不会合并
    	# 如果不为None,那么n_clusters必须是None,而且compute_full_tree必须为True
        distance_threshold=None,
    
    	# 计算簇之间的距离,可使树状图可视化
        compute_distances=False,
    )
    

    4.2 模型常用方法

    • fit(X)——对数据X进行聚类
    • labels_——获取训练数据所属的类别,比设置的聚类中心个数少1
    • n_leaves_——层次树中的叶子数
    • children_——一个大小为[n_samples-1,2]的数组,给出了每个非叶结点中的子节点数量
    • fit_predict(X)——先对X进行训练并预测X中每个实例的类,等于先调用fit(X)后调用predict(X),返回X的每个类,该模型不能对新的数据点进行预测
    • n_components_——一个整数,给出了连接图中的连通分量的估计

    4.3 实际例子

    from sklearn.cluster import AgglomerativeClustering
    from sklearn.datasets import make_blobs
    
    X, y = make_blobs(random_state=1)
    agg = AgglomerativeClustering(n_clusters=3)
    agg.fit_predict(X)
    

    输出:对数据训练并预测

    array([0, 2, 2, 2, 1, 1, 1, 2, 0, 0, 2, 2, 1, 0, 1, 1, 1, 0, 2, 2, 1, 2,
           1, 0, 2, 1, 1, 0, 0, 1, 0, 0, 1, 0, 2, 1, 2, 2, 2, 1, 1, 2, 0, 2,
           2, 1, 0, 0, 0, 0, 2, 1, 1, 1, 0, 1, 2, 2, 0, 0, 2, 1, 1, 2, 2, 1,
           0, 1, 0, 2, 2, 2, 1, 0, 0, 2, 1, 1, 0, 2, 0, 2, 2, 1, 0, 0, 0, 0,
           2, 0, 1, 0, 0, 2, 2, 1, 1, 0, 1, 0])
    

    4.3.1 获取层次树中的叶子数

    agg.n_leaves_
    

    输出

    100
    

    4.3.2 获取每个非叶结点中的子节点数量

    agg.children_
    

    输出

    array([[ 33,  68],
           [ 35,  39],
           [ 18,  21],
           [ 30,  92],
           [ 54,  58],
           [ 49, 100],
           [ 26,  55],
           [ 23,  27],
           [ 20,  45],
           [  3,  82],
           [  1,  71],
           [ 16,  52],
           [ 24,  38],
           [ 22,  77],
           [  9,  59],
           [ 44,  69],
           [ 40, 106],
           [ 15,  90],
           [ 36,  94],
           [ 53,  61],
           [ 72, 108],
           [ 37,  43],
           [ 17,  78],
           [ 60,  70],
           [ 50, 102],
           [ 76,  98],
           [107, 114],
           [ 56,  93],
           [  7, 110],
           [ 63, 112],
           [  8,  66],
           [ 11, 109],
           [ 42,  84],
           [  5,   6],
           [ 19, 121],
           [ 97, 104],
           [ 91, 105],
           [ 79,  88],
           [ 46,  73],
           [113, 116],
           [ 89, 132],
           [ 85,  87],
           [ 10,  41],
           [ 29,  51],
           [ 12,  96],
           [ 34, 118],
           [ 32, 144],
           [115, 123],
           [ 31,  48],
           [ 62, 125],
           [ 13, 130],
           [ 81, 134],
           [103, 135],
           [  0,  28],
           [ 75, 142],
           [120, 133],
           [ 65, 117],
           [ 47,  99],
           [127, 137],
           [101, 139],
           [122, 136],
           [ 74, 138],
           [140, 148],
           [ 80, 161],
           [111, 119],
           [155, 156],
           [124, 129],
           [131, 147],
           [ 64, 151],
           [141, 157],
           [ 83,  95],
           [143, 146],
           [  2, 168],
           [ 67, 164],
           [149, 170],
           [ 86, 150],
           [  4,  14],
           [128, 154],
           [158, 167],
           [ 25, 171],
           [159, 165],
           [160, 162],
           [153, 169],
           [ 57, 145],
           [126, 152],
           [163, 184],
           [166, 177],
           [173, 180],
           [178, 183],
           [175, 185],
           [174, 187],
           [176, 179],
           [172, 188],
           [181, 189],
           [186, 192],
           [190, 191],
           [182, 193],
           [194, 195],
           [196, 197]])
    
    

    4.3.3 可视化

     目前scikit-learn 没有绘制树状图的功能,但可以利用SciPy轻松生成树状图。SciPy的聚类算法接口与scikit-learn 的聚类算法稍有不同。SciPy提供了一个函数,接受数据数组X并计算出一个链接数组(linkage array),它对层次聚类的相似度进行编码。然后我们可以将这个链接数组提供给scipydendrogram 函数来绘制树状图。

    # 从SciPy中导入dendrogram函数和ward聚类函数
    from scipy.cluster.hierarchy import dendrogram, ward
    X, y = make_blobs(random_state=0, n_samples=12)
    
    # 将ward聚类应用于数据数组X
    # SciPy的ward函数返回一个数组,指定执行凝聚聚类时跨越的距离
    linkage_array = ward(X)
    
    # 现在为包含簇之间距离的linkage_array绘制树状图
    dendrogram(linkage_array)
    
    # 在树中标记划分成两个簇或三个簇的位置
    ax = plt.gca()
    bounds = ax.get_xbound()
    ax.plot(bounds, [7.25, 7.25], '--', c='k')
    ax.plot(bounds, [4, 4], '--', c='k')
    
    ax.text(bounds[1], 7.25, ' two clusters', va='center', fontdict={'size': 15})
    ax.text(bounds[1], 4, ' three clusters', va='center', fontdict={'size': 15})
    plt.xlabel("Sample index")
    plt.ylabel("Cluster distance")
    

    输出
    在这里插入图片描述

    五、DBSCN算法

    from sklearn.cluster import DBSCAN
    

    5.1 模型参数

    DBSCAN(
    
    	# 数据点的邻域距离阈值(半径)
        eps=0.5,
        *,
    
    	# 数据点半径为eps的邻域中数据点个数的最小个数
        min_samples=5,
    
    	# 可使用'euclidean', 'manhattan','chebyshev', 'minkowski”'
        metric='euclidean',
        metric_params=None,
    
    	# 最近邻搜索算法, 可选'auto', 'ball_tree', 'kd_tree', 'brute'
    	# 'brute'是使用蛮力搜索,一般使用'auto'即可,会自动拟合最好的最优算法
    	# 如果数据量很大或者特征也很多,用'auto'建树时间可能会很长,效率不高,建议选择KD树实现'kd_tree'
    	# 如果发现‘kd_tree’速度比较慢或者已经知道样本分布不是很均匀时,可以尝试用‘ball_tree’
    	# 如果输入样本是稀疏的,无论你选择哪个算法最后实际运行的都是‘brute’。
        algorithm='auto',
    
    	# 使用KD树或者球树时, 停止建子树的叶子节点数量的阈值
    	# 这个值越小,则生成的KD树或者球树就越大,层数越深,建树时间越长,反之,则生成的KD树或者球树会小,层数较浅,建树时间较短
    	# 这个值一般只影响算法的运行速度和使用内存大小,因此一般情况下可以不管它。
        leaf_size=30,
        p=None,
        n_jobs=None,
    )
    

    5.2 模型常用方法

    • fit(X)——对数据X进行聚类
    • labels_——获取训练数据所属的类别,噪声点为-1
    • fit_predict(X)——先对X进行训练并预测X中每个实例的类,等于先调用fit(X)后调用predict(X),返回X的每个类,该模型不能对新的数据点进行预测

    六、聚类指标

    6.1 RI 与 ARI

    # RI 兰德指数
    from sklearn.metrics.cluster import rand_score
    
    # ARI 调整兰德指数
    from sklearn.metrics.cluster import adjusted_rand_score
    

    6.1.1 模型参数

    rand_score(labels_true, labels_pred)
    adjusted_rand_score(labels_true, labels_pred)
    

    6.1.2 示例

    rand_score([0, 0, 1, 1], [1, 1, 0, 0])
    adjusted_rand_score([0, 0, 1, 1], [1, 1, 0, 0])
    

    输出

    1.0
    1.0
    

    6.2 NMI

    from sklearn.metrics.cluster import normalized_mutual_info_score
    

    6.2.1 模型参数

    normalized_mutual_info_score(
        labels_true,
        labels_pred,
        *,
        average_method='arithmetic',
    )
    

    6.2.2 示例

    normalized_mutual_info_score([0, 0, 1, 1], [1, 1, 0, 0])
    

    输出

    1.0
    

    6.3 Jaccard系数

    from sklearn.metrics import jaccard_score
    

    6.3.1 模型参数

    jaccard_score(
        y_true,
        y_pred,
        *,
        labels=None,
        pos_label=1,
        average='binary',
        sample_weight=None,
        zero_division='warn',
    )
    

    6.3.2 示例

    jaccard_score([0, 0, 1, 1], [0, 0, 1, 1])
    jaccard_score([0, 0, 1, 1], [1, 1, 0, 0])
    

    输出:在使用前,需要转化为相同的类别标识

    1.0
    0.0
    

    6.4 轮廓系数

    from sklearn.metrics.cluster import silhouette_score
    

    6.4.1 模型参数

    silhouette_score(
        X,
        labels,
        *,
        metric='euclidean',
    
    	# 在数据的随机子集上计算轮廓系数时要使用的样本大小
        sample_size=None,
        random_state=None,
        **kwds,
    )
    

    6.4.2 示例

    silhouette_score(X, agg.labels_)
    

    输出agg.labels_为用AgglomerativeClustering算法对数据集X进行的聚类

    0.5811444237627902
    

    6.5 CH指标

    from sklearn.metrics.cluster import calinski_harabasz_score
    

    6.5.1 模型参数

    calinski_harabasz_score(X, labels)
    

    6.5.2 示例

    calinski_harabasz_score(X, agg.labels_)
    

    输出

    26.268277404270318
    
    展开全文
  • 聚类分析的方法非常多,能够理解经典又最基础的聚类方法 —— 层次聚类法(系统聚类) 的基本原理并将代码用于实际的业务案例是本文的目标,同时这也会为理解后续与聚类相关的推文如 K-Means 等打下基础是。...

    前言

    聚类分析是研究分类问题的分析方法,是洞察用户偏好和做用户画像的利器之一。聚类分析的方法非常多,能够理解经典又最基础的聚类方法 —— 层次聚类法(系统聚类) 的基本原理并将代码用于实际的业务案例是本文的目标,同时这也会为理解后续与聚类相关的推文如 K-Means 等打下基础是。

    本文将详细介绍如何 利用 Python 实现基于层次聚类的客户分群,主要分为两个部分:

    层次聚类详细原理介绍

    Python 代码实战讲解

    原理部分

    原理介绍

    既然它们能被看成是一类的,所以要么它们距离近,要么它们或多或少有共同的特征。拿到数据集后,直接根据特征或指标来将样本分类的做法其实更适合业务能力比较强的人或有了十分明确的指标如男女各一类等硬性要求,所以本文以样本之间的距离为聚类指标。为了能够更好地深入浅出,我们调整了一下学习顺序,将小部分数学公式往后放,先从聚类结果的显示与分析入手。

    下面是有关层次聚类的几个常见问题。

    1、为什么都说层次树是层次聚类法独有的聚类结果图?

    因为树形图的横坐标会将每一个样本都标出来,并展示聚类的过程。几十个样本时候层次树就已经 “无法” 查看了,更何况成百上千的数据样本。

    c089a9f709fb6b0ef887178737c28b24.png

    2、层次树是怎么建立的?建立的基本步骤?

    其实层次树的建立过程表示的就是聚类的过程,只不过通过层次树我们可以看出类之间的层次关系(这一类与那一类相差多远),同时还可以通过层次树决定最佳的聚类个数和看出聚类方式(聚类顺序的先后)

    基本步骤比较简洁,只要短短的 3 步:

    计算每两个观测之间的距离

    将最近的两个观测聚为一类,将其看作一个整体计算与其它观测(类)之间的距离

    一直重复上述过程,直至所有的观测被聚为一类

    建立层次树的三个步骤虽然简洁,但其实也有令人迷惑的地方,所以为了让各位更好的从整体上去理解聚类过程而不是圄于细节,这里先直接放一个聚类过程图和对应的层次树

    e93b8f94cc6df38019ac78dcc4c2b609.png

    3、怎么从层次树中看出聚类过程?

    这一个简短的问题中其实暗含不少门道,第一:**当两个点被分为一类时,是从横坐标出发向上延伸,后形成一条横杠;当两个类被分为一类时,是横杠中点向上延伸。**这第一点中,横杠的数量就表示当所有的点都被圈为一类的时候经过了多少次聚类。

    f5e324d4c254a3d4d24db488322ed9f7.png

    同样,横杠距离横坐标轴的高度也有玄机,毕竟每生成一个横杠就表示又有一次聚类了,所以我们可以通过横杠的高度判断聚类的顺序,结合上图右半部分的圆圈和数字标号也可以看出。

    e21249db0f24bd1049d32d2a997ebdca.png

    所以聚类顺序便如下表:

    聚类次数

    被聚为一类的点

    第1次

    1和3     →    1,3

    第2次

    2和5     →     2,5

    第3次

    2,5 和 4   →   2,5,4

    第4次

    2,5,4 和 1,3   →   1,3,2,5,4

    第5次

    1,3,2,5,4 和 6   →   1,3,2,5,4,6(所有点被聚为一类)

    第二,整棵层次树是由一棵棵小树组成,每棵小树代表了一个类,小树的高度即是两个点或两个类之间的距离,所以两个点之间的距离越近,这棵树就越矮小。

    2375718416306932817933a67fc87225.png

    下面这一段仔细阅读的话对理解点与点,类与类,点与类之间的距离是如何在层次树上体现很有帮助。先从最矮的高度只有 d1 小树说起,这就是类 1,3 中两个孤立的点 1 和 3 之间的距离;同理,d2 为类2,5 中点 2 和 5 之间的距离。

    而至于 d3, d4, d5 这三个距离,他们并不像 d1 和 d2 那般表示的是一棵完整的树的高度,而更像是 “ 生长的枝干 ”,因为从第一点中的 “ 当两个类被分为一类时,是横杠中点向上延伸。” 可以看出 d3 是从类 2,5 横杠的中点往上延伸的,所以它表示会与另外的类聚成一起并形成一棵更大的树,图中即类 2,5 和点 4 被聚成一个新的类 2,5,4。

    同理:

    d4 表示类 2,5,4 与类 1,3 聚成新类 1,3,2,5,4

    d5 表示类 1,3,2,5,4 与点 6 聚成类 1,3,2,5,4,6

    4、怎么从层次树中看出聚类情况?可以通过决定纵轴分界线可决定这些数据到底是分成多少类

    fe0cfaf91481d6637ee09ed308ae070a.png定好分界线后,只需要看距离这条线横杠和单独的竖线即可,上图中距离红线的横杠有两条(分别表示类1,2 和类2,5),单独的竖线也有两条,从横坐标轴 4 和 6 上各延伸出的一条。同理可用到下图

    19ec44d22c1dca75fd43e5834102e0dd.png

    为什么最好不要分成 3 组:13,254,6 呢?

    因为树的高度表示两个点之间的距离,所以 4 到 类25 的距离只比到 类13 的距离要多如下图所示的一点点,所以硬是把 4 跟 25 分成一类就有点牵强了,正因为这种牵强的分类方式可能会让我们忽略 4 这个点单独的价值,所以我们不如直接将 4 看成单独的一类。

    603148c11d9d51594c5e01a2655a0af2.png

    推导与计算

    接下来就是需要更加动脑的数学原理和公式部分了,我们需要知晓点与点,类与类,点与类这三种距离如何计算。

    c750fcf9e030e4e7a07f2e6d702ba6ed.png

    最包罗万象的是明考斯基距离,因为 q 分别取 1 和 2 的时候就表示是绝对值距离和欧氏距离。点与点的距离很好求,我们一般用的都是欧氏距离,即初中学习的直角三角形三边关系,上图右上角点AC之间的距离(ab² + bc²) 后再开根号

    而至于类与类之间的距离求法,其实经过了一个演变,篇幅原因本文只会一笔带过那些不常用的方法并将重心放在最常用和主流的方法上。

    735c85cb7307c50a99ff4ca20e1ae28e.png

    平均联接和重心法都已经比较少用了,现大多采用较少受异常值影响且不知数据分布的情况下依然能有较好表现的 Ward 法。

    803242dce31abdbecc6cd30c32718b1e.png

    其实 Ward 法的公式与方差分析相似,都是通过组间距离来定夺点点/点类/类类间的距离,Ward 法许多详细的数学推导在网上有很多,这里我们直接展示最容易理解的一种:

    7bba790a015c982bb16b68342c437752.png上图为已知的五个点和它们 x,y 轴坐标,SS 为 Ward 最小方差法的公式。

    d876a91ef38b84b4b6fe924c0768804a.png

    当两个点被聚为一类时,这一类的组间差异 SS 便为其中一点的某一坐标与另外的所有坐标加加减减的一系列操作(通俗解释,其实直接看上图的 SS 计算过程已经可以理解。)

    了解 Ward 最小方差法的基本求解公式后,我们可以从最简单的聚类形式开始:5个点聚成4类。这意味着其中两个点会被聚在一起,剩下三个点各自为一类,所以总共会出现 C52 = 10 中情况,每种情况的组内 SS 分别如下表:

    4a0c7bdde73ac658ecfc78925f1f9187.png同理,如果这 5 个点聚成 3/2/1 类的情况如下表:

    f67621fa62ce616c0da1d31916cbd8f9.png需要注意的是:聚成两类后计算出 AB 这两个的利方差最小后,在后续聚成3类,2类的时候就直接把A和B两个看成是同一个个体了,所以不会再出现A和B分开的局面。

    结合两个表,我们便可以得出如下结论:

    如果需要被

    聚成 4 类,AB为一类,剩下3个点各为一类最好(SS 最小)

    如果需要被

    聚成 3 类,AB,DE为一类,剩下的 C 单独为一类最好

    如果需要被

    聚成 2 类,AB,CDE各位一类

    如果需要被

    聚成 1 类,对不起,我觉得没什么分析的必要

    在进入代码实战前,我们简单总结一下原理部分提到的知识点:

    层次树的阅读

    两个点之间的距离公式

    Ward 法求类内的组间差异,用以决定聚出的类别个数

    代码实战

    在正式实战前,需要注意以下几点,首先原始数据通常需要经过处理才能用于分析:

    缺失值

    异常值(极大或极小)

    分类变量需要转化为哑变量(0/1数值)

    分类变量类别不宜过多

    其次由于变量的量纲的不一样引起计算距离的偏差,我们需要对数据进行标准化。同时不同的统计方法对数据有不同的要求:

    决策树和随机森林允许缺失值和异常值

    聚类分析和回归模型则不支持缺失值

    在处理数据时,也有两个问题值得关注,

    1、聚类的时候,所有的 X 必须都是连续变量,为什么?

    分类变量无法计算距离,如某个变量表示的是性别,男和女;教育程度为小学,初中,高中,大学,那该变量在各个个体之间的距离怎么计算?所以做聚类分析时尽可能用分类变量。

    2、那这些分类变量的价值难道就无法利用了吗?

    可以先根据其他的连续变量聚类,而后对分出来的类做描述性统计分析,这时候就可以用上分类变量的价值了。另外一种方法是可以在第一步就把分类变量也用上的聚类方法,不过需要结合实际业务。

    以市场客户调研为例,属于 “ 客户的需求与态度 ” 这个分支,目的是依据调查问卷结果针对需求的数据分群,而调查分卷的问题中回答 “yes” 或者 “no” 类型的问题通常又会占一大部分,这时候我么可以通过合并多个问题回答的结果来将多个分类变量组合,生成一个连续变量,以电信客户的使用和需求情况为例:

    72975b952689a41257f910d0f66551a9.png当然也还可以计算分类变量之间的 cos 相似度,即直接把分类变量设成距离。总之,分类变量在聚类当中是一定需要处理的。

    现在终于到了正式的代码阶段,如果前面的原理都理解好了,代码的理解则可不费吹灰之力。这里我们使用一份公开的城市经济数据集,参数如下:

    AREA:城市名称

    Gross:总体经济情况指数

    Avg:平均经济情况指数

    import pandas as pd

    import numpy as np

    import matplotlib.pyplot as plt

    plt.rc('font', **{'family': 'Microsoft YaHei, SimHei'})  # 设置中文字体的支持

    plt.rcParams['axes.unicode_minus'] = False

    # 解决保存图像是负号'-'显示为方块的问题

    df = pd.read_csv('城市经济.csv')

    df

    ce1bbc26563fb9337136f93262eaa34c.png这些城市的指标分布如下波士顿矩阵图,篇幅原因绘图代码省略,后台回复关键字获取的源程序会一并提供。

    aea8a724151273bfa09fcfd2d3cb622c.pngsklearn 里面没有层次聚类的函数,所以从 scipy 中导入

    import scipy.cluster.hierarchy as sch

    # 生成点与点之间的距离矩阵, 这里用的欧氏距离: euclidean

    ## X:根据什么来聚类,这里结合总体情况 Gross 与平均情况 Avg 两者

    disMat = sch.distance.pdist(X=df[['Gross', 'Avg']], metric='euclidean')

    # 进行层次聚类: 计算距离的方法使用 ward 法

    Z = sch.linkage(disMat,method='ward')

    下面是层次聚类可视化:层次树

    # 将层级聚类结果以树状图表示出来并保存

    # 需要手动添加标签。

    P = sch.dendrogram(Z, labels=df.AREA.tolist())

    plt.savefig('聚类结果.png')

    c51a578489b74af0ee4a5ab36e0167b0.png

    最后说一下,未来还会有 K-Means 等聚类方法的推文。作为深入浅出聚类方法的开端,我们只需知道层次聚类相比 K-Means 的好处是它不用事先指定我们需要聚成几类 (K-Means 算法代码中的参数 k 指定)

    这样一来,我们只需要把计算全权交给程序,最终能得出一个比较精准的结果。但缺点是随之而来的计算复杂度的增加。

    所以层次聚类更适合小样本;K-Means 更适合大样本,在数据挖掘中也更常见,本文分享就到这里,我们下期决策树见~

    展开全文
  • Python中的凝聚层次聚类示例

    千次阅读 2019-01-02 09:19:07
    层次聚类算法将相似的对象分组到称为聚类的组中。层次聚类算法有两种: 凝聚(Agglomerative )-自下而上的方法。从许多小聚类开始,然后将它们合并到一起,创建更大的聚类。 分裂 (Divisive )- 自上而下的方法...
  • 在整本书上应用层次聚类,以尝试在角色中找到社群。使用AGNES算法对字符进行聚类。对不同聚类方案进行人工检查发现最优聚类,因为更频繁出现的角色占主导地位最少。这是六个簇的树形图:ag (cat2[,-1], method=...
  • 24、python分层聚类案例(scipy方法)

    千次阅读 2019-01-03 14:31:47
     层次聚类算法又称为树聚类算法,它根据数据之间的距离,透过一种层次架构方式,反复将数据 进行聚合,创建一个层次以分解给定的数据集。 2、方法 01 聚类方法 linkage=scipy.cluster.hierarchy.linkage(data,...
  • 1 sklearn层次聚类 01 ward  最小化所有聚类内的平方差总和,这是一种方差最小化的优化方向,这是与k-means的目标韩式相似的优化方法,但是用聚类分层的方法处理。 02 Maximum 或者complete linkage 最小化聚类...
  • 聚类分析的方法非常多,能够理解经典又最基础的聚类方法 —— 层次聚类法(系统聚类) 的基本原理并将代码用于实际的业务案例是本文的目标,同时这也会为理解后续与聚类相关的推文如 K-Means 等打下基础。 本文将详细...
  • python 聚类分析

    2020-11-30 07:05:27
    scipy.cluster是scipy下的一个做聚类的package, 共包含了两类聚类方法: 1. 矢量量化(scipy.cluster.vq):... 层次聚类(scipy.cluster.hierarchy):支持hierarchical clustering 和 agglomerative clustering(凝聚聚...
  • 一文读懂层次聚类Python代码)

    千次阅读 2021-11-21 21:20:01
    本篇想和大家介绍下层次聚类,先通过一个简单的例子介绍它的基本理论,然后再用一个实战案例Python代码实现聚类效果。 首先要说,聚类属于机器学习的无监督学习,而且也分很多种方法,比如大家熟知的有K-means。层次...
  • from scipy.cluster import hierarchy0.层次聚类的概念层次聚类和k-means一样都是很常用的聚类方法。...层次聚类又分为自底而上的聚合层次聚类和自顶而下的分裂层次聚类。0.1 聚合层次聚类每一个点初始为1类,得到N(...
  • 聚类聚类分析通常被用作数据分析技术,用于发现数据中的有趣模式,例如基于其行为的客户群。有许多聚类算法可供选择,对于所有情况,没有单一的最佳聚类算法。聚类聚类分析是无监督学习问题。它通常被用作数据...
  • 分享给大家供大家参考,具体如下:菜鸟一枚,编程初学者,最近想使用Python3实现几个简单的机器学习分析方法,记录一下自己的学习过程。关于KMeans算法本身就不做介绍了,下面记录一下自己遇到的问题。一 、关于初始...
  • 引言: 数据挖掘的本质是“计算机根据已有的数据做出决策”,其对社会的价值... 算法是数据挖掘最核心的部分,作为一名学习新人,在参考《数据挖掘导论》、《Python数据分析与挖掘实战》、《Python数据挖掘入门与实战
  • 聚类分析案例

    千次阅读 2020-12-20 11:35:21
    一、数据挖掘的常用方法利用数据挖掘进行数据分析常用的方法主要有分类、回归分析聚类、关联规则、特征、变化和偏差分析、Web页挖掘等,它们分别从不同的角度对数据进行挖掘。分类。分类是找出数据库中一组数据...
  • 聚类分析是没有给定划分类别的情况下,根据样本相似度进行样本分组的一种方法,是一种非监督的学习算法。聚类的输入是一组未被标记的样本,聚类根据数据自身的距离或相似度划分为若干组,划分的原则是组内距离最小化...
  • 根据机器学习中“层次聚类算法”的原理,我用python代码实现了一个具体的例子。层次聚类算法只能单独处理“连续变量”或者“离散变量”,这个实例中实现了仅针对“连续变量”的例子。 需要在聚类前进行最大最小归一...
  • 层次聚类分析

    千次阅读 2017-11-08 00:36:00
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • 点击上方,选择星标,每天给你送干货!来源:海豚数据科学实验室著作权归作者所有,本文仅作学术分享,若侵权,请联系后台删文处理聚类聚类分析是无监督学习问题。它通常被用作数据分析技术,用于发现...
  • 本文是萝卜的Python数据挖掘实战的第7篇1 - 基于不平衡数据的反欺诈模型实战2 - Apriori算法实现智能推荐3- 随机森林预测宽带客户离网4 - 多元线性回归模型实战5 -...
  • 作者:Pulkit Sharma 翻译:陈超 校对:吴振东本文约4700字,建议阅读15分钟本文从对比无监督学习和监督学习的特征切入,结合具体的案例来给大家介绍层级聚类的概念、应用场景、主要类型以及Python实现。引言理解...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,045
精华内容 818
关键字:

python层次聚类分析案例

python 订阅