精华内容
下载资源
问答
  • 主要为大家详细介绍了Python实现简单层次聚类算法以及可视化,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 主要介绍了Python聚类算法之凝聚层次聚类的原理与具体使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • 层次聚类算法介绍假设有 n 个待聚类的样本,对于层次聚类算法,它的步骤是:步骤一:(初始化)将每个样本都视为一个聚类;步骤二:计算各个聚类之间的相似度;步骤三:寻找最近的两个聚类,将他们归为一类;步骤四:...

    起步

    层次聚类( Hierarchical Clustering )是聚类算法的一种,通过计算不同类别的相似度类创建一个有层次的嵌套的树。

    32863.html

    层次聚类算法介绍

    假设有 n 个待聚类的样本,对于层次聚类算法,它的步骤是:

    步骤一:(初始化)将每个样本都视为一个聚类;

    步骤二:计算各个聚类之间的相似度;

    步骤三:寻找最近的两个聚类,将他们归为一类;

    步骤四:重复步骤二,步骤三;直到所有样本归为一类。

    79f3f00b0ae61ff93a007e005769d7f7.png

    整个过程就是建立一棵树,在建立的过程中,可以在步骤四设置所需分类的类别个数,作为迭代的终止条件,毕竟都归为一类并不实际。

    聚类之间的相似度

    聚类和聚类之间的相似度有什么来衡量呢?既然是空间中的点,可以采用距离的方式来衡量,一般有下面三种:

    Single Linkage

    又叫做 nearest-neighbor ,就是取两个类中距离最近的两个样本的距离作为这两个集合的距离。这种计算方式容易造成一种叫做 Chaining 的效果,两个 cluster 明明从“大局”上离得比较远,但是由于其中个别的点距离比较近就被合并了,并且这样合并之后 Chaining 效应会进一步扩大,最后会得到比较松散的 cluster 。

    Complete Linkage

    这个则完全是 Single Linkage 的反面极端,取两个集合中距离最远的两个点的距离作为两个集合的距离。其效果也是刚好相反的,限制非常大。这两种相似度的定义方法的共同问题就是指考虑了某个有特点的数据,而没有考虑类内数据的整体特点。

    Average Linkage 这种方法就是把两个集合中的点两两的距离全部放在一起求均值,相对也能得到合适一点的结果。有时异常点的存在会影响均值,平常人和富豪平均一下收入会被拉高是吧,因此这种计算方法的一个变种就是取两两距离的中位数。

    python 实现层次聚类

    空间中点的距离使用欧式距离:

    import math

    import numpy as np

    def euler_distance(point1: np.ndarray, point2: list) -> float:

    """

    计算两点之间的欧拉距离,支持多维

    """

    distance = 0.0

    for a, b in zip(point1, point2):

    distance += math.pow(a - b, 2)

    return math.sqrt(distance)

    定义聚类数的节点:

    class ClusterNode(object):

    def __init__(self, vec, left=None, right=None, distance=-1, id=None, count=1):

    """

    :param vec: 保存两个数据聚类后形成新的中心

    :param left: 左节点

    :param right: 右节点

    :param distance: 两个节点的距离

    :param id: 用来标记哪些节点是计算过的

    :param count: 这个节点的叶子节点个数

    """

    self.vec = vec

    self.left = left

    self.right = right

    self.distance = distance

    self.id = id

    self.count = count

    vec 表示合并后的聚类中心,是一个点,代表整个聚类的位置;distance 表示左节点和右节点的距离。

    计算层次聚类算法的类:

    class Hierarchical(object):

    def __init__(self, k = 1):

    assert k > 0

    self.k = k

    self.labels = None

    def fit(self, x):

    nodes = [ClusterNode(vec=v, id=i) for i,v in enumerate(x)]

    distances = {}

    point_num, future_num = np.shape(x) # 特征的维度

    self.labels = [ -1 ] * point_num

    currentclustid = -1

    while len(nodes) > self.k:

    min_dist = math.inf

    nodes_len = len(nodes)

    closest_part = None # 表示最相似的两个聚类

    for i in range(nodes_len - 1):

    for j in range(i + 1, nodes_len):

    # 为了不重复计算距离,保存在字典内

    d_key = (nodes[i].id, nodes[j].id)

    if d_key not in distances:

    distances[d_key] = euler_distance(nodes[i].vec, nodes[j].vec)

    d = distances[d_key]

    if d < min_dist:

    min_dist = d

    closest_part = (i, j)

    # 合并两个聚类

    part1, part2 = closest_part

    node1, node2 = nodes[part1], nodes[part2]

    new_vec = [ (node1.vec[i] * node1.count + node2.vec[i] * node2.count ) / (node1.count + node2.count)

    for i in range(future_num)]

    new_node = ClusterNode(vec=new_vec,

    left=node1,

    right=node2,

    distance=min_dist,

    id=currentclustid,

    count=node1.count + node2.count)

    currentclustid -= 1

    del nodes[part2], nodes[part1] # 一定要先del索引较大的

    nodes.append(new_node)

    self.nodes = nodes

    self.calc_label()

    def calc_label(self):

    """

    调取聚类的结果

    """

    for i, node in enumerate(self.nodes):

    # 将节点的所有叶子节点都分类

    self.leaf_traversal(node, i)

    def leaf_traversal(self, node: ClusterNode, label):

    """

    递归遍历叶子节点

    """

    if node.left == None and node.right == None:

    self.labels[node.id] = label

    if node.left:

    self.leaf_traversal(node.left, label)

    if node.right:

    self.leaf_traversal(node.right, label)

    最后将聚类的列表标记保存于 labels 中。

    测试

    与 sklearn 进行对比:

    iris = datasets.load_iris()

    my = Hierarchical(4)

    my.fit(iris.data)

    print(np.array(my.labels))

    sk = cluster.AgglomerativeClustering(4)

    sk.fit(iris.data)

    print(sk.labels_)

    得到输出:

    [3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3

    3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1

    1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 2 1 2 2 2 2 1 2 2 2 2

    2 2 1 1 2 2 2 2 1 2 1 2 1 2 2 1 1 2 2 2 2 2 1 2 2 2 2 1 2 2 2 1 2 2 2 1 2

    2 1]

    [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

    1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 3 2 3 2 3 2 3 3 2 3 2 3 2 3 3 2 3 2 2 2 2

    2 2 2 0 2 3 3 3 3 2 3 2 2 2 3 3 3 2 3 3 3 3 3 2 3 3 0 2 0 0 0 0 3 0 0 0 0

    0 0 2 2 0 0 0 0 2 0 2 0 2 0 0 2 2 0 0 0 0 0 2 2 0 0 0 2 0 0 0 2 0 0 0 2 0

    0 2]

    结果还算是理想的。

    层次聚类的优缺点

    优点:

    一次性得到聚类树,后期再分类无需重新计算;

    相似度规则容易定义;

    可以发现类别的层次关系。

    缺点:

    计算复杂度高,不适合数据量大的;

    算法很可能形成链状。

    附录

    展开全文
  • 中科大2019春AI 实验二,包括Kmeans算法,PCA算法和层次聚类算法
  • from scipy.cluster import hierarchy0.层次聚类的概念层次聚类和k-means一样都是很常用的聚类方法。...层次聚类又分为自底而上的聚合层次聚类和自顶而下的分裂层次聚类。0.1 聚合层次聚类每一个点初始为1类,得到N(...

    from scipy.cluster import hierarchy

    0.层次聚类的概念

    层次聚类和k-means一样都是很常用的聚类方法。层次聚类是对群体的划分,最终将样本划分为树状的结构。他的基本思路是每个样本先自成一类,然后按照某种规则进行合并,直到只有一类或者某一类的样本只有一个点。层次聚类又分为自底而上的聚合层次聚类和自顶而下的分裂层次聚类。

    0.1 聚合层次聚类

    每一个点初始为1类,得到N(样本点个数)类,计算每一类之间的距离,计算方法有很多,具体可以参考距离的计算方法。聚合层次聚类方法的终止条件是所有样本点都处于同一类了,或者两类之间的距离超过设置的某个阈值。大多数层次聚类都是聚合层次聚类。

    0.2 分裂层次聚类

    和聚合层次聚类是反着的,属于自上而下的一种聚类方法。刚开始的时候所有的样本点都位于同一类,然后一步步划分,终止条件是所有的样本点都位于单独的一类,或者两类之间的距离超过设置的某个阈值。

    下面这个图可以比较好的说明这个过程:

    916aab25cda7

    层次聚类的两种方法

    1.凝聚层次聚类算法步骤

    1.1 算法过程

    1)N个样本单独成类,G1(0)、G2(0)、G3(0)、……、GN(0),0代表初始状态。

    2)更新距离矩阵D(n),找出D(n)中最小值,把对应的两类合并为1类。

    3)更新距离矩阵D(n+1),重复步骤2-3。

    当两类之间的最小距离小于给定的阈值或者所有样本都单独成类的时候,结束算法。

    1.2算法案例

    有个老师带了五个学生,想给学生分组,让他们分组学习,采用层次聚类来对学生进行聚类,基础数据如下图。

    916aab25cda7

    学生基础数据

    先来算距离D(0),就采用欧式距离就好了。

    916aab25cda7

    初始距离矩阵

    找到最小的那两个合并为1类。

    916aab25cda7

    合并后的新数据

    然后计算更新后的距离D(1)

    916aab25cda7

    合并的后新距离

    以后的以此类推:

    916aab25cda7

    聚类的整体过程

    我们看到其实124是一类,35是一类。

    画出图来就是下面这个格式:

    916aab25cda7

    聚类结果

    3.Python处理层次聚类的包

    用的是在scipy.cluster里的hierarchy方法,下面来看代码,支持hierarchical clustering 和 agglomerative clustering。

    首先来看一些基本函数的用法

    linkage

    scipy.cluster.hierarchy.linkage(data,method = 'single')

    method 参数是类距离的计算公式

    singele 两个类之间最短的点的距离

    complete 两个类之间最长距离的点的距离

    centroid 两个类所有点的中点的距离

    pdist计算样本点之间的两两距离

    scipy.cluster.hierarchy.distance.pdist(data, metric='euclidean')

    metric参数是求距离的方法,默认是欧氏距离,可选的还有:

    ‘braycurtis’, ‘canberra’, ‘chebyshev’, ‘cityblock’, ‘correlation’, ‘cosine’, ‘dice’, ‘euclidean’, ‘hamming’, ‘jaccard’, ‘jensenshannon’, ‘kulsinski’, ‘mahalanobis’, ‘matching’, ‘minkowski’, ‘rogerstanimoto’, ‘russellrao’, ‘seuclidean’, ‘sokalmichener’, ‘sokalsneath’, ‘sqeuclidean’, ‘yule’

    关于求距离的函数我可能还会再更一篇文章,感兴趣的朋友可以等一下。笔者之前算字符相似度自己还写了一个杰尔卡德相似度,现在看看真实太费事了。

    dendrogram(linkage)

    scipy.cluster.hierarchy.dendrogram(linkage),这个函数是画图用的。

    import numpy

    import pandas

    from sklearn import datasets

    import scipy.cluster.hierarchy as hcluster

    import scipy

    #iris = datasets.load_iris()

    #data = iris.data

    #target = iris.target

    points=scipy.randn(20,4)

    # Compute and plot first dendrogram.

    linkage = hcluster.linkage(points, method='centroid')

    hcluster.dendrogram(linkage, leaf_font_size=10.)

    p = hcluster.fcluster( linkage, 3, criterion='maxclust')

    聚类结果如下图所示:

    916aab25cda7

    聚类结果

    以上就是层次聚类的简单应用,当然有不同的需求可以继续探索一些函数的参数,这个方法还是很好用的。

    展开全文
  • 层次聚类(AGNES)算法(Python) 是聚类算法的一种,通过计算不同类别数据点间的相似度来创建一棵有层次的嵌套聚类树。...AGNES是常用的一种层次聚类算法 使用场景:用于簇的数量较多,有连接约束等情况
  • 今天说K-means聚类算法,但是必须要先理解聚类和分类的区别,很多业务人员在日常分析时候不是很严谨,混为一谈,其实二者有本质的区别。 分类其实是从特定的数据中挖掘模式,作出判断的过程。比如Gmail邮箱里有垃圾...
  • 一文读懂层次聚类Python代码)

    千次阅读 2021-11-21 21:20:01
    本篇想和大家介绍下层次聚类,先通过一个简单的例子介绍它的基本理论,然后再用一个实战案例Python代码实现聚类效果。 首先要说,聚类属于机器学习的无监督学习,而且也分很多种方法,比如大家熟知的有K-means。层次...

    大家好,我是东哥。

    本篇想和大家介绍下层次聚类,先通过一个简单的例子介绍它的基本理论,然后再用一个实战案例Python代码实现聚类效果。

    首先要说,聚类属于机器学习的无监督学习,而且也分很多种方法,比如大家熟知的有K-means。层次聚类也是聚类中的一种,也很常用。下面我先简单回顾一下K-means的基本原理,然后慢慢引出层次聚类的定义和分层步骤,这样更有助于大家理解。

    层次聚类和K-means有什么不同?

    K-means 工作原理可以简要概述为:

    • 决定簇数(k)
    • 从数据中随机选取 k 个点作为质心
    • 将所有点分配到最近的聚类质心
    • 计算新形成的簇的质心
    • 重复步骤 3 和 4

    这是一个迭代过程,直到新形成的簇的质心不变,或者达到最大迭代次数。

    但是 K-means 是存在一些缺点的,我们必须在算法开始前就决定簇数 K 的数量,但实际我们并不知道应该有多少个簇,所以一般都是根据自己的理解先设定一个值,这就可能导致我们的理解和实际情况存在一些偏差。

    层次聚类完全不同,它不需要我们开始的时候指定簇数,而是先完整的形成整个层次聚类后,通过决定合适的距离,自动就可以找到对应的簇数和聚类。

    什么是层次聚类?

    下面我们由浅及深的介绍什么是层次聚类,先来一个简单的例子。

    假设我们有以下几点,我们想将它们分组:

    我们可以将这些点中的每一个分配给一个单独的簇,就是4个簇(4种颜色):

    然后基于这些簇的相似性(距离),将最相似的(距离最近的)点组合在一起并重复这个过程,直到只剩下一个集群:

    上面本质上就是在构建一个层次结构。先了解到这里,后面我们详细介绍它的分层步骤。

    层次聚类的类型

    主要有两种类型的层次聚类:

    • 凝聚层次聚类
    • 分裂层次聚类

    凝聚层次聚类

    先让所有点分别成为一个单独的簇,然后通过相似性不断组合,直到最后只有一个簇为止,这就是凝聚层次聚类的过程,和我们上面刚刚说的一致。

    分裂层次聚类

    分裂层次聚类正好反过来,它是从单个集群开始逐步分裂,直到无法分裂,即每个点都是一个簇。

    所以无论是 10、100、1000 个数据点都不重要,这些点在开始的时候都属于同一个簇:

    现在,在每次迭代中拆分簇中相隔最远的两点,并重复这个过程,直到每个簇只包含一个点:

    上面的过程就是分裂层次聚类

    执行层次聚类的步骤

    上面已经说了层次聚类的大概过程,那关键的来了,如何确定点和点的相似性呢?

    这是聚类中最重要的问题之一了,一般计算相似度的方法是:计算这些簇的质心之间的距离。距离最小的点称为相似点,我们可以合并它们,也可以将其称为基于距离的算法

    另外在层次聚类中,还有一个称为邻近矩阵的概念,它存储了每个点之间的距离。下面我们通过一个例子来理解如何计算相似度、邻近矩阵、以及层次聚类的具体步骤。

    案例介绍

    假设一位老师想要将学生分成不同的组。现在有每个学生在作业中的分数,想根据这些分数将他们分成几组。关于拥有多少组,这里没有固定的目标。由于老师不知道应该将哪种类型的学生分配到哪个组,因此不能作为监督学习问题来解决。下面,我们将尝试应用层次聚类将学生分成不同的组。

    下面是个5名学生的成绩:

    创建邻近矩阵

    首先,我们要创建一个邻近矩阵,它储存了每个点两两之间的距离,因此可以得到一个形状为 n X n 的方阵。

    这个案例中,可以得到以下 5 x 5 的邻近矩阵:

    矩阵里有两点需要注意下:

    • 矩阵的对角元素始终为 0,因为点与其自身的距离始终为 0
    • 使用欧几里得距离公式来计算非对角元素的距离

    比如,我们要计算点 1 和 2 之间的距离,计算公式为:

    ( 10 − 7 ) 2 = 9 = 3 \sqrt{(10-7)^2}=\sqrt{9}=3 (107)2 =9 =3

    同理,按此计算方法完成后填充邻近矩阵其余元素。

    执行层次聚类

    这里使用凝聚层次聚类来实现。

    步骤 1: 首先,我们将所有点分配成单个簇:

    这里不同的颜色代表不同的簇,我们数据中的 5 个点,即有 5 个不同的簇。

    步骤2: 接下来,我们需要查找邻近矩阵中的最小距离并合并距离最小的点。然后我们更新邻近矩阵:

    最小距离是 3,因此我们将合并点 1 和 2:

    让我们看看更新的集群并相应地更新邻近矩阵:

    更新之后,我们取了1、2 两个点中值 (7, 10) 最大的来替换这个簇的值。当然除了最大值之外,我们还可以取最小值或平均值。然后,我们将再次计算这些簇的邻近矩阵:

    第 3 步: 重复第 2 步,直到只剩下一个簇。

    重复所有的步骤后,我们将得到如下所示的合并的聚类:

    这就是凝聚层次聚类的工作原理。但问题是我们仍然不知道该分几组?是2、3、还是4组呢?

    下面开始介绍如何选择聚类数。

    如何选择聚类数?

    为了获得层次聚类的簇数,我们使用了一个概念,叫作树状图

    通过树状图,我们可以更方便的选出聚类的簇数。

    回到上面的例子。当我们合并两个簇时,树状图会相应地记录这些簇之间的距离并以图形形式表示。下面这个是树状图的原始状态,横坐标记录了每个点的标记,纵轴记录了点和点之间的距离:

    当合并两个簇时,将会在树状图中连接起来,连接的高度就是点之间的距离。下面是我们刚刚层次聚类的过程。

    然后开始对上面的过程进行树状图的绘制。从合并样本 1 和 2 开始,这两个样本之间的距离为 3。

    可以看到已经合并了 1 和 2。垂直线代表 1 和 2 的距离。同理,按照层次聚类过程绘制合并簇类的所有步骤,最后得到了这样的树状图:

    通过树状图,我们可以清楚地形象化层次聚类的步骤。树状图中垂直线的距离越远代表簇之间的距离越大。

    有了这个树状图,我们决定簇类数就方便多了。

    现在我们可以设置一个阈值距离,绘制一条水平线。比如我们将阈值设置为 12,并绘制一条水平线,如下:

    从交点中可以看到,聚类的数量就是与阈值水平线与垂直线相交的数量(红线与 2 条垂直线相交,我们将有 2 个簇)。与横坐标相对应的,一个簇将有一个样本集合为 (1,2,4),另一个集群将有一个样本集合 (3,5)。

    这样,我们就通过树状图解决了分层聚类中要决定聚类的数量。

    Python代码实战案例

    上面是理论基础,有点数学基础都能看懂。下面介绍下在如何用代码Python来实现这一过程。这里拿一个客户细分的数据来展示一下。

    数据集和代码在这里:

    https://github.com/xiaoyusmd/PythonDataScience

    分享不易,还请给个star!

    这个数据来源于UCI 机器学习库。我们的目的是根据批发分销商的客户在不同产品类别(如牛奶、杂货、地区等)上的年度支出,对他们进行细分。

    首先对数据进行一个标准化,为了让所有数据在同一个维度便于计算,然后应用层次聚类来细分客户。

    from sklearn.preprocessing import normalize
    data_scaled = normalize(data)
    data_scaled = pd.DataFrame(data_scaled, columns=data.columns)
    
    import scipy.cluster.hierarchy as shc
    plt.figure(figsize=(10, 7))  
    plt.title("Dendrograms")  
    dend = shc.dendrogram(shc.linkage(data_scaled, method='ward'))
    

    x 轴包含了所有样本,y 轴代表这些样本之间的距离。距离最大的垂直线是蓝线,假如我们决定要以阈值 6 切割树状图:

    plt.figure(figsize=(10, 7))  
    plt.title("Dendrograms")  
    dend = shc.dendrogram(shc.linkage(data_scaled, method='ward'))
    plt.axhline(y=6, color='r', linestyle='--')
    

    现在我们有两个簇了,我们要对这 2 个簇应用层次聚类:

    from sklearn.cluster import AgglomerativeClustering
    cluster = AgglomerativeClustering(n_clusters=2, affinity='euclidean', linkage='ward')  
    cluster.fit_predict(data_scaled)
    

    由于我们定义了 2 个簇,因此我们可以在输出中看到 0 和 1 的值。0 代表属于第一个簇的点,1 代表属于第二个簇的点。

    plt.figure(figsize=(10, 7))  
    plt.scatter(data_scaled['Milk'], data_scaled['Grocery'], c=cluster.labels_) 
    

    到这里我们就成功的完成了聚类。

    参考:https://www.analyticsvidhya.com/blog/2019/05/beginners-guide-hierarchical-clustering/

    数据挖掘、机器学习、深度学习干货等原创文章持续更新,可以微信搜一搜「 Python数据科学」第一时间阅读。

    展开全文
  • 前言聚类分析是研究分类问题的分析方法,是洞察用户偏好和做用户画像的利器之一。...本文将详细介绍如何利用 Python 实现基于层次聚类的客户分群,主要分为两个部分:层次聚类详细原理介绍Python ...

    前言

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

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

    Python 代码实战讲解

    原理部分

    原理介绍

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

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

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

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

    6448c90ea8e0495ebc54010cf8918be6.png

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

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

    基本步骤比较简洁,只要短短的 3 步:计算每两个观测之间的距离

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

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

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

    39e9fc4b0c18793033a2deab38abc5c0.png

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

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

    82aaaf37c6b87ec9a4c5e16527f63eef.png

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

    2be7979522c70fce94544c66d41008fd.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(所有点被聚为一类)

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

    e5531629904efbd55c2947dff981f663.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、怎么从层次树中看出聚类情况?可以通过决定纵轴分界线可决定这些数据到底是分成多少类

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

    6021ffb06fa648ae8af87765bfa9e56b.png

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

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

    95aeb39c04c1d41e3d546e0862c3b2d5.png

    推导与计算

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

    d3cee259b5501fcd94669d20e40696d8.png

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

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

    0260360c50a52b7d872011a27d780dfc.png

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

    86cdbc06f534f4f853487a27f01e98b0.png

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

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

    49abedf2a5b0b213aac300fa43f7217f.png

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

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

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

    892178da13f8daec36b026c258a34f5d.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” 类型的问题通常又会占一大部分,这时候我么可以通过合并多个问题回答的结果来将多个分类变量组合,生成一个连续变量,以电信客户的使用和需求情况为例:

    497e764a2c5bc94a9a53c94c818dea27.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

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

    b57e02ab2e6b37b5e7055da2a320cca1.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')

    04fd30ef59ab940be4b4bc4ac5240d47.png

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

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

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

    展开全文
  • K均值聚类算法python实现,以及聚类算法与EM最大算法的关系 参考引用 先上一张gif的k均值聚类算法动态图片,让大家对算法有个感性认识: 其中:N=200代表有200个样本,不同的颜色代表不同的簇(其中 3种颜色为3...
  • 本文实例讲述了Python实现的KMeans聚类算法。分享给大家供大家参考,具体如下: 菜鸟一枚,编程初学者,最近想使用Python3实现几个简单的机器学习分析方法,记录一下自己的学习过程。 关于KMeans算法本身就不做介绍...
  • 别看层次聚类算法简单,但是实现起来在数据结构方面还需要思考一番,不是那么轻而易举的确定数据结构,实现过的人应该知道的。1.Code# -*- coding: utf-8 -*- """ @author: 蔚蓝的天空Tom Talk is ...
  • 凝聚层次聚类层次聚类方法凝聚层次聚类算法原理簇间距离计算方法单链法single全链法complete组平均法 averageward法python代码实现绘制层次聚类树状图一些参考 相关文章: 数据挖掘 | [关联规则] 利用apyori库的关联...
  • 层次聚类python实现

    2021-10-31 15:30:54
    层次聚类算法 顾名思义,层次聚类就是一层一层的进行聚类,可以由上向下把大的类别(cluster)分割,叫作分裂法;也可以由下向上对小的类别进行聚合,叫作凝聚法;但是一般用的比较多的是由下向上的凝聚方法。 分裂...
  • 基本的算法思路就是:把当前组间距离最小的两组合并成一组。 算法的差异在算法如何确定组件的距离,一般有最大距离,最小距离,平均距离,马氏距离等等。 代码如下: import numpy as np import data_helper np....
  • 这篇文章主要介绍了Python聚类算法之凝聚层次聚类的原理与具体使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了Python聚类算法之凝聚层次聚类。分享给大家供大家参考,具体如下: 凝聚层次聚类:...
  • 层次聚类算法的原理及python实现

    万次阅读 多人点赞 2018-01-05 11:27:52
    层次聚类(Hierarchical Clustering)是一种聚类算法,通过计算不同类别数据点间的相似度来创建一棵有层次的嵌套聚类树。在聚类树中,不同类别的原始数据点是树的最低层,树的顶层是一个聚类的根节点。
  • 二、层次聚类层次聚类算法实际上分为两类:自上而下或自下而上。自下而上的算法在一开始就将每个数据点视为一个单一的聚类,然后依次合并(或聚集)类,直到所有类合并成一个包含所有数据点的单一聚类。因此,自下而上...
  • 层次聚类算法python实现

    千次阅读 2015-07-10 10:35:26
    文章给出层次聚类算法python实现方法,并用《数据挖掘导论》里面的具体数据进行运行,代码如下: from numpy import * from math import * from operator import * def dist(a,b):#a,b is mat c=(a-b)*(a-b).T ...
  • 聚类算法——python实现层次聚类(AGNES)

    万次阅读 多人点赞 2017-05-15 20:39:35
    AGNES算法是自底向上的层次聚类算法。开始时将数据集中的每个样本初始化为一个簇,然后找到距离最近的两个簇,将他们合并,不断重复这个过程,直达到到预设的聚类数目为止。 计算距离的三个公式: AGNES算法...
  • 主要介绍了python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 一、前言二、DBSCAN聚类算法三、参数选择四、DBSCAN算法迭代可视化展示五、常用的评估方法:轮廓系数六、用Python实现DBSCAN聚类算法一、前言去年学聚类算法的R语言的时候,有层次聚类、系统聚类、K-means聚类、K...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,388
精华内容 2,955
关键字:

层次聚类算法python

python 订阅
友情链接: 12864-Menu.zip