Educoder机器学习课程:聚类第一关
目录
任务描述
相关知识
编程要求
聚类第一关—聚类任务简述
任务描述
本关任务:了解无监督学习、聚类任务和性能度量的相关概念,使用python
语言编程实现性能度量函数。
相关知识
无监督学习
无监督学习着重于发现数据本身的分布特点。与监督学习不同,无监督学习不需要对数据进行标记。从功能角度讲,无监督学习模型可以发现数据的“群落”,同时也可以寻找“离群”的样本。另外,对于特征维度非常高的数据样本,同样可以通过无监督学习进行数据降维,保留最具有区分性的低维度特征。无监督学习里典型例子是聚类。
聚类任务
聚类是一个将数据对象集划分为多个组或簇的过程,使得簇内的数据对象具有很高的相似性,但不同簇间的对象具有很高的相异性。
聚类在“无监督学习”任务中研究最多、应用最广。聚类目标:将数据集中的样本划分为若干个通常不相交的子集(“簇”,cluster)。聚类既可以作为一个单独过程(用于找寻数据内在的分布结构),也可作为分类等其他学习任务的前驱过程。
聚类任务的形式化描述:假定样本集 D={x1,x2,⋯,xm}
包含 m 个无标记样本,每个样本 xi=(xi1,xi2,⋯,xin) 是一个 n 维的特征向量,聚类算法将样本集 D 划分成 k 个不相交的簇 {Cl∣l=1,2,…,k}
,其中 Cl′⋂l′=lCl=ϕ,且 D=⋃l=1kCl 。相应地,用 λj∈1,2,⋯,k 表示样本 xj 的“簇标记”,即 xj∈Cλj 。于是,聚类的结果可用包含 m 个元素的簇标记向量 λ={λ1,λ2,⋯,λm}
表示。
聚类性能度量
编程要求
根据提示,在右侧编辑器Begin-End部分补充代码。
任务描述:使用Python语言,对聚类结果进行性能评估。
外部指标:将聚类结果与某个“参考模型”进行比较。
对数据集 D={x1,x2,…,xm}
,假定通过聚类得到的簇划分为 C={C1,C2,…,Ck}
,参考模型给出的簇划分为 C∗={C1∗,C2∗,…,Cs∗}
。相应地,令 λ 与 λ∗
分别表示与 C 和 C∗ 对应的簇标记向量。
我们将样本两两配对考虑,定义
1. Jaccard 系数(Jaccard Coefficient, JC)
JC=a+b+ca
2. FM 指数(Fowlkes and Mallows Index, FMI)
FMI=a+ba⋅a+ca
3. Rand 指数(Rand Index, RI)
RI=m(m−1)2(a+b)
以上指数在 [0,1] 区间内,越大越好。
内部指标:直接考察聚类结果而不用任何参考模型。
考虑聚类结果的簇划分 C={C1,C2,…,Ck}
,定义
1.簇 C 内样本间的平均距离
avg(C)=∣C∣(∣C∣−1)21≤i≤j≤∣C∣∑dist(xi,xj)
2.簇 C 内样本间的最远距离
diam(C)=1≤i≤j≤∣C∣maxdist(xi,xj)
3.簇 Ci 与簇 Cj 最近样本间的距离
dmin(C)=xi∈Ci,xj∈Cjmindist(xi,xj)
4.簇 Ci 与簇 Cj 中心点间的距离
dcen(C)=dist(μi,μj)
# 导入库
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
from sklearn.model_selection import train_test_split
import numpy as np
# 加载鸢尾花数据集
iris = load_iris()
x = iris['data']
y = iris['target']
# 将数据集分为训练集和测试集
np.random.seed(0)
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.1)
# 任务1:创建 KMeans 对象,令 n_clusters=4
########## Begin ##########
kmeans = KMeans(n_clusters=4)
########## End ##########
# 任务2:调用 fit 函数执行训练过程
########## Begin ##########
kmeans = kmeans.fit(x_train)
########## End ##########
# 任务3:调用 predict 函数进行预测
########## Begin ##########
y_pred = kmeans.predict(x_test)
########## End ##########
# 打印结果
print("真实结果:\n", y_test)
print("预测结果:\n", y_pred)
# 计算 a,b,c,d
a = b = c = d = 0
m = 15
for j in range(m):
for i in range(j):
if y_test[i]==y_test[j] and y_pred[i]==y_pred[j]:
a = a + 1
elif y_test[i]==y_test[j] and y_pred[i]!=y_pred[j]:
b = b + 1
elif y_test[i]!=y_test[j] and y_pred[i]==y_pred[j]:
c = c + 1
else:
d = d + 1
# 根据公式计算 Jaccard 系数
JC = a / (a + b + c)
# 根据公式计算 FM 指数
FM = np.sqrt(a ** 2 / ((a + b) * (a + c)))
# 根据公式计算 Rand 指数
RI = 2 * (a + b) / (m * (m - 1))
# 打印结果
print("Jaccard 系数为{},FM 指数为{},Rand 指数为{}。".format(JC, FM, RI))
作者:鹿毅十川