当前位置: 首页 > news >正文

机器学习实验四 ——基于距离的层次聚类

本关任务:
使用scipy实现自下而上的凝聚聚类并作聚类分析。
相关知识

为了完成本关任务,你需要掌握:1.层次聚类算法,2.空间和聚类分析。
层次聚类介绍

层次聚类存在两个方向或两种方法。一个是自下而上,另一个是自上而下。对于自下而上,每个点一开始是作为一个单独的集群。接着,将两个最接近的集群合并,以形成一个两点集群。该过程将继续合并最接近的集群,直到您获得包含所有点的单个集群。自下而上又称为凝聚聚类。自上而下正好相反。它从包含所有点的单个集群开始,然后进行分割,直到每个集群都变成一个单独的点。

无论使用哪种方法,分层聚类都会针对 n 个数据点生成集群聚类树。生成集群聚类树后,可以选择一个层级来获取集群。
树状图

第二关任务中的聚类视图依赖于数据的二维性质,因此不能用于具有两个以上特征的数据集。另一种将层次聚类可视化的工具,叫树状图(dendrogram),可以用来处理多维数据集。

目前sk-learn没有直接绘制树状图的功能,但我们可以利用scipy轻松生成树状图。

树状图在底部显示数据点。然后以这些点(表示单点簇)作为叶节点绘制一棵树,每合并两个簇就添加一个新的父节点。以此类推。树状图的y轴不仅说明凝聚算法中两个簇何时合并,每个分支的长度还表示被合并的簇之间的距离。例如,上面树状图中,最长的分支是用标记为three clusters的虚线表示的三条线。它们是最长的分支,这表示从三个簇到两个簇的过程中合并了一些距离非常远的点。
连接标准

在scipy中,可以用linkage 定义连接标准,即如何计算簇间的距离。常用的选项如下:

single:取两个集合中距离最短的两个点的距离作为两个集合的距离
complete:取两个集合中距离最远的两个点的距离作为两个集合的距离
average:把两个集合中的点两两的距离全部放在一起求一个平均值
ward:所有类簇的方差和

数据集

随机生成数据点使聚类服从高斯分布
聚类函数 fcluster

在scipy中,根据linkage matrix可以用fcluster 函数得到聚类结果。任务相关主要函数参数有:

t是用来区分不同聚类的阈值,在不同的criterion条件下所设置的参数是不同的。
criterion代表了聚类判定标准,常用的有: criterion=maxclust时,参数t代表了最大的聚类的个数;criterion=distance时,参数t代表了绝对的差值,如果小于这个差值,两个数据将会被合并,当大于这个差值,两个数据将会被分开;criterion=inconsistent时,参数t应该在0-1之间波动,t越接近1代表两个数据之间的相关性越大,t越趋于0表明两个数据的相关性越小。
depth 代表了进行不一致性(inconsistent)计算的时候的最大深度,对于其他的参数是没有意义的,默认为2.

数据集

随机生成数据点使聚类服从高斯分布
编程要求

根据提示,在右侧编辑器补充代码:调用scipy库计算随机数据集的距离矩阵,用最远距离计算linkage向量并输出一个凝聚聚类的树状图。然后,用fcluster函数对数据集进行聚类并输出聚类结果。

实验代码

 #encoding=utf8
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as mpl
import numpy as np
from mpl_toolkits import mplot3d

from scipy.spatial.distance import pdist,squareform
import scipy.cluster.hierarchy as hy
from scipy.cluster.hierarchy import fcluster #abc

# 用于生成聚类数据的函数
def cluster(number=20, cnumber=5, csize=10):
    # 聚类服从高斯分布
    rnum = np.random.rand(cnumber, 2)
    rn = rnum[:, 0]*number
    rn = rn.astype(int)
    rn[np.where(rn < 5)] = 5
    rn[np.where(rn > number / 2.)] = round(number /2., 0)
    ra = rnum[:, 1]*2.9
    ra[np.where(ra < 1.5)] = 1.5
    cls = np.random.randn(number, 3)*csize
    # 随机设定各聚类的质点
    rxyz = np.random.randn(cnumber-1, 3)
    for i in range(cnumber-1):
        tmp = np.random.randn(rn[i+1], 3)
        x = tmp[:, 0] + ( rxyz[i, 0] * csize )
        y = tmp[:, 1] + ( rxyz[i, 1] * csize )
        z = tmp[:, 2] + ( rxyz[i, 2] * csize )
        tmp = np.column_stack([x, y, z])
        cls = np.vstack([cls, tmp])
    return cls
    
def test(path):
    # 创建待聚类数据
    cls = cluster()
    # 可视化数据  
    fig = mpl.figure(figsize=(8, 8))
    ax = mpl.axes(projection='3d')
    ax.scatter3D(cls[:, 0], cls[:, 1], cls[:, 2], c='b', marker='o')
    fig.savefig(path + 'T4_data.png', bbox='tight')
    ### 根据提示补充代码 #### 
    # 1、计算数据集cls的距离矩阵(默认计算欧式距离,可以尝试其他距离)
    #*****************begin*************************
    D=pdist(cls)
    M=squareform(D)
	#*****************end*************************
    # 2、用簇间最大距离向量建立连接标准Y1
    #*****************begin*************************
    Y1=hy.linkage(M,method='complete') #abc
	#*****************end*************************
    # 3、根据linkage matrix 生成树状图
     #abc
    fig = mpl.figure()
    H = hy.dendrogram(Y1)
    #*****************end*************************
    fig.savefig(path + 'T4_tree.png', bbox='tight')

    # 4、已知最大的聚类的个数t=5,根据Y1用fcluster得到聚类结果
    #*****************begin*************************
    cluster_res = fcluster(Y1,t=1)
	#*****************end*************************
    # 5、可视化聚类结果并保存到'T4_cluster.png'
    #*****************begin*************************
    fig = mpl.figure()  #指定窗口大小 平台运行会出错  figsize 
    ax = mpl.axes(projection='3d') 
    ax.scatter3D(cls[:,0],cls[:,1], cls[:,2],c=cluster_res,marker='o')
    #*****************end*************************
    fig.savefig(path + 'T4_cluster.png', bbox='tight')
    mpl.show()
    return 1

运行截图:
在这里插入图片描述

实验小结:
实验代码不难,最难搞的是在绘图的过程中出现了一个小BUG,在Educoder平台调试了好久,发现在画多个窗口的时候,即出现两个 fig = mpl.figure(figsize(8,8)) fig = mpl.figure(figsize=(10,10)) 会报这个错误“NameError: name ‘figsize’ is not defined”
感觉原因应该是在‘figsize’上面,这个一个系统变量,但由于我使用了多次,这个平台误以为这是我自定义的变量,所以报NameError。(Educoder平台报错总是指向第二个‘figsize’所在的那一行),后来,我直接去掉figsize,不指定窗口大小,代码就过了。
调试代码的神奇之处:就在于你永远无法把握下一个bug可能出现的地方,有一些神bug可能存在玄学(挠挠头,苦笑),可能平台在低内存运行下语法什么的可能会产生一些特殊的效应,具体的解释有待以后的努力学习咯。

相关文章:

  • 机器学习第二关——k-means算法流程
  • eclipse中怎么删除Web App Libraries重复的jar包
  • 常见Http响应状态码
  • 记录EduCoder实验平台的感受(答案匹配机制)
  • 二手车交易系统数据库的表格设计
  • eclipse建servlet 注解正确 却无法访问
  • 软件项目管理EAC、ETC的计算
  • 三点估计法计算完工可能性
  • 求解某项目的关键路径和总工期
  • 软件过程管理复习
  • JDBC封装的JavaBean里面没有ToSting方法,会出现取不到对象,反而取回类的hash码
  • Java中DAO层、Service层和Controller层的区别
  • 程序员之第一关修炼:学会思考,才能学会创造
  • 阅读和笔记同时整理——pdf笔记软件推荐BookxNote
  • Idea工具使用---添加右键菜单
  • [数据结构]链表的实现在PHP中
  • 0x05 Python数据分析,Anaconda八斩刀
  • angular2 简述
  • CentOS7 安装JDK
  • HTML中设置input等文本框为不可操作
  • Linux各目录及每个目录的详细介绍
  • log4j2输出到kafka
  • PHP 小技巧
  • Python_网络编程
  • Vue2.x学习三:事件处理生命周期钩子
  • vue-loader 源码解析系列之 selector
  • webpack4 一点通
  • 初识MongoDB分片
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 给第三方使用接口的 URL 签名实现
  • 构建二叉树进行数值数组的去重及优化
  • 普通函数和构造函数的区别
  • 学习使用ExpressJS 4.0中的新Router
  • 优秀架构师必须掌握的架构思维
  • 【云吞铺子】性能抖动剖析(二)
  • Spring Batch JSON 支持
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #vue3 实现前端下载excel文件模板功能
  • (4) PIVOT 和 UPIVOT 的使用
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (超详细)语音信号处理之特征提取
  • (二)hibernate配置管理
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (转)Linq学习笔记
  • *p++,*(p++),*++p,(*p)++区别?
  • .net framework 4.0中如何 输出 form 的name属性。
  • .net wcf memory gates checking failed
  • .Net 应用中使用dot trace进行性能诊断
  • .NET程序员迈向卓越的必由之路
  • .NET开源快速、强大、免费的电子表格组件