目录

1. 算法原理

1.1 算法介绍

1.2 重要参数

1.2.1 簇数

1.2.2 距离度量

1.3 实现过程

1.4 优缺点

1.4.1 优点

1.4.2 缺点

2. 问题描述

3. 解决问题

3.1 问题分析

3.2 结果计算

3.2.1 确定K值

3.2.2 进行聚类

4. 实验结果与数据分析

4.1 结果展示

4.2 数据分析

4.3 优化改进

5 附录

5.1 详细数据

5.2 完整数据

5.2.1 求平均轮廓系数

5.2.2 肘部法求SSE

        内容来自本人某次作业

1. 算法原理

1.1 算法介绍

        K-means是一种基于聚类分析的算法,是一种基于划分方法的聚类,其核心目标是将数据集划分为k个不同的簇,使每个数据点都属于最近的簇,在簇内部具有较低的差异性,而在不同的簇之间具有较大的差异性。K-means算法的核心思想是计算样本与中心点的距离,并通过反复迭代来最小化簇内方差(损失函数)的总和,从而找到最优的簇划分的解。

图1 聚类效果示意图

        如图1所示,K-means最终会将数据聚类成此效果。

        在K-means算法中,每个簇的中心被称作簇中心或质心,整体误差准则也叫做畸变程度。该算法需要确定的输入参数是簇数k及样本与簇中心之间的距离度量方法,因为其结果对这些参数选择非常敏感。

1.2 重要参数

1.2.1 簇数

        簇数是K-means算法中非常重要的参数之一,一般根据数据量的不同而不同,常见的簇数在3-5左右。确定簇数的方法有:

        手肘法:在不同的簇数下,计算对应的误差平方和SSE,并绘制出簇数与SSE之间的折线图。一般情况下,随着簇数的增加,SSE会不断下降;但是,当簇数接近真实聚类数量时,SSE的下降速度会逐渐变缓,形成一个类似于手肘的拐点,该点的簇数为最佳的聚类数量。

        轮廓系数法:利用轮廓系数来评价聚类的效果。轮廓系数综合考虑了个体到所属簇的距离和与其他簇的距离,值越接近1表示聚类效果越好,越接近-1则表示聚类效果越差。通过计算不同簇数下的平均轮廓系数,并选择平均轮廓系数最大的簇数作为最佳聚类数量。一般来说,轮廓系数小于0.5说明聚类效果不理想,轮廓系数大于0.7说明聚类效果非常好。

        交叉验证法:将原始数据划分为训练集和测试集,利用训练集进行聚类并得到SSE值,然后再将测试集数据进行预测,得到其所属的簇号,并计算测试集数据到其所属簇的SSE值。不断增加簇数,直到测试集的SSE值开始快速增加为止,此时所对应的簇数即为最佳的聚类数量。

1.2.2 距离度量

        距离度量也是K-means算法中非常重要的参数,常用的计算样本与簇中心之间的距离度量方法有:

        欧几里得距离,可理解空间中两点间的直线距离,是最易理解的计算距离的方法也是最常用的方法。不适合高维度数据,对某一维度大数值差异更加敏感。

        曼哈顿距离,也常称为行驶距离。与欧式距离不同,曼哈顿距离可理解为城市中出租车从一点到底另一点的距离,通常是出租车沿着道路行驶的距离所以往往是两点在南北上的距离之和再加上东西方向上的距离之和。反映在坐标上是x轴距离差加上y轴距离差。

      

1.3 实现过程

        (1)选择需要选择合适的特征

        (2)需要确定聚类数量K

        (3)是否进行数据清洗,如去除缺失值、标准化等。

        (4)如何对数据聚类,得到不同组别的数据

1.4 优缺点

        K-means 是一种基于无监督学习的聚类算法,它是将样本空间划分成若干个不相交的球形区域,然后通过对数据对象的重心进行更新,来找到最优的聚类中心。K-means 算法的优点和缺点如下:

1.4.1 优点

        (1)速度快且可扩展:K-means 算法的时间复杂度为 O(n×k×m),其中n表示样本数,k表示聚类数,m表示维数。这意味着该算法在处理大规模数据集时具有优秀的计算效率和运行速度。此外,随着计算机硬件性能的提升和并行计算技术的不断发展,K-means 算法的扩展性也更加出色。

        (2)易于实现和解释:K-means 算法的实现相对简单,无需依赖太多特殊的先验知识,只需要选择合适的聚类数,然后按照迭代式的流程不断地更新聚类中心即可。因此,在实践中,K-means 算法常常被广泛应用于各种数据挖掘、图像处理以及 Web 应用程序等领域。

        (3)应用广泛:K-means 算法可以应用于多种领域,例如电子商务中的商品推荐、自然资源管理中的空间聚类分析以及语音识别、图像分类等方面。

1.4.2 缺点

        (1)需要事先选择聚类数:K-means 算法在使用前必须确定聚类数量K,但是在实际应用中,聚类数量通常不为已知或固定值,如何选择最佳聚类数成为了K-means算法的痛点之一。

        (2) 对初始聚类中心敏感:K-means 算法对初值的设定十分敏感,如果初始聚类中心选择差,容易得到次优解或漏解。同时,K-means 算法也很容易陷入局部最小值状态,这可能导致聚类结果不理想或并不满足需求。

        (3) 不适合处理非球形数据:由于 K-means 算法假设各个簇之间是球形的,因此它不太擅长处理非球形数据集。对于那些包含类似环形、月牙型或肾脏形等复杂形态的数据集,该算法的效果会明显变差。

        (4) 对噪声和异常值敏感:由于 K-means 算法基于欧氏距离度量样本之间的相似性,因此在存在噪声和异常值的情况下,其聚类结果易受到这些干扰因素的影响,导致失去部分可解释性。

        综上所述,K-means 算法作为一种经典的无监督学习算法,在处理数据聚类问题的时候有着出色的优点,但同时也存在着一些不足之处。因此,在实际使用中,需要对算法的缺陷和局限性加以认识,并且采用合适的方法来加以弥补和改进。

2. 问题描述

        已知近年来全国各省市GDP排行榜(不含港澳台和直辖市)如表1所示,详细数据请看附录。请对此数据选择合适的方法进行聚类分析,并给出你的分析过程和结果。

序号 省份 2021年GDP(亿元) 2022年GDP(亿元) 2023年第一季度GDP(亿元) 1 广东 124369 129119 30178.2 2 江苏 116364 122876 29401.7 3 山东 83095 87435 20411 4 浙江 73516 77715 18925 5 河南 58887 61345.1 14969 … … … … … 27 西藏 2000 2134.62 575.87

表1:2022年全国各省市GDP排行榜(部分)

3. 解决问题

3.1 问题分析

通过分析数据,发现可以K-means进行聚类分析。分析步骤如下:

        (1)选择需要选择合适的特征进行聚类

        (2)需要确定聚类数量k

        (3)是否进行数据清洗,如去除缺失值、标准化等。

        (4)如何对数据聚类,得到不同组别的省份,

        (5)数据最终反映了什么问题。

通过对以上问题的分析,得出的分析结果如下:

        (1)本题中可以选取2021-2022年GDP和2023年第一季度GDP作为个特征

        (2)根据肘部法则和平均轮廓系数等方法,确定最佳聚类数量k

        (3)对原始数据进行单位统一,采取亿元为单位。通过分析和查询,没有异常值并补全了部分缺失值。

        (4)运用k-means算法进行聚类。将得到的聚类结果与原始数据进行比较。

       (5)最后,对每个组别的省份进行分析,探究其共性和特征,结合相关信息和经济背景加以解释。

3.2 结果计算

3.2.1 确定K值

        本文采用肘部法则和平均轮廓系数的方法,以确定最佳聚类数量K。通过matlab计算平均轮廓系数,结果如下:

K值 1 2 3 4 5 6 … 27 轮廓系数 NaN 0.6682 0.6374 0.5461 0.4371 0.5919 .. 1

表2 平均轮廓系数表(部分)

        数据过多这里仅展示部分,完整请看附录。将平均轮廓系数画图以进行直观表示:

 图2 轮廓系数折线图

        由图可得,轮廓系数存在一定的波动。从趋势上看k值越大,聚类效果越好,当k趋向27时,轮廓系数趋向为1。但是结合实际问题,我们需要全面考虑,由此需要再计算肘部法的结果,将两者一起考虑得出最优k值

图3 肘部法运算结果

        根据肘部法则和轮廓系数法,可以参考图1和图2两个指标变化情况来选择最佳的簇数k。从数据中可以看出,在K = 6之前SSE下降得很快,之后的下降速度开始变缓。而在k = 6时,轮廓系数首次达到峰值,数值为0.5919较为理想,并且随着k的增加保持较高水平。因此,综合考虑,最佳的簇数K为6。(本题所用的计算代码放于附录)

3.2.2 进行聚类

        得到最优K值后,进行聚类。本文采用matlab进行聚类计算。代码放于附录。

4. 实验结果与数据分析

4.1 结果展示

         经聚类,得到的结果如下:

类别 聚类结果 第一类 广东 江苏 第二类 山东 浙江 第三类 河南 四川 湖北 福建 湖南 安徽 河北 第四类 陕西 江西 辽宁 云南 广西 山西 内蒙古 第五类 贵州 新疆 黑龙江 吉林 甘肃 第六类 海南 宁夏 青海 西藏

表3 聚类结果

        通过聚类效果可得出中国经济按地区GDP划分的六大分类。将每个类别包含省份的数量进行直观表示为:

图4 六类类别包含省份的数量

        为了方便了解每类别中各个省份的GDP情况,根据2022年GDP将六大类省份进行分组画图可得:

图5 六类省份GDP示意图

4.2 数据分析

        就图4而言,第一、二类和第五、六类的数量较少,第三、四类数量较多,结合本题分析可得:这是符合经济规律的,因为一个国家中发展飞快和发展缓慢的地区是相对较少的,往往经济实力即GDP居中的省份较多,所有第三、四类省份的数量应该多于第一、二类和第五、六类。

        就聚类效果而言,从折线图5来看,每一类的折线都较为平缓,而不同类之间又有明显的差距,说明聚类效果较好。

        结合实际分析结果,第一类包含广东和江苏,这两个都是中国唯二GDP破10万亿元的省份且两省之间GDP差距不大。第二类包括山东和浙江,这个省份都在7万亿元以上,两省之间GDP差距不大。第一类和第二类都是遥遥领先于中国其他省份,在聚类结果中显示出“断档”的效果,而实际广东、江苏、山东和浙江也是中国发展最强劲的省份。第三类是中国发展较快的省市,包含了人口大省河南、河北和部分沿海沿江省份。第四类是中国发展较平稳的省市,包含了辽宁和中国中部的广大省份。第五类和第六类是包含了黑、吉和新建、西藏等经济基础较差西部省份。此聚类结果符合当前中国的现实。

4.3 优化改进

        K-means的应用非常广泛,但也面临着一些令人困扰的问题。例如,需要手动确定聚类数、对初始聚类中心敏感、易受噪声和异常值影响等。针对K-means 算法的各种缺点和在实际应用中的问题,优化方向主要包括以下几个方面:

(1)自适应聚类数:为了解决手动确定聚类数的问题,可以通过考虑模型复杂度和聚类效果等因素,在K-means算法中引入自适应聚类数的思想。可以利用无监督评估模型性能指标、信息熵或者贪心搜索方法等技术来探究最优聚类数。

(2)初始点策略优化:针对K-means算法对初始聚类中心选择的敏感性,可以采取一系列初始化策略来提高算法的稳健性与鲁棒性。例如,K-Means++ 等开创性算法,它们在挖掘聚类簇时,能够保证结果的高准确率,同时具有较高的鲁棒性;

(3)非欧几里得距离下的拓展:作为基于欧氏距离的聚类算法,K-means难以处理非欧几里得空间上的数据,如文本数据、图片视频、互联网阵地及压缩的视频解码、时间序列、蛋白质序列等。将K-means通用化是支持各向异性数据类型的手段之一,如 Kernel K-means 聚类算法是一种灵活的、广义化的欧氏K-means变量。

(4)非凸聚类簇的挖掘:K-means 假设每个样本点只能属于唯一的簇,并且这些聚类簇都是凸性结构。而在实际中,数据往往具有更加复杂的几何形态,如双月牙型、环形结构甚至是高斯混合分布模型。因此,未来研究还需要聚焦非凸性聚类簇的挖掘方法和技术。

5 附录

5.1 详细数据

表4 GDP数据和聚类结果

序号 省份 2021年GDP(亿元) 2022年GDP (亿元) 2023年第一季度GDP (亿元) 聚类结果 1 广东 124369 129119 30178.2 3 2 江苏 116364 122876 29401.7 3 3 山东 83095 87435 20411 1 4 浙江 73516 77715 18925 1 5 河南 58887 61345.1 14969 4 6 四川 53850 56749.8 13374.7 4 7 湖北 50012 53734.9 11899.7 4 8 福建 48810 53109.9 12061.9 4 9 湖南 46063 48670.4 11659.8 4 10 安徽 42959 45045 10936.2 4 11 河北 40391 42370.4 10041.4 4 12 陕西 29800 32772.7 7651.9 6 13 江西 29619 32074.7 7320.7 6 14 辽宁 27584 28975.1 6661.4 6 15 云南 27146 28954.2 6852.16 6 16 广西 24740 26300.9 6250.83 6 17 山西 22590 25642.6 5824.33 6 18 内蒙古 20514 23159 5344 6 19 贵州 19586 20164.6 4939.77 2 20 新疆 16000 17741.3 4149.52 2 21 黑龙江 14879 15901 3104.4 2 22 吉林 13235 13070.2 2833.88 2 23 甘肃 10243 11201.6 2670.7 2 24 海南 6475 6818.22 1775.96 5 25 宁夏 4522 5069.57 1206.76 5 26 青海 3346 3610.1 888.93 5 27 西藏 2000 2134.62 575.87 5

表5 平均轮廓系数表(完整)

K 轮廓系数 K 轮廓系数 K 轮廓系数 1 NaN 10 0.594314 19 0.729542 2 0.668228 11 0.500661 20 0.76321 3 0.637439 12 0.5177 21 0.801589 4 0.546112 13 0.608237 22 0.850406 5 0.437111 14 0.624953 23 0.909831 6 0.591982 15 0.569917 24 0.901283 7 0.545203 16 0.628832 25 0.97668 8 0.596923 17 0.626908 26 0.985676 9 0.570099 18 0.653269 27 1

5.2 完整数据

5.2.1 求平均轮廓系数

% 首先,生成一个随机的数据集

clc;clear;

%data = readmatrix('E:\日常\gdp.xlsx');

X = [124369 129119 30178.2

116364 122876 29401.7

83095 87435 20411

73516 77715 18925

58887 61345.1 14969

53850 56749.8 13374.7

50012 53734.9 11899.7

48810 53109.9 12061.9

46063 48670.4 11659.8

42959 45045 10936.2

40391 42370.4 10041.4

29800 32772.7 7651.9

29619 32074.7 7320.7

27584 28975.1 6661.4

27146 28954.2 6852.16

24740 26300.9 6250.83

22590 25642.6 5824.33

20514 23159 5344

19586 20164.6 4939.77

16000 17741.3 4149.52

14879 15901 3104.4

13235 13070.2 2833.88

10243 11201.6 2670.7

6475 6818.22 1775.96

4522 5069.57 1206.76

3346 3610.1 888.93

2000 2134.62 575.87

];

x=X;

[m,n]=size(x);

lunkuo=ones(1,m);

julei=ones(m);

for k=1: m

% 调用kmeans函数进行聚类分析

% 这里我分别计算了k从1-27的值,是为了得出所有的聚类结果和轮廓系数

% 当然,最后我进行根据最优k值进行选择我要的数据

[idx, centers] = kmeans(x, k);

% s为轮廓系数

s = silhouette(x,idx,'Euclidean');

mean_s = mean(s);

lunkuo(1,k)=mean_s;

%每一列对应一个聚类簇

julei(:,k)=idx;

end

5.2.2 肘部法求SSE

% 加载数据

clc;clear;

%data = readmatrix('E:\日常\gdp.xlsx');

data=[124369 129119 30178.2

116364 122876 29401.7

83095 87435 20411

73516 77715 18925

58887 61345.1 14969

53850 56749.8 13374.7

50012 53734.9 11899.7

48810 53109.9 12061.9

46063 48670.4 11659.8

42959 45045 10936.2

40391 42370.4 10041.4

29800 32772.7 7651.9

29619 32074.7 7320.7

27584 28975.1 6661.4

27146 28954.2 6852.16

24740 26300.9 6250.83

22590 25642.6 5824.33

20514 23159 5344

19586 20164.6 4939.77

16000 17741.3 4149.52

14879 15901 3104.4

13235 13070.2 2833.88

10243 11201.6 2670.7

6475 6818.22 1775.96

4522 5069.57 1206.76

3346 3610.1 888.93

2000 2134.62 575.87

];

% 簇数取值范围(仅取前10个)

K = 10;

% SSE向量初始化

SSE = zeros(K,1);

for k = 1:K

% 对数据进行k-means聚类,并计算误差平方和

[~,~,sumd] = kmeans(data,k,'Replicates',5);

SSE(k) = sum(sumd);

end

% 绘制SSE与簇数k的变化曲线

plot(1:K,SSE,'o-');

xlabel('聚类数(k)');

ylabel('误差平方和(SSE)');

% 设置标题,轴标签等

grid on;

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: