[译] 层次聚类的初学者指南(用 Python 实现)

栏目: 编程工具 · 发布时间: 4年前

内容简介:原文选自 | analyticsvidhya作者 | Pulkit Sharma全文约4700字,推荐阅读时间7分钟

原文选自 | analyticsvidhya

作者 | Pulkit Sharma

全文约4700字,推荐阅读时间7分钟

点击【阅读原文】可查看英文原文

介绍

任何行业中,了解客户行为都是至关重要的。去年,我的首席营销官问 “现有客户中哪些客户应作为新产品的目标用户?”时,我就意识到了这一点。

对我来说,这是一个很好的学习曲线。我意识到了细分客户是多么重要,这样企业就可以制定和构建针对性策略。聚类的概念在这里变得非常方便!

像细分客户这样的问题通常很棘手,因为我们没有任何目标变量供考虑。我们处在一个无监督学习的状态,需要从中找出模式和结构,而不用考虑一个既定的结果。作为一名数据科学家,这既具有挑战又令人兴奋。

[译] 层次聚类的初学者指南(用  <a href='https://www.codercto.com/topics/20097.html'>Python</a>  实现)

有几种不同的方法可以执行聚类(如下所示)。我将在本文中向您介绍其中一种--层次聚类。

我们将了解层次聚类是什么,它优于其他聚类算法的优势,不同类型的层次聚类以及执行它的步骤。我们最终使用客户细分数据集在Python中实现层次聚类。我很喜欢这种技术,我相信你也会在看完这篇文章之后做到这一点!

注意:如上所述,有多种方法可以执行群集。我鼓励您在文末链接查看介绍不同类型群集的精彩指南。

目录

  1. 监督学习与无监督学习

  2. 为什么采用层次聚类

  3. 什么是层次聚类

  4. 层次聚类的类型

    1. 聚合层次聚类

    2. 分裂层次聚类

  5. 执行层次聚类的步骤

  6. 如何选择层次聚类中的聚类数

  7. 使用层次聚类解决客户细分问题

监督学习与非监督学习

在深入层次聚类之前,理解有监督和无监督学习之间的区别非常重要。让我用一个简单的例子解释这个差异。

假设我们想要估算每天在城市租用的自行车数量:

[译] 层次聚类的初学者指南(用 Python 实现)

或者假设我们想要预测泰坦尼克号上的人是否幸存:

[译] 层次聚类的初学者指南(用 Python 实现)

我们在这两个示例中都有一个固定的目标:

  • 在第一个例子中,我们必须根据季节,假日,工作日,天气,气温等特征预测自行车的数量。

  • 我们在第二个例子中预测乘客是否幸存。在'Survived'变量中,0代表该人丧生,1代表该人幸存。这里的自变量包括船票等级,性别,年龄等。

因此,当我们给出一个目标变量(上述两种情况下的数量和生存情况)时,我们必须根据给定的一组预测变量或自变量(季节,假日,性别,年龄等)进行预测,这些问题称为监督学习问题。

让我们从下图直观地理解这一点:

[译] 层次聚类的初学者指南(用 Python 实现)

这里y是我们的依赖变量,或叫做目标变量,X代表自变量。目标变量依赖于X,因此它也被称为因变量。我们使用自变量在目标变量的监督下训练我们的模型,因此命名为监督学习。

在训练模型时,我们的目标是生成将自变量映射到所需目标的函数。一旦模型被训练,模型就可以通过新的观测值预测它们的目标。简而言之,这是有监督的学习。

但是可能存在我们没有任何目标变量来预测的情况。没有任何明确的目标变量的这些问题被称为无监督学习问题。我们在这些问题中只有自变量而没有目标/因变量。

[译] 层次聚类的初学者指南(用 Python 实现)

在这些情况下,我们尝试将整个数据划分为一些组。这些组称为集群,制作这些集群的过程称为聚类。

[译] 层次聚类的初学者指南(用 Python 实现)

该技术通常用于将群体聚类到不同的群组中。一些常见示例包括细分客户,将文档归类在一起,推荐相似的歌曲或电影等。

有许多无监督学习的应用。如果您遇到任何有趣的应用程序,请随时在下面的评论部分分享!

现在,有各种算法可以帮助我们划分这些集群。最常用的聚类算法是K-means和Hierarchical clustering(层次聚类)。

为什么使用层次聚类

在我们深入层次聚类之前,我们应该先了解K-means的工作原理。相信我,它将使层次聚类的概念变得更加容易。

以下是K-means工作原理的概述:

  1. 确定簇数(k)

  2. 从数据中选择k个随机点作为质心

  3. 将所有点分配到最近的簇的质心

  4. 计算新形成的簇的质心

  5. 重复步骤3和4

这是一个迭代过程。它将继续运行,直到新形成的簇的质心不再变化或达到最大迭代次数。

但K-means存在一定的挑战。因为它总是试图将集群划分为相同大小。此外,我们必须在算法开始时确定簇的数量。理想情况下,我们不知道算法的一开始应该有多少个簇,因此它是K-means的挑战。

这就平稳的过渡到了层次聚类。它消除了必须预先定义集群数量的问题。听起来像在做梦!那么,让我们看看什么是层次聚类,以及它如何改进k-means。

什么是层次聚类

假设我们有以下几个点,我们希望将它们分组:

[译] 层次聚类的初学者指南(用 Python 实现)

我们可以将每个点分配给一个单独的集群:

[译] 层次聚类的初学者指南(用 Python 实现)

现在,基于这些集群的相似性,我们可以将最相似的集群组合在一起并重复此过程,直到只留下一个集群:

[译] 层次聚类的初学者指南(用 Python 实现)

我们这是在构建集群层次结构。这就是为什么这个算法被称为层次聚类。我将在后面的部分讨论如何确定集群的数量。现在,让我们看看不同类型的层次聚类。

层次聚类的类型

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

  1. 聚合层次聚类

  2. 分裂层次聚类

让我们来详细了解一下每种类型。

聚合层次聚类

我们在这种技术中,将每个点分配给一个单独的集群。假设有4个数据点。我们将每个点分配给一个集群,因此在开始时将有4个集群:

[译] 层次聚类的初学者指南(用 Python 实现)

然后,在每次迭代时,我们合并最近的一对集群并重复此步骤,直到只留下一个簇:

[译] 层次聚类的初学者指南(用 Python 实现)

我们在每一步合并(或添加)集群,对吧?因此,这种类型的聚类也称为加和层次聚类。

分裂层次聚类

分裂层次聚类以相反的方式工作。我们不是从n个集群开始(在n个观察的情况下),而是从单个集群开始,并将所有点分配给该集群。

因此,如果我们有10或1000个数据点,都无关紧要。所有这些点在开始时都属于同一个集群:

[译] 层次聚类的初学者指南(用 Python 实现)

现在,在每次迭代中,我们分离集群中的最远点并重复此过程,直到每个集群仅包含一个点:

[译] 层次聚类的初学者指南(用 Python 实现)

我们在每一步进行分裂(或划分)集群,因此称为分裂层次聚类。

聚合聚类在业界广泛使用,这将成为本文的重点。一旦我们处理了聚合型,分裂的层次聚类就像一块蛋糕一样。

执行层次聚类的步骤

我们在层次聚类中合并最相似的点或集群--这是我们已知的。现在的问题是 - 我们如何确定哪些点相似,哪些不相似?这是聚类中最重要的问题之一!

计算相似度的方法之一是获取这些集群质心之间的距离。具有最小距离的点被称为相似点,我们可以合并它们。这被称为基于距离的算法(因为我们正在计算集群之间的距离)。

在层次聚类中,有一个被称为邻近矩阵的概念。它存储了每个点之间的距离。让我们举一个例子来理解这个矩阵以及执行层次聚类的步骤。

示例

[译] 层次聚类的初学者指南(用 Python 实现)

假设一位老师想把她的学生分成不同的小组。她有每个学生的作业得分,她希望根据这些分数给学生分组(这里没有固定要多少组的目标)。由于教师不知道应该将哪种类型的学生分配到哪个小组,所以不能将其作为监督学习问题解决。我们将尝试在此处应用层次聚类,并将学生划分为不同的组。

我们来看看5名学生的样本:

[译] 层次聚类的初学者指南(用 Python 实现)

创建邻近矩阵

首先,我们将创建一个邻近矩阵,它将告诉我们每个点之间的距离。我们计算了每个点与每个其他点的距离,得到一个形状为n X n的方形矩阵(其中n是观测数)。

制作5 x 5邻近矩阵:

[译] 层次聚类的初学者指南(用 Python 实现)

此矩阵的对角线元素将始终为0,因为点与其自身的距离始终为0。使用欧几里德距离公式计算其余距离。假设我们想要计算第1点和第2点之间的距离:

√(10-7)^ 2 =√9= 3

同样,我们可以计算所有距离并填充邻近矩阵。

执行层次聚类的步骤

第1步: 首先,将所有点分配给单个集群:

[译] 层次聚类的初学者指南(用 Python 实现)

这里不同的颜色代表不同的聚类。您可以看到有5个点,对应5个不同的聚类。

第2步:   接下来,我们将查看邻近矩阵中的最小距离,合并具有最小距离的点。然后更新邻近矩阵:

[译] 层次聚类的初学者指南(用 Python 实现)

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

[译] 层次聚类的初学者指南(用 Python 实现)

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

[译] 层次聚类的初学者指南(用 Python 实现)

这里取了两个标记(7,10)的最大值来替换该集群的标记。也可以取最小值或平均值,而不是最大值。现在,我们将再次计算这些集群的邻近矩阵:

[译] 层次聚类的初学者指南(用 Python 实现)

第3步: 我们将重复步骤2,直到只剩下一个集群。

首先查看邻近矩阵中的最小距离,然后合并最近的一对集群。重复这些步骤后,我们将获得如下所示的合并集群:

[译] 层次聚类的初学者指南(用 Python 实现)

我们从5个集群开始,最后只有一个集群。这就是聚合层次聚类的工作原理。但问题仍然存在---我们如何决定集群的数量?让我们在下一节中介绍。

如何选择层次聚类中的聚类数

准备好回答这个自从开始学习以来就一直存在的问题了吗?为了获得用于层次聚类的聚类数量,我们使用了一种叫做树图的令人敬畏的概念。

树图是一种树状图,记录合并或分裂的序列。

让我们回到师生示例。每当合并两个聚类时,树图将记录这些聚类之间的距离并以图形表示。我们来看看树状图是怎样的:

[译] 层次聚类的初学者指南(用 Python 实现)

我们在x轴上有数据集的样本,在y轴上有距离。每当合并两个集群时,我们将在这个树图中加入它们,并且连接的高度将是这些点之间的距离。接下来我们来构建树图:

[译] 层次聚类的初学者指南(用 Python 实现)

下面花点时间处理上面的图像。我们首先合并样本1和2,这两个样本之间的距离为3(参考上一节中的第一个邻近矩阵)。让我们在树图中绘制这个:

[译] 层次聚类的初学者指南(用 Python 实现)

合并了样本1和2。垂直线表示这些样本之间的距离。同样,我们绘制了合并聚类的所有步骤,最后,我们得到了这样的树图:

[译] 层次聚类的初学者指南(用 Python 实现)

我们可以清楚地看到层次聚类的步骤。树形图中垂直线的距离越大,这些集群之间的距离就越大。

现在,我们可以设置一个阈值距离并绘制一条水平线(通常,设置阈值使其截断最高的垂直线)。我们将此阈值设置为12并绘制一条水平线:

[译] 层次聚类的初学者指南(用 Python 实现)

集群的数量将是与使用阈值绘制的线相交的垂直线的数量。在上面的例子中,由于红线与2条垂直线相交,我们将有2个簇。一个集群将有一个样本(1,2,4),另一个集群将有一个样本(3,5)。很简单,对吧?

这就是我们如何在层次聚类中使用树形图来确定聚类的数量。在下一节中,我们将实现层次聚类,这将帮助您理解我们在本文中学到的所有概念。

使用层次聚类解决批发商客户细分问题

是时候用Python弄脏我们的手了!

我们将解决批发商客户细分问题。数据托管在UCI机器学习存储库中。这个问题的目的是根据各种产品类别(如牛奶,杂货店,地区等)的年度支出来细分批发商的客户。

让我们先探索数据然后应用层次聚类来划分客户群。

首先导入所需的库:


 

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

%matplotlib inline

加载数据并查看前几行:


 

data = pd.read_csv('Wholesale customers data.csv')

data.head()

[译] 层次聚类的初学者指南(用 Python 实现)

有多种产品类别 - 生鲜,牛奶,杂货等。这些值代表每个客户购买每种产品的单位数量。我们的目标是从这些数据中创建可以将相似客户分组在一起的集群。当然,我们将使用层次聚类来解决这个问题。

但在应用层次聚类之前,我们必须对数据进行标准化,以使每个变量的衡量标准相同。为什么这很重要?因为如果标准不同,模型可能会变得偏向具有更高等级的变量,如生鲜或牛奶(参见上表)。

那么,让我们首先规范化数据并将所有变量带到相同的比例:


 

from sklearn.preprocessing import normalize

data_scaled = normalize(data)

data_scaled = pd.DataFrame(data_scaled, columns=data.columns)

data_scaled.head()

[译] 层次聚类的初学者指南(用 Python 实现)

我们可以看到所有变量的规模几乎都相似。首先绘制树图来帮助我们确定这个特定问题的聚类数量:


 

import scipy.cluster.hierarchy as shc

plt.figure(figsize=(10, 7))

plt.title("Dendrograms")

dend = shc.dendrogram(shc.linkage(data_scaled, method='ward'))

[译] 层次聚类的初学者指南(用 Python 实现)

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='--')

[译] 层次聚类的初学者指南(用 Python 实现)

我们有两个簇,因为这条线在两点切割树状图。现在让我们为2个集群应用层次聚类:


 

from sklearn.cluster import AgglomerativeClustering

cluster = AgglomerativeClustering(n_clusters=2, affinity='euclidean', linkage='ward')

cluster.fit_predict(data_scaled)

[译] 层次聚类的初学者指南(用 Python 实现)

我们可以在输出中看到0和1的值,因为我们定义了2个簇。0表示属于第一个簇的点,1表示第二个簇中的点。现在让我们想象两个集群:


 

plt.figure(figsize=(10, 7))

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

[译] 层次聚类的初学者指南(用 Python 实现)

真棒!我们可以清楚地看到这两个集群。这就是我们如何在Python中实现层次聚类。

结语

层次聚类是一种非常有用的观测分段方法。不必预先定义集群数量的优点使其比k-Means更具优势。

您对层次聚类有何看法?您是否觉得使用较少的计算资源创建集群有更好的方法?欢迎留言讨论!

原文链接 

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

原文项目Github

聚类简介和不同的聚类方法

https://www.analyticsvidhya.com/blog/2016/11/an-introduction-to-clustering-and-different-methods-of-clustering/?utm_source=blog&utm_medium=beginners-guide-hierarchical-clustering

封面图来源:pexels by Pok Rie

[译] 层次聚类的初学者指南(用 Python 实现)


以上所述就是小编给大家介绍的《[译] 层次聚类的初学者指南(用 Python 实现)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

捉虫记

捉虫记

施迎 / 清华大学出版社 / 2010-6 / 56.00元

《捉虫记:大容量Web应用性能测试与LoadRunner实战》主要讲解大容量Web性能测试的特点和方法,以及使用业内应用非常广泛的工具——Load Runner 9进行性能测试的具体技术与技巧。《捉虫记:大容量Web应用性能测试与LoadRunner实战》共17章,分为5篇。第1篇介绍软件测试的定义、方法和过程等内容:第2篇介绍Web应用、Web性能测试的分类、基本硬件知识、Web应用服务器选型、......一起来看看 《捉虫记》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具