机器学习(七) ----------聚类(K-means)

目录

1 核心思想

2 K-means算法

2.1 算法概述

2.2 算法步骤

2.3 数学原理

2.4 ‘肘’方法确定K值

2.4.1 原理

2.4.2 步骤

2.4.3 代码实现

2.5 聚类评估方法

2.5.1 SC轮廓系数(Silhouette Coefficient)

计算方法

解读

注意事项

2.5.2  Calinski-Harabasz指数

定义

计算公式

评估原理

优点

缺点

适用情况

2.6 优缺点

2.7 改进和扩展

2.8 代码实现


1 核心思想

聚类算法的核心思想是将数据集中的样本划分为若干个不相交的子集,即“簇”。每个簇可能对应于一些潜在的概念或类别。聚类算法的目标是让同一簇内的数据样本尽可能相似,而不同簇间的数据样本尽可能不相似。这种相似性通常基于数据样本之间的某种距离度量来定义,如欧氏距离、余弦相似度等。

聚类算法是无监督学习方法的一种,它不需要预先设定数据标签或类别信息,而是通过分析数据样本之间的内在规律和特征来自动划分数据类别。聚类算法的种类繁多,包括基于划分的聚类算法(如K-means)、基于层次的聚类算法、基于密度的聚类算法(如DBSCAN)、基于网格的聚类算法、基于模型的聚类算法等。(本处只介绍K-means算法)

2 K-means算法

2.1 算法概述

K-means算法是一种基于迭代的聚类算法,它试图将数据点划分为K个集群(或称为簇),使得每个数据点都属于离其最近的均值(即聚类中心或质心)所对应的集群。K-means算法的核心是更新质心和分配数据点到最近的质心。

2.2 算法步骤

  1. 初始化
    • 选择K个点作为初始质心。这可以是随机选择,或者通过一些启发式方法(如K-means++)来选择,以加速收敛和避免糟糕的局部最优解。
  2. 分配数据点到最近的质心
    • 对于数据集中的每个数据点,计算它与K个质心之间的距离(如欧氏距离)。
    • 将数据点分配给距离它最近的质心所对应的集群。
  3. 更新质心
    • 对于每个集群,计算其内部所有数据点的均值(即新的质心)。
    • 将每个集群的质心更新为该均值。
  4. 迭代优化
    • 重复步骤2和3,直到满足某个停止条件。常见的停止条件包括:
      • 质心的位置不再发生显著变化(即收敛)。
      • 达到预设的最大迭代次数。
      • 准则函数(如SSE)的变化小于某个阈值。

2.3 数学原理

  • 距离度量:通常使用欧氏距离来度量数据点与质心之间的距离。但在某些情况下,也可以使用其他距离度量,如曼哈顿距离、余弦相似度等。

  • 准则函数(SSE):K-means算法使用均方差(Sum of the Squared Errors, SSE)作为准则函数,也称为损失函数。SSE表示每个数据点到其所属集群的质心的距离的平方和。数学上,SSE可以表示为:

SSE = \sum_{i=1}^{K}\sum_{x\in C_i}\left \| x-u_i \right \|^2

其中,Ci​是第i个集群的数据点集合,μi​是第i个集群的质心,∣∣x−μi​∣∣是数据点x与质心μi​之间的距离。

  • 收敛性:虽然K-means算法不保证找到全局最优解(即SSE的最小值),但在某些条件下,它可以保证收敛到局部最优解。收敛性通常通过观察质心的变化或SSE的变化来判断。

2.4 ‘肘’方法确定K值

2.4.1 原理

“肘”方法(Elbow Method)是一种常用于确定K-means聚类算法中最佳聚类数(K值)的启发式方法。该方法基于SSE(Sum of the Squared Errors,误差平方和)与聚类数K之间的关系来确定最佳的K值。

2.4.2 步骤

以下是使用“肘”方法确定K值的步骤:

  1. 计算不同K值的SSE:首先,对于一系列不同的K值(例如从1开始逐渐增加),对给定的数据集进行K-means聚类,并计算每个K值对应的SSE。
  2. 绘制SSE图:将每个K值及其对应的SSE绘制在一张图表上。通常,横轴表示K值,纵轴表示对应的SSE。
  3. 寻找“肘点”:在SSE图上,观察SSE随K值变化的趋势。通常,随着K值的增加,SSE会逐渐减小,因为更多的聚类可以更好地拟合数据。但是,当K值增加到某个点后,SSE的减小速度会明显放缓,形成一个类似于“肘部”的弯曲点。这个点就是所谓的“肘点”。
  4. 选择肘点对应的K值:根据SSE图上的“肘点”,选择对应的K值作为最佳聚类数。这个K值通常表示在增加聚类数时,能够获得较大的聚类效果提升与计算成本之间的平衡。

需要注意的是,“肘”方法是一种启发式方法,其结果可能受到数据分布、噪声等因素的影响。因此,在实际应用中,可能需要结合其他方法(如轮廓系数、Calinski-Harabasz指数等)来综合评估聚类效果,并选择最佳的K值。

2.4.3 代码实现

在Python中,我们可以使用sklearn库的KMeans类来执行K-means聚类,并计算不同K值下的SSE(误差平方和),然后通过绘制图形来找到“肘点”。以下是一个简单的代码示例,用于实现这一过程:

import numpy as np  
import matplotlib.pyplot as plt  
from sklearn.cluster import KMeans  
from sklearn.datasets import make_blobs  # 生成模拟数据  
X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)  # 初始化一个空的列表来存储SSE值  
sse = []  # 遍历不同的K值  
for k in range(1, 11):  kmeans = KMeans(n_clusters=k, init='k-means++', max_iter=300, n_init=10, random_state=0)  kmeans.fit(X)  sse.append(kmeans.inertia_)  # inertia_ 是KMeans类的一个属性,它给出了每个点到其最近质心的距离的平方和  # 绘制SSE与K值的关系图  
plt.plot(range(1, 11), sse)  
plt.title('The Elbow Method showing the optimal k')  
plt.xlabel('Number of clusters')  
plt.ylabel('SSE')  
plt.show()  # 根据SSE图,找到“肘点”  
# 实际应用中,可能需要一些启发式规则或手动选择  
# 例如,可以通过检查SSE的减少率来找到“肘点”  
# 这里我们假设“肘点”是SSE开始平缓变化的点  
# 注意:这是一个简化的示例,实际中可能需要更复杂的逻辑来确定“肘点”

在这个例子中,我们使用make_blobs函数生成了一个模拟数据集,然后遍历了从1到10的不同K值,并计算了每个K值下的SSE。然后,我们使用matplotlib库绘制了SSE与K值的关系图。

要找到“肘点”,通常我们需要观察SSE的减少率。在图中,当K值较小时,SSE的减少幅度通常很大,因为增加聚类数能够显著改善聚类效果。然而,当K值增加到一定程度时,SSE的减少率会开始放缓,形成一个类似于“肘部”的弯曲点。这个“肘点”就是我们要找的K值。

在实际应用中,可能需要一些启发式规则或手动选择来确定“肘点”。例如,我们可以计算相邻K值之间SSE的减少率,并找到减少率开始明显放缓的点。然而,需要注意的是,“肘点”方法并不是一种严格的数学方法,其结果可能会受到数据分布、噪声等因素的影响。因此,在实际应用中,我们可能需要结合其他方法(如轮廓系数、Calinski-Harabasz指数等)来综合评估聚类效果,并选择最佳的K值。

2.5 聚类评估方法

2.5.1 SC轮廓系数(Silhouette Coefficient)

轮廓系数(Silhouette Coefficient)是一种用于评估聚类效果的指标,它结合了聚类的凝聚度和分离度两种因素。对于数据集中的每个样本,轮廓系数衡量了样本与其所属聚类内其他样本的相似度(凝聚度)以及样本与其他聚类中样本的不相似度(分离度)。

计算方法

轮廓系数是针对单个样本的,然后取所有样本的平均值得到整个数据集的轮廓系数。对于数据集中的第i个样本,其轮廓系数s(i)的计算步骤如下:

1. 计算样本i到同聚类其他样本的平均距离a(i):这代表了样本i所属聚类的凝聚度。a(i)越小,说明样本i越应该被聚类到该簇。

a\left ( i \right ) = \frac{1}{\left | C_i \right |-1}\sum_{j\in C_i,i\neq j}dist(i,j)

其中,C_i是样本i所属的聚类,|C_i|是该聚类的样本数,dist(i, j)是样本ij之间的距离。

2.计算样本i到所有其他聚类中的样本的平均距离的最小值b(i):这代表了样本i与其他聚类的分离度。b(i)越大,说明样本i越不属于其他聚类。

b(i) = min\left ( \frac{1}{\left | C_k \right |}\sum_{j\in C_k}^{}dist(i,j)\right )

其中,C_k是除了C_i以外的其他聚类。

3.计算样本i的轮廓系数s(i)

s(i)=\frac{b(i)-a(i)}{max\left \{ a(i),b{i} \right \}}

轮廓系数的值域是[-1, 1]。值越接近1表示聚类效果越好,样本i越应该被聚类到当前聚类;值越接近-1表示聚类效果越差,样本i更可能被聚类到错误的聚类中;值接近0则表示样本i在两个聚类的边界上。

4.计算整个数据集的轮廓系数:取所有样本轮廓系数的平均值。

解读
  • 如果一个聚类中的大多数样本的轮廓系数都比较高,则整个聚类的质量是好的。
  • 如果一个聚类的轮廓系数较低,则可能是由于聚类过大或聚类中包含了一些与其他聚类距离较近的样本。
  • 如果一个样本的轮廓系数较低,则可能是因为它被错误地分配到了某个聚类中。
注意事项
  • 轮廓系数对于凸形聚类(如K-means聚类产生的聚类)的效果评估通常比较好,但对于非凸形聚类(如基于密度的聚类产生的聚类)可能不太准确。
  • 轮廓系数对样本数量的变化比较敏感,如果样本数量过少,可能会导致评估结果不准确。
  • 在计算轮廓系数时,选择合适的距离度量方法(如欧氏距离、曼哈顿距离等)也是非常重要的。

2.5.2  Calinski-Harabasz指数

Calinski-Harabasz Index(Calinski-Harabasz指数)是聚类分析中的一种评估指标,主要用于评估聚类效果的好坏。以下是关于Calinski-Harabasz Index的详细介绍:

定义

Calinski-Harabasz指数是基于簇内的协方差与簇间的协方差之间的比值进行计算的。该指标值越大,代表聚类效果越好。

计算公式

评估原理

Calinski-Harabasz指数通过计算聚类之间的离散度与聚类内部的紧密度之比来确定最佳的聚类数((m - k))/((k - 1))部分是一个修正系数,用于平衡聚类数量和样本数量对指标的影响。

当簇的密集且分离较好时,Calinski-Harabasz指数的值会更高。这意味着簇内部的数据点紧密聚集,而簇与簇之间有明显的分离。因此,Calinski-Harabasz指数越大,表示聚类效果越好。

优点
  • 计算速度快:与轮廓系数等其他聚类评估指标相比,Calinski-Harabasz指数的计算速度更快,尤其适用于大型数据集。
  • 评估效果直观:Calinski-Harabasz指数的值直接反映了聚类效果的好坏,方便用户根据指标值进行优化。
缺点
  • 对噪声和异常值敏感:由于Calinski-Harabasz指数是基于协方差矩阵进行计算的,因此它对噪声和异常值比较敏感。在存在噪声或异常值的情况下,指标值可能会受到较大影响。
  • 适用于具有清晰、凸形状的聚类结构:Calinski-Harabasz指数在处理具有清晰、凸形状的聚类结构时表现较好。然而,对于非凸形状的聚类结构,该指标可能会出现偏差。
适用情况

Calinski-Harabasz指数适用于各种类型的数据集,尤其是数据分布相对均匀且没有明显的几何形状的聚类结构。然而,在处理具有非凸形状的聚类结构或存在噪声和异常值的数据集时,可能需要结合其他聚类评估指标进行综合评估。

2.6 优缺点

  • 优点
    • 原理简单,易于实现和解释。
    • 处理大数据集时,通常比层次聚类等算法更高效。
    • 当结果集群是密集的、球状或团状的,且集群之间区别明显时,效果较好。
  • 缺点
    • 需要预先指定集群的个数K,这通常是一个难题。
    • 对初始质心的选择敏感,不同的初始质心可能导致完全不同的聚类结果。
    • 对噪声和异常值敏感,因为它们可能影响质心的计算和集群的分配。
    • 只适用于凸数据集,对于非凸数据集可能无法得到理想的聚类效果。

2.7 改进和扩展

  • K-means++:一种改进的初始化方法,旨在选择更好的初始质心,从而加速收敛和避免糟糕的局部最优解。
  • Mini Batch K-means:一种适用于大数据集的K-means算法的变体,它使用数据集的子集(即mini batch)来更新质心,从而在不牺牲太多精度的情况下提高计算效率。
  • 模糊C-means(FCM):一种软聚类方法,它允许数据点以不同的隶属度属于多个集群,从而能够处理更复杂的数据结构和不确定性。
  • 谱聚类:一种基于图论的聚类方法,它首先将数据点视为图中的节点,然后构建节点之间的相似度矩阵(或称为邻接矩阵),最后使用图论中的谱分析方法来划分集群。谱聚类通常能够处理非凸数据集和具有复杂结构的数据集。

2.8 代码实现

import numpy as np  
import matplotlib.pyplot as plt  
from sklearn.cluster import KMeans  
from sklearn.datasets import make_blobs  # 创建一个包含不同数量簇的模拟数据集  
X, y_true = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)  # 定义畸变程度(Distortion)的计算函数  
def calculate_distortion(X, k):  kmeans = KMeans(n_clusters=k, random_state=0).fit(X)  return kmeans.inertia_  # 初始化一个列表,用于存储不同K值对应的畸变程度  
distortions = []  
for i in range(1, 11):  K = i  distortions.append(calculate_distortion(X, K))  # 绘制K值与畸变程度的曲线  
plt.plot(range(1, 11), distortions, marker='o')  
plt.xlabel('Number of clusters')  
plt.ylabel('Distortion')  
plt.title('The Elbow Method showing the optimal k')  
plt.show()  # 根据肘部方法选择最佳的K值(这里可以手动从图中观察)  
# 也可以编写一个自动化方法来选择K值,例如通过计算畸变程度的二阶导数或者变化率来选择  
# 自动化选择K值的示例(这里使用简单的斜率变化来模拟)  
# ... (这部分代码需要根据你的需求来实现)  # 假设我们从图中观察到K=4时有一个明显的肘部,因此选择K=4  
best_k = 4  
kmeans = KMeans(n_clusters=best_k, random_state=0).fit(X)  
labels = kmeans.predict(X)  # 绘制聚类结果  
plt.scatter(X[:, 0], X[:, 1], c=labels, s=50, cmap='viridis')  
centers = kmeans.cluster_centers_  
plt.scatter(centers[:, 0], centers[:, 1], c='black', s=200, alpha=0.5);  
plt.show()

在这个例子中,我们首先生成了一个模拟数据集,然后使用了一个函数来计算不同K值对应的畸变程度。接着,我们绘制了K值与畸变程度的曲线图,并手动从图中选择了最佳的K值。最后,我们使用选定的K值来执行K-means聚类,并绘制了聚类结果。

注意:在实际应用中,肘部可能并不总是那么明显,特别是在数据集非常复杂或者噪声很大的情况下。因此,你可能需要结合其他方法或者领域知识来确定最佳的K值。

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

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

相关文章

刷代码随想录有感(77):回溯算法——含有重复元素的全排列

题干&#xff1a; 代码&#xff1a; class Solution { public:vector<int> tmp;vector<vector<int>> res;void backtracking(vector<int> nums, vector<int> used){if(tmp.size() nums.size()){res.push_back(tmp);return;}sort(nums.begin(),…

对安卓手机上损坏的 SD 卡进行故障排除:恢复提示和修复

概括 如果您总是在旅途中&#xff0c;那么您很可能每天都在使用 SD 卡。这些微小但功能强大的闪存已经变得和手机的内部存储一样有用。它们可以存储数据并移动您想要的任何数据类型&#xff0c;因为它们在 Android 设备上添加了额外的存储空间。不幸的是&#xff0c;他们可能会…

四天学会JS高阶(学好vue的关键)——深入面向对象(理论+实战)(第三天)

***本章面试使用居多* 理论篇**一、编程思想 1.1 面向过程 JS 前端居多 按照步骤 性能高 适合跟硬件关系很紧密 没有面向对象易维护易复用易扩展 1.2 面向对象 java典型 按照功能&#xff0c;把事务分别成一个个对象&#xff0c;对象之间分工合作 比较灵活 适合多人合作的…

python绘制多级饼图(分层饼图)

python绘制多级饼图&#xff08;分层饼图&#xff09; 介绍效果代码 介绍 多级饼图展示了数据的层次结构&#xff0c;其中每个级别表示数据的一个层次。我们可以使用matplotlib绘制多级饼图。 效果 代码 import matplotlib.pyplot as plt# 示例数据 outer_labels [Category…

css卡片横线100%宽度

所需样式: 横线不用border, 用单独一个div, 这样就不会影响父组件的padding <div class"pumpDetailView"><div class"pump_title_name"><span>{{ pumpInfo.pointname }}</span><divclass"point_state":style"…

html 字体设置 (web端字体设置)

windows自带的字体是有版权的&#xff0c;包括微软雅黑&#xff08;方正&#xff09;、宋体&#xff08;中易&#xff09;、黑体&#xff08;中易&#xff09;等 版权算是个大坑&#xff0c;所谓为了避免版权问题&#xff0c;全部使用开源字体即可 我这里选择的是思源宋体&…

nodejs 与 npm 版本对应关系

官方地址&#xff1a;https://nodejs.org/en/about/previous-releases

C++容器之无序多集(std::unordered_multiset)

目录 1 概述2 使用实例3 接口使用3.1 construct3.2 assigns3.3 iterators3.4 capacity3.5 find3.6 count3.7 equal_range3.8 emplace3.9 emplace_hint3.10 insert3.11 erase3.12 clear3.13 swap3.14 bucket_count3.15 max_bucket_count3.16 bucket_size3.17 bucket3.18 load_fa…

全栈式数据统计:SqlAlchemy怎样连接MsSql Server获取视图列表

1.源代码 #-----------获取数据库视图列表----------------------------- # -------密码含特殊字符使用 from urllib.parse import quote_plus as urlquotefrom sqlalchemy import create_engine, MetaData, inspect# 替换为你的数据库连接字符串 DRIVER "ODBC Driver 1…

【新】snapd申请Let‘s Encrypt免费SSL证书、自动化续签证书

简介 之前写过一篇certbot申请SSL证书的文章&#xff1a;SSL证书申请&#xff0c;写得比较详细&#xff0c;但是最近发现使用snapd会更方便。 使用机器&#xff1a;Ubuntu 20.04 简单步骤 1、首先安装必要软件 sudo apt install snapd sudo apt install certbot sudo apt …

可视化在医疗健康领域的巨大价值,该如何设计呢。

可视化设计在医疗健康领域具有以下价值&#xff1a; 数据展示与分析&#xff1a;可视化设计可以将医疗健康领域的大量数据以图表、图形等形式进行展示和分析&#xff0c;帮助医生、研究人员和决策者更直观地理解和解读数据&#xff0c;发现规律和趋势&#xff0c;从而做出科学决…

C++高效死锁检测——实现原理与应用(基于强连通分量)

背景 在项目使用多进程、多线程过程中&#xff0c;因争夺资源而造成一种资源竞态&#xff0c;所以需加锁处理。如下图所示&#xff0c;线程 A 想获取线程 B 的锁&#xff0c;线程 B 想获取线程 C 的锁&#xff0c;线程 C 想获取线程 D 的锁&#xff0c; 线程 D 想获取线程 A 的…

回溯大法总结

前言 本篇博客将分两步来进行&#xff0c;首先谈谈我对回溯法的理解&#xff0c;然后通过若干道题来进行讲解&#xff0c;最后总结 对回溯法的理解 回溯法可以看做蛮力法的升级版&#xff0c;它在解决问题时的每一步都尝试所有可能的选项&#xff0c;最终找出所以可行的方案…

【Git】版本控制工具——Git介绍及使用

目录 版本控制版本控制系统的主要目标分类小结 分布式版本控制系统——GitGit特点Git与SVN的区别Git的工作机制 Git安装Git 团队协作机制团队内协作跨团队协作远程仓库远程仓库的作用有以下几个方面远程仓库操作流程/团队协作流程 Git分支什么是分支分支的好处 Git的常用命令Gi…

【热门话题】CentOS 常见命令指南

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 CentOS 常见命令指南一、文件与目录操作1. 切换目录2. 查看当前目录3. 列出目录…

SVM影像组学特征

近期做一个影像组学的分类模型 做的是一个胃癌T分期的模型&#xff0c;我刷选统计出一些胃癌区域的特征&#xff0c;如图&#xff1a;有癌症面积、体积等等 下面要做一个SVM&#xff08;支持向量机&#xff09;分类的模型&#xff0c;导入该文件&#xff0c;进行二分类&#x…

MFC密码对话框之间数据传送实例(源码下载)

新建一个login工程项目对话框&#xff0c;主对话框IDD_LOGIN_DIALOG中一个显示按钮IDC_BUTTON1、一个密码按钮IDC_BUTTON2。添加一个密码对话框IDD_DIALOG1&#xff0c;添加类password&#xff0c;在对话框中添加一个编辑框IDC_EDIT1、一个确定按钮IDC_BUTTON1。 程序功能&…

百度集团:AI重构,走到哪了?

内有自家公关一号“自曝”狼性文化&#xff0c;主动制造舆论危机。 外有&#xff0c;OpenAI、谷歌、字节、华为等大模型劲敌扎堆迭代新产品&#xff0c; 强敌环伺。 今天我们要说的是早就从BAT掉队的——百度。 最近&#xff0c;在武汉Aapollo Day 2024上&#xff0c;百度发布了…

抖音小店新规重磅来袭!事关店铺流量!商家的福音来了?

大家好&#xff0c;我是喷火龙。 就在前两天&#xff0c;抖店发布了新规&#xff0c;我给大家总结了一下&#xff0c;无非就是两点。 第一点&#xff1a;保证金下调&#xff0c;一证开多店。 第二点&#xff1a;新品上架破10单&#xff0c;有流量扶持。 咱来细细的解读&…

零基础HTML教程(34)--HTML综合实例

文章目录 1. 背景2. 开发流程2.1 网站功能设计2.2 建立网站目录结构2.3 开发首页2.2 生平简介页2.3 经典诗词页2.4 苏轼图集页2.5 留言板 3. 小结 1. 背景 通过前面33篇文章的学习&#xff0c;我们对HTML有了一个比较全面的了解。 本篇&#xff0c;我们编写一个网站实例&…