当前位置:   article > 正文

头歌-机器学习 第4次实验 AGNES层次聚类方法

头歌-机器学习 第4次实验 AGNES层次聚类方法

第1关:距离的计算

任务描述

本关任务:根据本关所学知识,完成calc_min_dist函数,calc_max_dist函数以及calc_avg_dist函数分别实现计算两个簇之间的最短距离、最远距离和平均距离。

相关知识

为了完成本关任务,你需要掌握:

  • 为什么需要距离
  • 距离的计算
为什么需要距离

AGNES算法是一种自底向上聚合的层次聚类算法,它先会将数据集中的每个样本看作一个初始簇,然后在算法运行的每一步中找出距离最近的两个簇进行合并,直至达到预设的簇的数量。所以AGNES算法需要不断的计算簇之间的距离,这也符合聚类的核心思想(物以类聚,人以群分),因此怎样度量两个簇之间的距离成为了关键。

距离的计算

衡量两个簇之间的距离通常分为最小距离、最大距离和平均距离。在AGNES算法中可根据具体业务选择其中一种距离作为度量标准。

最小距离

最小距离描述的是两个簇之间距离最近的两个样本所对应的距离。例如下图中圆圈和菱形分别代表两个簇,两个簇之间离得最近的样本的欧式距离3.3,则最小距离为3.3

假设给定簇Ci​与Cj​,则最小距离为:

dmin​=minxini,zinj​dist(x,z)

最大距离

最大距离描述的是两个簇之间距离最远的两个样本所对应的距离。例如下图中圆圈和菱形分别代表两个簇,两个簇之间离得最远的样本的欧式距离23.3,则最大距离为23.3

假设给定簇Ci​与Cj​,则最大距离为:

dmin​=maxxini,zinj​dist(x,z)

平均距离

平均距离描述的是两个簇之间样本的平均距离。例如下图中圆圈和菱形分别代表两个簇,计算两个簇之间的所有样本之间的欧式距离并求其平均值。

假设给定簇Ci​与Cj​,∣Ci​∣,∣Cj​∣分别表示簇i与簇j中样本的数量,则平均距离为:

dmin​=∣Ci​∣∣Cj​∣1​sumxini​sumzinj​dist(x,z)

编程要求

根据提示,在右侧Begin-End区域补充代码,完成clac_min_dist函数,calc_max_dist函数以及calc_avg_dist函数分别实现计算两个簇之间的最短距离、最远距离和平均距离。注意:距离请使用欧氏距离。

calc_min_dist函数中的参数:

  • cluster1:簇1中的样本数据,类型为ndarray
  • cluster2:簇2中的样本数据,类型为ndarray

calc_max_dist函数中的参数:

  • cluster1:簇1中的样本数据,类型为ndarray
  • cluster2:簇2中的样本数据,类型为ndarray

calc_avg_dist函数中的参数:

  • cluster1:簇1中的样本数据,类型为ndarray
  • cluster2:簇2中的样本数据,类型为ndarray
测试说明

只需完成clac_min_dist函数,calc_max_dist函数以及calc_avg_dist函数即可,平台会对你编写的代码进行测试,并会按顺序打印最小距离、最大距离与平均距离。以下为其中一个测试用例,其中cluster1部分表示属于簇1的样本数据,cluster2部分表示属于簇2的样本数据:

测试输入: {'cluster1':[[0, 1, 0], [1, 0, 1], [1, 2, 3.2], [0, 0, 1.2], [1, 1, 0.1]], 'cluster2':[[10.1, 20.3, 9], [8.2, 15.3, 11]]}

预期输出: 17.016756, 23.977906, 21.133420

  1. import numpy as np
  2. def calc_min_dist(cluster1, cluster2):
  3. '''
  4. 计算簇间最小距离
  5. :param cluster1:簇1中的样本数据,类型为ndarray
  6. :param cluster2:簇2中的样本数据,类型为ndarray
  7. :return:簇1与簇2之间的最小距离
  8. '''
  9. #********* Begin *********#
  10. min_dist = float('inf')
  11. for i in range(len(cluster1)):
  12. for j in range(len(cluster2)):
  13. dist = np.sqrt(np.sum((cluster1[i]-cluster2[j])**2))
  14. if dist < min_dist:
  15. min_dist = dist
  16. return min_dist
  17. #********* End *********#
  18. def calc_max_dist(cluster1, cluster2):
  19. '''
  20. 计算簇间最大距离
  21. :param cluster1:簇1中的样本数据,类型为ndarray
  22. :param cluster2:簇2中的样本数据,类型为ndarray
  23. :return:簇1与簇2之间的最大距离
  24. '''
  25. #********* Begin *********#
  26. max_dist = 0
  27. for i in range(len(cluster1)):
  28. for j in range(len(cluster2)):
  29. dist = np.sqrt(np.sum((cluster1[i]-cluster2[j])**2))
  30. if dist > max_dist:
  31. max_dist = dist
  32. return max_dist
  33. #********* End *********#
  34. def calc_avg_dist(cluster1, cluster2):
  35. '''
  36. 计算簇间平均距离
  37. :param cluster1:簇1中的样本数据,类型为ndarray
  38. :param cluster2:簇2中的样本数据,类型为ndarray
  39. :return:簇1与簇2之间的平均距离
  40. '''
  41. #********* Begin *********#
  42. avg_dist = 0
  43. count = 0
  44. for i in range(len(cluster1)):
  45. for j in range(len(cluster2)):
  46. dist = np.sqrt(np.sum((cluster1[i]-cluster2[j])**2))
  47. avg_dist += dist
  48. count += 1
  49. avg_dist /= count
  50. return avg_dist
  51. #********* End *********#

 第2关:AGNES算法流程

任务描述

本关任务:补充python代码,完成AGNES函数完成聚类功能。

相关知识

为了完成本关任务,你需要掌握AGNES算法流程

AGNES算法流程

AGNES算法是一种自底向上聚合的层次聚类算法,它先会将数据集中的每个样本看作一个初始簇,然后在算法运行的每一步中找出距离最近的两个簇进行合并,直至达到预设的簇的数量。

举个例子,现在先要将西瓜数据聚成两类,数据如下表所示:

编号体积重量
11.22.3
23.67.1
31.12.2
43.56.9
51.52.5

一开始,每个样本都看成是一个簇(1号样本看成是1号簇,2号样本看成是2号簇,...,5号样本看成是5号簇),假设簇的集合为C=[[1], [2], [3], [4], [5]]

假设使用簇间最小距离来度量两个簇之间的远近,从表中可以看出1号簇与3号簇的簇间最小距离最小。因此需要将1号簇和3号簇合并,那么此时簇的集合C=[[1, 3], [2], [4], [5]]

然后继续看这4个簇中哪两个簇之间的最小距离最小,我们发现2号簇与4号簇的最小距离最小,因此我们要进行合并,合并之后C=[[1, 3], [2, 4], [5]]

然后继续看这3个簇中哪两个簇之间的最小距离最小,我们发现5号簇与[1, 3]簇的最小距离最小,因此我们要进行合并,合并之后C=[[1, 3, 5], [2, 4]]

这个时候C中只有两个簇了,达到了我们的预期目标(想要聚成两类),所以算法停止。算法停止后会发现,我们已经将5个西瓜,聚成了两类,一类是小西瓜,另一类是大西瓜。

如果将整个聚类过程中的合并,与合并的次序可视化出来,就能看出为什么说AGNES是自底向上的层次聚类算法了。

AGNES伪代码如下:

 
  1. #假设数据集为D,想要聚成的簇的数量为k
  2. def AGNES(D, k):
  3. #C为聚类结果
  4. C = []
  5. #将每个样本看成一个簇
  6. for d in D:
  7. C.append(d)
  8. #C中簇的数量
  9. q=len(C)
  10. while q > k:
  11. 寻找距离最小的两个簇a和b
  12. 将a和b合并,并修改C
  13. q = len(C)
  14. return C
编程要求

Begin-End区域完成AGNES函数实现聚类功能,并将聚类结果返回(量化距离时请使用簇间最大欧氏距离)。PS:假设数据集为[[1, 2], [10, 11], [1, 3]],那么聚类结果可能为[[[1, 2], [1, 3]], [[10, 11]]]

其中:

  • feature:数据集,类型为ndarray
  • k:表示想要将数据聚成k类,类型为int
测试说明

只需完成AGNES函数即可,程序内部会调用您所完成的AGNES函数对数据进行聚类,若聚类后的簇与真实结果相似度高于0.8视为过关。

  1. import numpy as np
  2. def AGNES(feature, k):
  3. '''
  4. AGNES聚类并返回聚类结果
  5. 假设数据集为`[1, 2], [10, 11], [1, 3]],那么聚类结果可能为`[[1, 2], [1, 3]], [[10, 11]]]
  6. :param feature:训练数据集所有特征组成的ndarray
  7. :param k:表示想要将数据聚成`k`类,类型为`int`
  8. :return:聚类结果
  9. '''
  10. #********* Begin *********#
  11. # 找到距离最小的下标
  12. def find_Min(M):
  13. min = np.inf
  14. x = 0;
  15. y = 0
  16. for i in range(len(M)):
  17. for j in range(len(M[i])):
  18. if i != j and M[i][j] < min:
  19. min = M[i][j];
  20. x = i;
  21. y = j
  22. return (x, y, min)
  23. #计算簇间最大距离
  24. def calc_max_dist(cluster1, cluster2):
  25. max_dist = 0
  26. for i in range(len(cluster1)):
  27. for j in range(len(cluster2)):
  28. dist = np.sqrt(np.sum(np.square(cluster1[i] - cluster2[j])))
  29. if dist > max_dist:
  30. max_dist = dist
  31. return max_dist
  32. #初始化C和M
  33. C = []
  34. M = []
  35. for i in feature:
  36. Ci = []
  37. Ci.append(i)
  38. C.append(Ci)
  39. for i in C:
  40. Mi = []
  41. for j in C:
  42. Mi.append(calc_max_dist(i, j))
  43. M.append(Mi)
  44. q = len(feature)
  45. #合并更新
  46. while q > k:
  47. x, y, min = find_Min(M)
  48. C[x].extend(C[y])
  49. C.pop(y)
  50. M = []
  51. for i in C:
  52. Mi = []
  53. for j in C:
  54. Mi.append(calc_max_dist(i, j))
  55. M.append(Mi)
  56. q -= 1
  57. return C
  58. #********* End *********#

 第3关:红酒聚类

任务描述

本关任务:sklearn中的AgglomerativeClustering类实现了AGNES算法,本关你需要使用 sklearnAgglomerativeClustering来对红酒数据进行聚类。

相关知识

为了完成本关任务,你需要掌握:AgglomerativeClustering

数据集介绍

数据集为一份红酒数据,一共有178个样本,每个样本有13个特征,这里不会提供你红酒的标签,你需要自己根据这13个特征对红酒进行聚类,部分数据如下图:

数据获取代码:

 
  1. import pandas as pd
  2. data_frame = pd.read_csv('./step3/dataset.csv', header=0)
AgglomerativeClustering

AgglomerativeClustering的构造函数中有两个常用的参数可以设置:

  • n_clusters:将数据聚成n_clusters个类
  • linkage:设置AGNES聚类时使用最小簇间距离、最大簇间距离还是平均距离。传入ward表示最小簇间距离,传入complete表示最大簇间距离,传入average表示平均距离

AgglomerativeClustering类中的fit_predict函数用于训练模型并获取聚类结果,fit_predict函数有一个向量输入:

  • X:数据集,形状为**[样本数量,特征数量]**的ndarray

AgglomerativeClustering的使用代码如下:

 
  1. from sklearn.cluster import AgglomerativeClustering
  2. agnes = AgglomerativeClustering(k=5)
  3. # 注意:x为ndarray
  4. result = agnes.fit_predict(x)
编程要求

Begin-End区域填写Agglomerative_cluster(data)函数完成红酒数据聚类任务,簇的数量为3。其中:

  • data:数据样本,类型为ndarrayshape=[样本数量, 特征数量]

  • return: 聚类结果,类型为ndarray

注意:直接使用原始数据进行聚类的效果可能不太理想,你可能需要对数据进行预处理。

提示:AGNES算法需要计算距离,想想什么样的预处理方式对依赖距离的算法有好的效果。

测试说明

只需返回聚类结果即可,程序内部会检测您的代码,吻合度高于0.9视为过关。

  1. #encoding=utf8
  2. from sklearn.cluster import AgglomerativeClustering
  3. def Agglomerative_cluster(data):
  4. '''
  5. 对红酒数据进行聚类
  6. :param data: 数据集,类型为ndarray
  7. :return: 聚类结果,类型为ndarray
  8. '''
  9. #********* Begin *********#
  10. from sklearn.preprocessing import StandardScaler
  11. scaler = StandardScaler()
  12. data = scaler.fit_transform(data)
  13. agnes = AgglomerativeClustering(n_clusters=3)
  14. result = agnes.fit_predict(data)
  15. return result
  16. #********* End *********#

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/424959?site
推荐阅读
相关标签
  

闽ICP备14008679号