机器学习本科课程 实验6 聚类实验

第一题:使用sklearn的DBSCAN和AgglomerativeClustering完成聚类

实验内容:

  1. 使用sklearn的DBSCAN和AgglomerativeClustering在两个数据集上完成聚类任务
  2. 对聚类结果可视化
  3. 对比外部指标FMI和NMI

1. 导入模块

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inlineimport warnings
warnings.filterwarnings('ignore')

2. 生成数据集

from sklearn import datasets
X1, y1 = datasets.make_circles(n_samples = 1500, factor = 0.5, noise = 0.05, random_state = 32)
X2, y2 = datasets.make_moons(n_samples = 1500, noise = 0.05, random_state = 32)
colors = np.array(['#377eb8', '#ff7f00', '#4daf4a', '#f781bf', '#a65628', '#984ea3', '#999999', '#e41a1c', '#dede00'])
plt.title('dataset1')
plt.scatter(X1[:, 0], X1[:, 1], s = 10, c = colors[y1])
plt.title('dataset2')
plt.scatter(X2[:, 0], X2[:, 1], s = 10, c = colors[y2])

3. 导入模型

我们导入密度聚类和层次聚类两个模型

from sklearn.cluster import DBSCAN, AgglomerativeClustering

4. 训练模型

dbscan = DBSCAN(eps = 0.1)
dbscan.fit(X1)

密度聚类模型使用模型的labels_属性就可以获得聚类后的类标记

dbscan.labels_

层次聚类的linkage参数表示我们要用哪种距离(最小、最大、平均)进行聚类。这里我们选择single,表示最小距离。complete表示最大距离,average表示平均距离。

注意:single参数是在sklearn 0.20版本才加入的!

agg = AgglomerativeClustering(n_clusters = 2, linkage="single")
agg.fit(X1)

5. 聚类结果可视化

plt.figure(figsize = (8, 4))
plt.subplot(121)
plt.title('DBSCAN dataset1')
plt.scatter(X1[:, 0], X1[:, 1], s = 10, c = colors[dbscan.labels_])plt.subplot(122)
plt.title('AGG dataset1')
plt.scatter(X1[:, 0], X1[:, 1], s = 10, c = colors[agg.labels_])

6. 指标计算

我们这里选用两个外部指标,FMI和NMI。

互信息(mutual information)表示了两个分布的一致程度。归一化的互信息(NMI)将互信息值映射到0到1的空间内。值越高,说明两个分布的一致性越高。

FMI是Fowlkes-Mallows index,使用precision和recall计算得到,其值域也是0到1,越大说明聚类效果越和参考模型相近。

from sklearn.metrics import normalized_mutual_info_score
from sklearn.metrics import fowlkes_mallows_score
normalized_mutual_info_score(y1, dbscan.labels_)
normalized_mutual_info_score(y1, agg.labels_)
fowlkes_mallows_score(y1, dbscan.labels_)
fowlkes_mallows_score(y1, agg.labels_)

Test

请你使用密度聚类和高斯混合模型在数据集X2上进行聚类,绘制聚类后的效果。计算FMI和NMI值,填入下标

双击此处填写

()

算法FMINMI
密度聚类0.99870.9934
高斯混合模型0.74750.3952
from sklearn.mixture import GaussianMixture
# 密度聚类 (DBSCAN)
dbscan = DBSCAN(eps=0.1) 
dbscan_labels = dbscan.fit_predict(X2)# 高斯混合模型 (Gaussian Mixture Model)
gmm = GaussianMixture(n_components=2, random_state=32)
gmm_labels = gmm.fit_predict(X2)# 绘制密度聚类效果
plt.figure(figsize=(12, 5))plt.subplot(1, 2, 1)
plt.scatter(X2[:, 0], X2[:, 1], c=colors[dbscan_labels], cmap='viridis', s=50)
plt.title('DBSCAN Clustering')# 绘制高斯混合模型效果
plt.subplot(1, 2, 2)
plt.scatter(X2[:, 0], X2[:, 1], c=colors[gmm_labels], cmap='viridis', s=50)
plt.title('Gaussian Mixture Model Clustering')plt.show()# 计算 FMI 和 NMI 值
fmi_dbscan = fowlkes_mallows_score(y2, dbscan_labels)
nmi_dbscan = normalized_mutual_info_score(y2, dbscan_labels)fmi_gmm = fowlkes_mallows_score(y2, gmm_labels)
nmi_gmm = normalized_mutual_info_score(y2, gmm_labels)print(f"密度聚类 - Fowlkes Mallows Index: {fmi_dbscan:.4f}")
print(f"密度聚类 - Normalized Mutual Info: {nmi_dbscan:.4f}")
print()
print(f"高斯混合模型 - Fowlkes Mallows Index: {fmi_gmm:.4f}")
print(f"高斯混合模型 - Normalized Mutual Info: {nmi_gmm:.4f}")

第二题:实现K-means

实验内容:

  1. 实现一个K-means聚类算法
  2. 计算外部指标FMI和NMI
  3. 对聚类结果可视化
  4. 完成第二个数据集上myKmeans与层次聚类(single)算法的对比
我们要实现一个K-means算法,也称为原型聚类算法。## 初始化K-means在实现的时候,首先需要选取类簇中心。类簇中心的选取方法有很多,我们这里使用最简单的方法,随机选取。也就是,从给定的待聚类的样本中,随机选取 $K$ 个样本,作为 $K$ 个类簇的中心。## 优化选取类中心后,就需要不断的调成类中心的位置,开始优化过程,优化主要分为两步:### 第一步计算所有样本到 $K$ 个类中心的距离。每个样本,选择距自己最近的类中心作为自己属于的类簇。(这里的距离我们选择欧式距离)### 第二步针对第一步分出来的 $K$ 个类簇,计算每个类簇内样本的均值,将计算得到的 $K$ 个均值向量,作为这 $K$ 个类簇新的中心。### 然后循环第一步和第二步,直至一定的迭代次数,或类中心无显著的位置改变为止。

1. 导入模块

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inlineimport warnings
warnings.filterwarnings('ignore')

2. 生成数据集

from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples = 1500, random_state = 170)

这里的X和y分别代表样本和对应的真实标记。

使用plt.scatter绘制散点图,参数c是一个np.ndarray,表示类别,相同的值会有相同的颜色。

plt.scatter(X[:, 0], X[:, 1], c = y)

3. 欧式距离的实现

给定向量 x ∈ R m x \in \mathbb{R}^m xRm y ∈ R m y \in \mathbb{R}^m yRm,两个向量的欧式距离定义为:

E ( x , y ) = ∑ i = 1 m ( x i − y i ) 2 E(x, y) = \sqrt{\sum^m_{i = 1} (x_i - y_i)^2} E(x,y)=i=1m(xiyi)2

其中, i i i 表示向量的第 i i i 个分量。

我们要实现一个可以计算多个样本组成的矩阵 X X X,与某一个类中心 y y y 之间欧氏距离的函数。

给定输入矩阵 X ∈ R n × m X \in \mathbb{R}^{n \times m} XRn×m,其中 n n n 是样本数, m m m 是特征数,给定输入的类簇中心 y ∈ R m y \in \mathbb{R}^m yRm

我们要计算 n n n 个样本到某一类簇中心 y y y 的欧式距离,最后的结果是 E ∈ R n E \in \mathbb{R}^{n} ERn,每个元素表示矩阵 X X X 中的每个样本到类中心 y y y 的欧式距离。

def compute_distance(X, y):'''计算样本矩阵X与类中心y之间的欧氏距离Parameters----------X, np.ndarray, 样本矩阵 X, 维度:(n, m)y, np.ndarray, 类中心 y,维度:(m, )Returns----------distance, np.ndarray, 样本矩阵 X 每个样本到类中心 y 之间的欧式距离,维度:(n, )'''# YOUR CODE HEREy= np.tile(y, (X.shape[0], 1))distance = np.sum(((X-y)**2),axis=1)**0.5return distance
# 测试样例
print(compute_distance(np.array([[0, 0], [0, 1]]), np.array([0, 1]))) # [ 1.  0.]
print(compute_distance(np.array([[0, 0], [0, 1]]), np.array([1, 1]))) # [ 1.41421356  1.        ]

下面开始实现K-means聚类算法

class myKmeans:def __init__(self, n_clusters, max_iter = 100):'''初始化,三个成员变量Parameters----------n_clusters: int, 类簇的个数max_iter, int, default 100, 最大迭代轮数,默认为100'''# 表示类簇的个数self.n_clusters = n_clusters# 表示最大迭代次数self.max_iter = int(max_iter)# 类簇中心self.centroids = Nonedef choose_centroid(self, X):'''选取类簇中心Parameters----------X: np.ndarray, 样本矩阵X,维度:(n, m)Returns----------centroids: np.ndarray, 维度:(n_clusters, m)'''centroids = X[np.random.choice(np.arange(len(X)), self.n_clusters, replace = False), :]return centroidsdef compute_label(self, X):'''给定样本矩阵X,结合类中心矩阵self.centroids,计算样本矩阵X内每个样本属于哪个类簇Parameters----------X: np.ndarray, 样本矩阵X,维度:(n, m)Returns----------labels: np.ndarray, 维度:(n, )'''# 将每个样本到每个类簇中心的距离存储在distances中,每行表示当前样本对于不同的类中心的距离distances = np.empty((len(X), self.n_clusters))# 遍历类中心,对每个类中心,计算所有的样本到这个类中心的距离for index in range(len(self.centroids)):# 计算样本矩阵X所有样本到当前类中心的距离,存储在distances中的第index列中# YOUR CODE HEREdistances[:, index] = compute_distance(X, self.centroids[index])# 取distances每行最小值的下标,这个下标就是这个样本属于的类簇的标记# YOUR CODE HERElabels = np.argmin(distances, axis=1)# 返回每个样本属于的类簇的标记return labelsdef fit(self, X):'''聚类,包含类中心初始化,类中心优化两个部分Parameters----------X: np.ndarray, 样本矩阵X,维度:(n, m)'''# 类中心随机初始化self.centroids = self.choose_centroid(X)# 优化self.max_iter轮for epoch in range(self.max_iter):# 计算当前所有样本的属于哪个类簇labels = self.compute_label(X)# 重新计算每个类簇的类中心for index in range(self.n_clusters):# 重新计算第 index 个类中心,对属于这个类簇的样本取均值# YOUR CODE HEREself.centroids[index, :] = X[labels == index].sum(axis=0) / X[labels == index].shape[0]

4. 聚类

# 初始化一个3类簇的模型
model = myKmeans(3)# 对X进行聚类,计算类中心
model.fit(X)# 计算X的类标记
prediction = model.compute_label(X)

5. 聚类结果可视化

# 使用我们的预测结果上色
plt.scatter(X[:, 0], X[:, 1], c = prediction)

6. 评价指标

这里,我们选用两个外部指标,FMI和NMI。

from sklearn.metrics import normalized_mutual_info_score
from sklearn.metrics import fowlkes_mallows_score
print(normalized_mutual_info_score(y, prediction))
print(fowlkes_mallows_score(y, prediction))

Test

使用下面提供的数据,完成以下实验:

  1. 使用myKmeans和层次聚类算法(AgglomerativeClustering)对该数据进行聚类。
  2. 计算出两个模型的FMI和NMI值,并对聚类结果可视化。
  3. 分析为什么两个模型的聚类效果会出现如此的不同。

要求:

  1. 层次聚类的连接方式选择’single’,即使用两个类簇之间的最小距离
  2. 类簇个数设定为2

完成下表的填写:

双击此处填写
算法FMINMI
myKmeans0.49960.0003
AgglomerativeClustering1.00001.0000
from sklearn.datasets import make_circles
X, y = make_circles(n_samples = 1500, factor = .5, noise = .05, random_state = 32)
plt.scatter(X[:, 0], X[:, 1], c = y)
# 初始化一个2类簇的模型
model_test = myKmeans(2)# 对X进行聚类,计算类中心
model_test.fit(X)# 计算X的类标记
prediction = model_test.compute_label(X)
plt.figure(figsize=(12, 4))plt.subplot(1, 2, 1)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis', s=40)
plt.title("True Clusters")plt.subplot(1, 2, 2)
plt.scatter(X[:, 0], X[:, 1], c=prediction, cmap='viridis', s=40)
plt.title("Agglomerative Clustering")plt.show()# 计算评估指标
fmi1 = fowlkes_mallows_score(y, prediction)
nmi1 = normalized_mutual_info_score(y, prediction)
print(f"K-means - Fowlkes Mallows Index: {fmi1:.4f}")
print(f"K-means - Normalized Mutual Info: {nmi1:.4f}")
# YOUR CODE HERE
agg2 = AgglomerativeClustering(n_clusters=2, linkage='single')
labels2 = agg2.fit_predict(X)
plt.figure(figsize=(12, 4))plt.subplot(1, 2, 1)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis', s=40)
plt.title("True Clusters")plt.subplot(1, 2, 2)
plt.scatter(X[:, 0], X[:, 1], c=labels2, cmap='viridis', s=40)
plt.title("Agglomerative Clustering")plt.show()# 计算评估指标
fmi2 = fowlkes_mallows_score(y, labels2)
nmi2 = normalized_mutual_info_score(y, labels2)
print(f"层次聚类 - Fowlkes Mallows Index: {nmi2:.4f}")
print(f"层次聚类 - Normalized Mutual Info: {nmi2:.4f}")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/667864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第二届 N1CTF Junior WEB方向 部分题解WP

zako 题目描述&#xff1a;很简单的rce哦 启动环境&#xff0c;源码直接给了。 execute.sh #!/bin/bashreject(){echo ${1}exit 1 }XXXCMD$1awk -v str"${XXXCMD}" \ BEGIN{deny";&$(){}[]!#$%^&*-";for(i 1; i < length(str); i){char su…

力扣:216. 组合总和 III

回溯解法思路&#xff1a; 1.先声明一个集合来接受全部组合等于n的组合&#xff0c;在声明一个单个组合的集合来接收遍历的全部的组合。 2.写一个回溯函数&#xff0c;里面有终止条件和遍历全部组合的for循环来进行遍历全部的组合&#xff0c;终止条件为li2的集合的长度等于k…

Open CASCADE学习|分割曲线

1、通过参数进行分割 分别获得曲线的 FirstParameter 和 LastParameter &#xff0c;然后对参数进行分割&#xff0c;获得n个ui&#xff0c;并对每个ui调用D0&#xff08;获得这个点的坐标值&#xff09;或D1&#xff08;获得这个点的坐标值和切向量&#xff09;。这个方法的优…

《图像处理》 图像细化

前言 图像细化算法又称之为Thinning Algorithms&#xff0c;或者骨架提取&#xff08;skeleton&#xff09;。该算法通常用于手写体数字的细化&#xff0c;输入的图像要求是黑白图像&#xff0c;即二值图像。从白色区域提取出该区域的中心线&#xff0c;中心线对于白色区域相当…

Transformer的PyTorch实现之若干问题探讨(一)

《Transformer的PyTorch实现》这篇博文以一个机器翻译任务非常优雅简介的阐述了Transformer结构。在阅读时存在一些小困惑&#xff0c;此处权当一个记录。 1.自定义数据中enc_input、dec_input及dec_output的区别 博文中给出了两对德语翻译成英语的例子&#xff1a; # S: de…

编译原理本科课程 专题5 基于 SLR(1)分析的语义分析及中间代码生成程序设计

一、程序功能描述 本程序由C/C编写&#xff0c;实现了赋值语句语法制导生成四元式&#xff0c;并完成了语法分析和语义分析过程。 以专题 1 词法分析程序的输出为语法分析的输入&#xff0c;完成以下描述赋值语句 SLR(1)文法的语义分析及中间代码四元式的过程&#xff0c;实现…

开源节点框架STNodeEditor使用

节点&#xff0c;一般都为树形Tree结构&#xff0c;如TreeNode&#xff0c;XmlNode。 树形结构有其关键属性Parent【父节点】&#xff0c;Children【子节点】 LinkedListNode为链表线性结构&#xff0c;有其关键属性Next【下一个】&#xff0c;Previous【上一个】&#xff0c…

1978-2022年人民币汇率(年平均价)数据

1978-2022年人民币汇率&#xff08;年平均价&#xff09;数据 1、时间&#xff1a;1978-2022年&#xff0c;其中人民币对欧元汇率时间为2002-2022年 2、指标&#xff1a;人民币对美元汇率(美元100)(元)、人民币对日元汇率(日元100)(元)、人民币对港元汇率(港元100)(元)、人民…

华为突然官宣:新版鸿蒙系统,正式发布

华为&#xff0c;一家始终引领科技创新潮流的全球性企业&#xff0c;近日再次引发行业震动——全新HarmonyOS NEXT&#xff0c;被誉为“纯血版鸿蒙”的操作系统正式官宣。这是华为在操作系统领域迈出的坚实且具有突破性的一步&#xff0c;标志着华为正逐步摆脱对安卓生态系统的…

3D力导向树插件-3d-force-graph学习002

一、实现效果&#xff1a;节点文字同时展示 节点显示不同颜色节点盒label文字并存节点上添加点击事件 二、利用插件&#xff1a;CSS2DRenderer 提示&#xff1a;以下引入文件均可在安装完3d-force-graph的安装包里找到 三、关键代码 提示&#xff1a;模拟数据可按如下格式填…

Node.js 包管理工具

一、概念介绍 1.1 包是什么 『包』英文单词是 package &#xff0c;代表了一组特定功能的源码集合 1.2 包管理工具 管理『包』的应用软件&#xff0c;可以对「包」进行 下载安装 &#xff0c; 更新 &#xff0c; 删除 &#xff0c; 上传 等操作。 借助包管理工具&#xff0…

深度学习本科课程 实验5 循环神经网络

循环神经网络实验 任务内容 理解序列数据处理方法&#xff0c;补全面向对象编程中的缺失代码&#xff0c;并使用torch自带数据工具将数据封装为dataloader分别采用手动方式以及调用接口方式实现RNN、LSTM和GRU&#xff0c;并在至少一种数据集上进行实验从训练时间、预测精度、…

android tv开发-1,leanback

目录 1.leanback库的一些事 2.leanback在使用时遇到的一些麻烦 视频卡片 页面空白 关于左侧菜单的一些设置 数据加载异常与加载中的一些操作 如果页面无数据,如何显示错误的页面.

视频美颜SDK开发指南:从入门到精通的技术实践

美颜SDK是一种强大的工具&#xff0c;它不仅仅可以让用户在实时视频中获得光滑的肌肤和自然的妆容&#xff0c;从简单的滤镜到复杂的人脸识别&#xff0c;美颜SDK涵盖了广泛的技术领域。 一、美颜SDK的基本原理 美颜SDK包括图像处理、人脸检测和识别、滤镜应用等方面。掌握这些…

2024日常训练

#一些简单的训练 第一题&#xff1a;带余除法 来源于dotcpp、 习题一 &#xff08;题目可以自己去看一看&#xff0c;这里就直接开始写题解了&#xff09; 题解&#xff1a; 1.需要用到map()函数来接受一行整数输入 2.需要用到---end 这里就可以实现输出结果在同一行 …

mysql 使用join进行多表关联查询

join类型 在一些报表统计或数据展示时候需要提取的数据分布在多个表中&#xff0c;这个时候需要进行join连表操作。join将两个或多个表当成不同的数据集合&#xff0c;然后进行集合取交集运算。比如有订单Order表记录用户id&#xff0c;如果像查询订单对应的用户信息&#xff…

uniapp中使用EelementPlus

uniapp的强大是非常震撼的&#xff0c;一套代码可以编写到十几个平台。这个可以在官网上进行查询uni-app官网。主要还是开发小型的软件系统&#xff0c;使用起来非常的方便、快捷、高效。 uniapp中有很多自带的UI&#xff0c;在创建项目的时候&#xff0c;就可以自由选择。而E…

网络编程面试系列-01

1. 应用层中常见的协议都有哪些? 应用层协议(application layer protocol)定义了运行在不同端系统上的应用程序进程如何相互传递报文。 应用层协议 1)DNS:一种用以将域名转换为IP地址的Internet服务,域名系统DNS是因特网使用的命名系统,用来把便于人们使用的机器名字…

Unity类银河恶魔城学习记录1-11 PlayerPrimaryAttack P38

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Player.cs using System.Collections; using System.Collections.Generic…

苹果公司宣布,为Apple Vision Pro打造了超过600款新应用

深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领域的领跑者。点击订阅&#xff0c;与未来同行&#xff01; 订阅&#xff1a;https://rengongzhineng.io/ 。 2月…