数学建模——聚类分析

前言

本文是笔者在B站的学习收获,B站教程:www.bilibili.com/video/BV1kC...

本文将通过案例详细介绍聚类分析,包括完整建模和编程(matlab编写)过程。

本文还会介绍一部分k-means算法。

正文

什么是聚类?
◆聚类是一个将数据集划分为若干组或类的过程,并使得同一个组内的数据对象具有较高的相似度;而不同组中的数据对象是不相似的。

◆相似或不相似是基于数据描述属性的取值来确定的,通常利用各数据对象间的距离来进行表示。

◆聚类分析尤其适合用来探讨样本间的相互关联关系从而对一个样本结构做一个初步的评价。
聚类分析有两种:一种是对样品的分类,称为Q型 ,另一种是对变量(指标)的分类,称为R型

R型聚类分析的主要作用:

(1)不但可以了解个别变量之间的亲疏程度,而且可以了解各个变量组合之间的亲疏程度。

(2)根据变量的分类结果以及它们之间的关系,可以选择主要变量进行Q型聚类分析或回归分析。(R2为选择标准)

Q型聚类分析的主要作用:

(1)可以综合利用多个变量的信息对样本进行分析。

(2)分类结果直观,聚类谱系图清楚地表现数值分类结果。

(3)聚类分析所得到的结果比传统分类方法更细致、全面、合理。我们主要讨论Q型聚类分析,Q型聚类常用的统计量是距离.

问题:

为了研究辽宁等5省1991年城镇居民生活消费情况的分布规律,根据调查资料做类型分类,用最短距离做类间分类。数据如下:

求解:

使用谱系聚类法求解问题,谱系聚类法即一般的聚类方法。

1. 选择样本间距离的定义及类间距离的定义;

这里样板间距离选择欧式距离计算,类间距离选择类最短距离计算:

即用两类中样品之间的距离最短者作为两类间距离

2. 计算n个样本两两之间的距离,得到距离矩阵

根据1中选择的欧氏距离编写代码求出距离:

ini 复制代码
b=[7.9 39.77 8.49 12.94 19.27 11.05 2.04 13.29
 7.68 50.37 11.35 13.3 19.25 14.59 2.75 14.87
 9.42 27.93 8.2 8.14 16.17 9.42 1.55 9.76
 9.16 27.98 9.01 9.32 15.99 9.1 1.82 11.35
 10.06 28.64 10.52 10.05 16.18 8.39 1.96 10.81];
d1=pdist(b); % b中每行之间距离

为了方便看,可以把结果转换成下三角矩阵:

ini 复制代码
S = tril(squareform(d1))

此时结果(S)为:

3. 构造个类,每类只含有一个样本;

将每一个省区视为一个样品 ,也就是每个类中仅包含一个省区:

4. 合并符合类间距离定义要求的两类为一个新类;

根据1中选择的类最小距离,找到此时距离矩阵的最小数2.2,它对应的坐标是(4,3),所以我们将3.4合并为一类,为类6,替代了3、4两类 。

类6与剩余的1、2、5之间的距离都选择3,4和他们的最小值:

这样就形成了一个新的距离矩阵:

5. 计算新类与当前各类的距离。

若类的个数为1,则转到步骤6,否则回到步骤4;

这一步相当于判断条件,用来决定是否终止循环的,按照步骤最后跳出循环的矩阵是1*1大小的。

但是放在matlab中,这个循环步骤用一行代码就可以完成:

ini 复制代码
z1= linkage(d1)

并且会输出聚类结果:

这表示:

在2.2033的水平,G3,G4合成一类为G6

在2.2159的水平,G6,G5合成一类为G7

在11.6726的水平,G1,G2合成一类为G8

在12.7983的水平,G7,G8合成一类

6.画出聚类图;

代码为:

ini 复制代码
H=dendrogram(z1,d) % 注意若样本少于30,可以省去d,否则必须填写.

按照注释,此时d可以省略,代码修改为:

ini 复制代码
H=dendrogram(z1)

结果为:

这个图和步骤5中的聚类结果一一对应。

7.决定类的个数和类。

ini 复制代码
T=cluster(z1,k) % 注意k是分类数目

这里假设分成3类,即k=3,结果为:

数字一样的表示在一个类中,也就是说我们分类的结果是:

辽宁在第一类,浙江在第二类,河南、甘肃、青海在第三类。

此时如果再看聚类图可以知道,如果要分成三类,应该在2.2159的水平,此时G6,G5合成一类为G7 ,也就是3、4、5一类的意思。

k-means算法

特点:

只适用于聚类均值有意义的场合,在某些应用中,如:数据集中包含符号属性时,直接应用k-means算法就有问题;

用户必须事先指定k的个数;

对噪声和孤立点数据敏感,少量的该类数据能够对聚类均值起到很大的影响。

步骤:

简而言之就是,在一堆点中,先指定任意个点作为中心点,点的个数为k,然后计算对每个点计算到这些中心点的距离(如欧氏距离等方法),和距离该点最近的中心点暂时分为一类。

然后在每一类中根据其中的点计算这一类的重心:

等等

用这些重心来更新之前的中心点,然后再计算每个点计算到这些中心点的距离,和距离该点最近的中心点又暂时分为一类。

一直重复这个过程,直到每个点所属的类不再发生改变。

相关推荐
XY_墨莲伊4 小时前
【算法设计与分析】实验5:贪心算法—装载及背包问题
c语言·数据结构·c++·算法·贪心算法·排序算法
Happy_Traveller5 小时前
三角形的最大周长(976)
数据结构·算法·leetcode
水蓝烟雨5 小时前
[HOT 100] 2824. 统计和小于目标的下标对数目
算法·hot 100
KuaCpp5 小时前
搜索与图论复习2最短路
c++·算法·图论
咒法师无翅鱼5 小时前
【leetcode详解】T598 区间加法
算法·leetcode·职场和发展
砂糖はいかがですか。6 小时前
关于合并两个有序链表
数据结构·算法·链表
不会打代码呜呜呜呜6 小时前
小白零基础--CPP多线程
开发语言·c++·算法
辰尘_星启7 小时前
【单层神经网络】基于MXNet的线性回归实现(底层实现)
算法·线性回归·mxnet
kcwqxx7 小时前
day37|完全背包基础+leetcode 518.零钱兑换II ,377.组合总和II
c++·算法·leetcode·动态规划
程序趣谈7 小时前
算法随笔_36: 复写零
数据结构·python·算法