第1关:距离的计算
相关知识
为了完成本关任务,你需要掌握:
- 为什么需要距离
- 距离的计算
为什么需要距离
AGNES
算法是一种自底向上聚合的层次聚类算法,它先会将数据集中的每个样本看作一个初始簇,然后在算法运行的每一步中找出距离最近的两个簇进行合并,直至达到预设的簇的数量。所以AGNES
算法需要不断的计算簇之间的距离,这也符合聚类的核心思想(物以类聚,人以群分),因此怎样度量两个簇之间的距离成为了关键。
距离的计算
衡量两个簇之间的距离通常分为最小距离、最大距离和平均距离。在AGNES
算法中可根据具体业务选择其中一种距离作为度量标准。
最小距离
最小距离描述的是两个簇之间距离最近的两个样本所对应的距离。例如下图中圆圈和菱形分别代表两个簇,两个簇之间离得最近的样本的欧式距离为3.3
,则最小距离为3.3
。
假设给定簇Ci与Cj,则最小距离为:
dmin=minxini,zinjdist(x,z)
最大距离
最大距离描述的是两个簇之间距离最远的两个样本所对应的距离。例如下图中圆圈和菱形分别代表两个簇,两个簇之间离得最远的样本的欧式距离为23.3
,则最大距离为23.3
。
假设给定簇Ci与Cj,则最大距离为:
dmin=maxxini,zinjdist(x,z)
平均距离
平均距离描述的是两个簇之间样本的平均距离。例如下图中圆圈和菱形分别代表两个簇,计算两个簇之间的所有样本之间的欧式距离并求其平均值。
假设给定簇Ci与Cj,∣Ci∣,∣Cj∣分别表示簇i
与簇j
中样本的数量,则平均距离为:
dmin=∣Ci∣∣Cj∣1sumxinisumzinjdist(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
import numpy as np
def calc_min_dist(cluster1, cluster2):
'''
计算簇间最小距离
:param cluster1:簇1中的样本数据,类型为ndarray
:param cluster2:簇2中的样本数据,类型为ndarray
:return:簇1与簇2之间的最小距离
'''
#********* Begin *********#
min_dist = np.inf
for i in range(len(cluster1)):
for j in range(len(cluster2)):
dist = np.sqrt(np.sum(np.square(cluster1[i] - cluster2[j])))
if dist < min_dist:
min_dist = dist
return min_dist
#********* End *********#
def calc_max_dist(cluster1, cluster2):
'''
计算簇间最大距离
:param cluster1:簇1中的样本数据,类型为ndarray
:param cluster2:簇2中的样本数据,类型为ndarray
:return:簇1与簇2之间的最大距离
'''
#********* Begin *********#
max_dist = 0
for i in range(len(cluster1)):
for j in range(len(cluster2)):
dist = np.sqrt(np.sum(np.square(cluster1[i] - cluster2[j])))
if dist > max_dist:
max_dist = dist
return max_dist
def calc_avg_dist(cluster1, cluster2):
'''
计算簇间平均距离
:param cluster1:簇1中的样本数据,类型为ndarray
:param cluster2:簇2中的样本数据,类型为ndarray
:return:簇1与簇2之间的平均距离
'''
#********* Begin *********#
num = len(cluster1) * len(cluster2)
avg_dist = 0
for i in range(len(cluster1)):
for j in range(len(cluster2)):
dist = np.sqrt(np.sum(np.square(cluster1[i] - cluster2[j])))
avg_dist += dist
avg_dist = avg_dist / num
return avg_dist
#********* End *********#