Kmeans算法的K值选择技巧【Elbow Method + Silhouette Score Method】

2023-10-29 04:12

本文主要是介绍Kmeans算法的K值选择技巧【Elbow Method + Silhouette Score Method】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、方法简述
  • 二、使用到的数据集
  • 三、代码实现
  • 四、结论


一、方法简述

在Kmeans算法中最终聚类数量K的选择主要通过两个方法综合判断:

  1. Elbow Method
    这是一种绘制k值范围的平方和的方法。如果此图看起来像一只手臂,则k是选择的类似肘部的值。从这个肘值开始,平方和(惯性)开始以线性方式减小,因此被认为是最佳值。
    在这里插入图片描述
    上图的最佳K值为3

  2. Silhouette Score Method
    这是一种根据数据点与彼此相似的其他数据点的聚类程度来评估聚类质量的方法。使用距离公式计算该分数,并且选择具有最高分数的k值用于建模。
    具体来说,Silhouette Score 是一种衡量聚类结果质量的指标,它结合了聚类内部的紧密度和不同簇之间的分离度。对于每个数据点,Silhouette Score 考虑了以下几个因素:
      1.紧密度:数据点到同簇其他点的平均距离
      2.分离度:数据点到最近不同簇的平均距离
    设紧密度为a,分离度为b,Silhouette Score 计算公式为 ( b − a ) / m a x ( a , b ) (b - a) / max(a, b) (ba)/max(a,b)。该值的范围在 -1 到 1 之间,越接近 1 表示数据点聚类得越好,越接近 -1 则表示聚类结果较差。
    在这里插入图片描述
    上图的最佳值为2,3,4

综合两种方法进行判断后,K值选3较为合适


二、使用到的数据集

  • 用到的数据集:
    各国发展水平统计信息↓
    https://download.csdn.net/download/weixin_43721000/88480791
  • 字段解释:
    country : 国名
    child_mort : 每1000个婴儿的5年死亡率
    exports : 人均商品和服务出口,以人均国内生产总值的百分比给出
    health : 人均卫生支出总额,以人均国内生产总值的百分比给出
    imports : 人均商品和服务进口,以人均国内生产总值的百分比给出
    Income : 人均净收入
    Inflation : 国内生产总值年增长率的测算(通货膨胀率)
    life_expec : 如果按照目前的死亡率模式,新生儿的平均寿命是多少年
    total_fer : 如果目前的年龄生育率保持不变,每个妇女生育的孩子数量
    gdpp : 人均国内生产总值,计算方法是国内生产总值除以总人口
  • 任务类型:
    对所有国家发展水平聚类,确定待援助国家,涵盖算法:K-Means、DBSCAN、Hierarchical

三、代码实现

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
pd.options.display.float_format = '{:.2f}'.format
import warnings
warnings.filterwarnings('ignore')from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from sklearn.preprocessing import MinMaxScaler, StandardScalerdef show_elbow_and_silhouette_score(data_values):'''1.计算Elbow Method2.计算Silhouette Score Method3.绘图:return:'''sse = {}sil = []kmax = 10fig = plt.subplots(nrows=1, ncols=2, figsize=(20, 5))# Elbow Method :plt.subplot(1, 2, 1)for k in range(1, 10):kmeans = KMeans(n_clusters=k, max_iter=1000).fit(data_values)sse[k] = kmeans.inertia_  # Inertia: Sum of distances of samples to their closest cluster centersns.lineplot(x=list(sse.keys()), y=list(sse.values()))plt.title('Elbow Method')plt.xlabel("k : Number of cluster")plt.ylabel("Sum of Squared Error")plt.grid()# Silhouette Score Methodplt.subplot(1, 2, 2)for k in range(2, kmax + 1):kmeans = KMeans(n_clusters=k).fit(data_values)labels = kmeans.labels_sil.append(silhouette_score(data_values, labels, metric='euclidean'))sns.lineplot(x=range(2, kmax + 1), y=sil)plt.title('Silhouette Score Method')plt.xlabel("k : Number of cluster")plt.ylabel("Silhouette Score")plt.grid()plt.show()if __name__ == '__main__':# 读取数据data = pd.read_csv('./data/Country-data.csv')print(data.head())#                country  child_mort  exports  ...  life_expec  total_fer   gdpp# 0          Afghanistan       90.20    10.00  ...       56.20       5.82    553# 1              Albania       16.60    28.00  ...       76.30       1.65   4090# 2              Algeria       27.30    38.40  ...       76.50       2.89   4460# 3               Angola      119.00    62.30  ...       60.10       6.16   3530# 4  Antigua and Barbuda       10.30    45.50  ...       76.80       2.13  12200# 数据降维# 将较为细分的领域数据合并# health <== child_mort, health, life_expec, total_fer# trade <== imports, exports# finance <== income, inflation, gdpp# 最终由9个维度降至3维df = pd.DataFrame()df['Health'] = (data['child_mort'] / data['child_mort'].mean()) + (data['health'] / data['health'].mean()) + (data['life_expec'] / data['life_expec'].mean()) + (data['total_fer'] / data['total_fer'].mean())df['Trade'] = (data['imports'] / data['imports'].mean()) + (data['exports'] / data['exports'].mean())df['Finance'] = (data['income'] / data['income'].mean()) + (data['inflation'] / data['inflation'].mean()) + (data['gdpp'] / data['gdpp'].mean())print(df.head())#    Health  Trade  Finance# 0    6.24   1.20     1.35# 1    3.04   1.72     1.47# 2    3.39   1.60     3.17# 3    6.47   2.43     3.49# 4    2.96   2.36     2.24# 数据归一化mms = MinMaxScaler()  # Normalization# ss = StandardScaler()  # Standardizationdf['Health'] = mms.fit_transform(df[['Health']])df['Trade'] = mms.fit_transform(df[['Trade']])df['Finance'] = mms.fit_transform(df[['Finance']])df.insert(loc=0, value=list(data['country']), column='Country')print(df.head())#                Country  Health  Trade  Finance# 0          Afghanistan    0.63   0.14     0.08# 1              Albania    0.13   0.20     0.09# 2              Algeria    0.18   0.19     0.21# 3               Angola    0.66   0.28     0.24# 4  Antigua and Barbuda    0.12   0.28     0.15# 取出归一化之后的各项特征张量data_values = df.drop(columns=['Country']).values  # Feature Combination : Health - Trade - Financeprint(data_values)# [[0.6257404  0.13961443 0.07981958]#  [0.12745148 0.19990106 0.08875623]#  [0.18248518 0.18662177 0.2128085 ]#  [0.66138147 0.28305774 0.23694587]#      ...       ...        ...#  [0.17006974 0.40338563 0.12143593]#  [0.39745068 0.17024776 0.22963179]#  [0.52690852 0.18140481 0.13499709]]# 聚类并绘制 elbow 和 silhouette_score 方法的图像show_elbow_and_silhouette_score(data_values)

在这里插入图片描述


四、结论

  1. Elbow Method 显示肘部位置 K=3
  2. Silhouette Score Method 显示的较高分数在 K=2,3 时表现较好
  3. 综合两个方法最终确认 K的选值为 3

这篇关于Kmeans算法的K值选择技巧【Elbow Method + Silhouette Score Method】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/298182

相关文章

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

Pandas中多重索引技巧的实现

《Pandas中多重索引技巧的实现》Pandas中的多重索引功能强大,适用于处理多维数据,本文就来介绍一下多重索引技巧,具有一定的参考价值,感兴趣的可以了解一下... 目录1.多重索引概述2.多重索引的基本操作2.1 选择和切片多重索引2.2 交换层级与重设索引3.多重索引的高级操作3.1 多重索引的分组聚

Redis多种内存淘汰策略及配置技巧分享

《Redis多种内存淘汰策略及配置技巧分享》本文介绍了Redis内存满时的淘汰机制,包括内存淘汰机制的概念,Redis提供的8种淘汰策略(如noeviction、volatile-lru等)及其适用场... 目录前言一、什么是 Redis 的内存淘汰机制?二、Redis 内存淘汰策略1. pythonnoe

怎么关闭Ubuntu无人值守升级? Ubuntu禁止自动更新的技巧

《怎么关闭Ubuntu无人值守升级?Ubuntu禁止自动更新的技巧》UbuntuLinux系统禁止自动更新的时候,提示“无人值守升级在关机期间,请不要关闭计算机进程”,该怎么解决这个问题?详细请看... 本教程教你如何处理无人值守的升级,即 Ubuntu linux 的自动系统更新。来源:https://

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Python 中 requests 与 aiohttp 在实际项目中的选择策略详解

《Python中requests与aiohttp在实际项目中的选择策略详解》本文主要介绍了Python爬虫开发中常用的两个库requests和aiohttp的使用方法及其区别,通过实际项目案... 目录一、requests 库二、aiohttp 库三、requests 和 aiohttp 的比较四、requ

将Python应用部署到生产环境的小技巧分享

《将Python应用部署到生产环境的小技巧分享》文章主要讲述了在将Python应用程序部署到生产环境之前,需要进行的准备工作和最佳实践,包括心态调整、代码审查、测试覆盖率提升、配置文件优化、日志记录完... 目录部署前夜:从开发到生产的心理准备与检查清单环境搭建:打造稳固的应用运行平台自动化流水线:让部署像

el-select下拉选择缓存的实现

《el-select下拉选择缓存的实现》本文主要介绍了在使用el-select实现下拉选择缓存时遇到的问题及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录项目场景:问题描述解决方案:项目场景:从左侧列表中选取字段填入右侧下拉多选框,用户可以对右侧

Java 枚举的常用技巧汇总

《Java枚举的常用技巧汇总》在Java中,枚举类型是一种特殊的数据类型,允许定义一组固定的常量,默认情况下,toString方法返回枚举常量的名称,本文提供了一个完整的代码示例,展示了如何在Jav... 目录一、枚举的基本概念1. 什么是枚举?2. 基本枚举示例3. 枚举的优势二、枚举的高级用法1. 枚举

不删数据还能合并磁盘? 让电脑C盘D盘合并并保留数据的技巧

《不删数据还能合并磁盘?让电脑C盘D盘合并并保留数据的技巧》在Windows操作系统中,合并C盘和D盘是一个相对复杂的任务,尤其是当你不希望删除其中的数据时,幸运的是,有几种方法可以实现这一目标且在... 在电脑生产时,制造商常为C盘分配较小的磁盘空间,以确保软件在运行过程中不会出现磁盘空间不足的问题。但在