赞
踩
本关任务:根据本关所学知识,完成calc_min_dist
函数,calc_max_dist
函数以及calc_avg_dist
函数分别实现计算两个簇之间的最短距离、最远距离和平均距离。
为了完成本关任务,你需要掌握:
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 = float('inf')
- for i in range(len(cluster1)):
- for j in range(len(cluster2)):
- dist = np.sqrt(np.sum((cluster1[i]-cluster2[j])**2))
- 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((cluster1[i]-cluster2[j])**2))
- if dist > max_dist:
- max_dist = dist
- return max_dist
- #********* End *********#
-
-
- def calc_avg_dist(cluster1, cluster2):
- '''
- 计算簇间平均距离
- :param cluster1:簇1中的样本数据,类型为ndarray
- :param cluster2:簇2中的样本数据,类型为ndarray
- :return:簇1与簇2之间的平均距离
- '''
-
- #********* Begin *********#
- avg_dist = 0
- count = 0
- for i in range(len(cluster1)):
- for j in range(len(cluster2)):
- dist = np.sqrt(np.sum((cluster1[i]-cluster2[j])**2))
- avg_dist += dist
- count += 1
- avg_dist /= count
- return avg_dist
- #********* End *********#
本关任务:补充python
代码,完成AGNES
函数完成聚类功能。
为了完成本关任务,你需要掌握AGNES
算法流程
AGNES
算法是一种自底向上聚合的层次聚类算法,它先会将数据集中的每个样本看作一个初始簇,然后在算法运行的每一步中找出距离最近的两个簇进行合并,直至达到预设的簇的数量。
举个例子,现在先要将西瓜数据聚成两类,数据如下表所示:
编号 | 体积 | 重量 |
---|---|---|
1 | 1.2 | 2.3 |
2 | 3.6 | 7.1 |
3 | 1.1 | 2.2 |
4 | 3.5 | 6.9 |
5 | 1.5 | 2.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
伪代码如下:
#假设数据集为D,想要聚成的簇的数量为k
def AGNES(D, k):
#C为聚类结果
C = []
#将每个样本看成一个簇
for d in D:
C.append(d)
#C中簇的数量
q=len(C)
while q > k:
寻找距离最小的两个簇a和b
将a和b合并,并修改C
q = len(C)
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
视为过关。
- import numpy as np
- def AGNES(feature, k):
- '''
- AGNES聚类并返回聚类结果
- 假设数据集为`[1, 2], [10, 11], [1, 3]],那么聚类结果可能为`[[1, 2], [1, 3]], [[10, 11]]]
- :param feature:训练数据集所有特征组成的ndarray
- :param k:表示想要将数据聚成`k`类,类型为`int`
- :return:聚类结果
- '''
- #********* Begin *********#
- # 找到距离最小的下标
- def find_Min(M):
- min = np.inf
- x = 0;
- y = 0
- for i in range(len(M)):
- for j in range(len(M[i])):
- if i != j and M[i][j] < min:
- min = M[i][j];
- x = i;
- y = j
- return (x, y, min)
- #计算簇间最大距离
- def calc_max_dist(cluster1, cluster2):
- 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
- #初始化C和M
- C = []
- M = []
- for i in feature:
- Ci = []
- Ci.append(i)
- C.append(Ci)
- for i in C:
- Mi = []
- for j in C:
- Mi.append(calc_max_dist(i, j))
- M.append(Mi)
- q = len(feature)
- #合并更新
- while q > k:
- x, y, min = find_Min(M)
- C[x].extend(C[y])
- C.pop(y)
- M = []
- for i in C:
- Mi = []
- for j in C:
- Mi.append(calc_max_dist(i, j))
- M.append(Mi)
- q -= 1
- return C
- #********* End *********#
本关任务:sklearn
中的AgglomerativeClustering
类实现了AGNES
算法,本关你需要使用 sklearn
中AgglomerativeClustering
来对红酒数据进行聚类。
为了完成本关任务,你需要掌握:AgglomerativeClustering
数据集为一份红酒数据,一共有178
个样本,每个样本有13
个特征,这里不会提供你红酒的标签,你需要自己根据这13
个特征对红酒进行聚类,部分数据如下图:
数据获取代码:
import pandas as pd
data_frame = pd.read_csv('./step3/dataset.csv', header=0)
AgglomerativeClustering
的构造函数中有两个常用的参数可以设置:
n_clusters
:将数据聚成n_clusters
个类linkage
:设置AGNES
聚类时使用最小簇间距离、最大簇间距离还是平均距离。传入ward
表示最小簇间距离,传入complete
表示最大簇间距离,传入average
表示平均距离AgglomerativeClustering
类中的fit_predict
函数用于训练模型并获取聚类结果,fit_predict
函数有一个向量输入:
X
:数据集,形状为**[样本数量,特征数量]**的ndarray
AgglomerativeClustering
的使用代码如下:
from sklearn.cluster import AgglomerativeClustering
agnes = AgglomerativeClustering(k=5)
# 注意:x为ndarray
result = agnes.fit_predict(x)
在Begin-End
区域填写Agglomerative_cluster(data)
函数完成红酒数据聚类任务,簇的数量为3
。其中:
data
:数据样本,类型为ndarray
,shape=[样本数量, 特征数量]
return
: 聚类结果,类型为ndarray
注意:直接使用原始数据进行聚类的效果可能不太理想,你可能需要对数据进行预处理。
提示:AGNES算法需要计算距离,想想什么样的预处理方式对依赖距离的算法有好的效果。
只需返回聚类结果即可,程序内部会检测您的代码,吻合度高于0.9
视为过关。
- #encoding=utf8
- from sklearn.cluster import AgglomerativeClustering
-
- def Agglomerative_cluster(data):
- '''
- 对红酒数据进行聚类
- :param data: 数据集,类型为ndarray
- :return: 聚类结果,类型为ndarray
- '''
-
- #********* Begin *********#
- from sklearn.preprocessing import StandardScaler
- scaler = StandardScaler()
- data = scaler.fit_transform(data)
- agnes = AgglomerativeClustering(n_clusters=3)
- result = agnes.fit_predict(data)
- return result
-
- #********* End *********#
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。