k-means聚类算法的MATLAB实现及可视化

K-means算法是一种无监督学习算法,主要用于数据聚类。其工作原理基于迭代优化,将数据点划分为K个集群,使得每个数据点都属于最近的集群,并且每个集群的中心(质心)是所有属于该集群的数据点的平均值。以下是K-means算法的基本工作步骤: 

  1. 初始化
    • 选择要将数据集分成的集群数量K。
    • 随机选择K个数据点作为初始质心(即集群中心)。这些质心可以是从样本中随机选取的,也可以根据先验知识或经验来选择。
  2. 分配数据点到集群
    • 对于数据集中的每个数据点,计算其与每个质心的距离(通常使用欧氏距离)。
    • 将每个数据点分配到距离其最近的质心所在的集群。
  3. 更新质心
    • 对于每个集群,计算属于该集群的所有数据点的平均值(坐标的均值)。
    • 将计算出的均值作为新的质心。
  4. 迭代
    • 重复步骤2和3,直到满足停止条件。停止条件可以包括质心不再显著变化(即新旧质心之间的差异很小),或者算法达到了预定的最大迭代次数。
  5. 输出
    • 输出最终的K个集群以及每个集群的质心。

K-means算法的目标是最小化每个数据点到其所属集群质心的平方距离之和,即最小化集群内的平方误差。由于初始质心是随机选择的,因此不同的初始质心可能会导致不同的聚类结果。为了获得更稳定和更好的聚类效果,有时会多次运行K-means算法,并选择最佳的聚类结果。

在K-means算法中,K值(即要形成的集群数量)的确定是一个重要但具有挑战性的问题,因为不同的K值可能会导致不同的聚类结果。没有一种通用的方法可以直接确定最佳的K值,但可以通过以下一些策略来帮助你选择和评估不同的K值:

  1. 肘部法则(Elbow Method)
    这种方法通过绘制不同K值对应的聚类内误差和(Sum of Squared Errors, SSE)或畸变(Distortion)的曲线来工作。随着K值的增加,SSE通常会减小,因为更多的集群意味着每个集群中的数据点更紧密。但是,当K值增加到一定程度时,SSE的减少会变得不那么显著,形成一个类似于“肘部”的转折点。这个转折点通常被认为是最佳的K值。

  2. 轮廓系数(Silhouette Analysis)
    轮廓系数是评估聚类效果的一种方法,它结合了凝聚度和分离度两种度量。对于每个数据点,轮廓系数计算其到同一集群内其他点的平均距离(凝聚度)与其到最近邻集群内点的平均距离(分离度)的比值。整个数据集的轮廓系数是所有数据点轮廓系数的平均值。较高的轮廓系数值通常表示较好的聚类效果。你可以通过绘制不同K值的轮廓系数来找到最佳的K值。

  3. 间隙统计量(Gap Statistic)
    间隙统计量是一种通过比较实际数据的聚类结果与随机数据(具有相同分布)的聚类结果来评估最佳K值的方法。当实际数据的聚类结果显著好于随机数据的聚类结果时,可以认为找到了一个合适的K值。

  4. 层次聚类(Hierarchical Clustering)
    你可以首先使用层次聚类来确定大致的集群数量,然后再使用K-means算法进行细化。层次聚类可以提供一个关于数据集中可能存在多少自然集群的直观感受。

  5. 基于业务或先验知识
    在某些情况下,你可能已经知道数据集中应该有多少个集群,这通常基于业务逻辑或先验知识。例如,你可能正在分析一个包含三个不同产品类别的数据集,因此自然会选择K=3。

  6. 稳定性方法
    通过多次运行K-means算法并评估结果的稳定性来确定K值。如果对于不同的初始条件,算法都能产生相似的聚类结果,那么可以认为这个K值是稳定的。

请注意,没有一种方法是绝对正确的,每种方法都有其优点和局限性。在实际应用中,你可能需要结合多种方法来确定最佳的K值。同时,还需要考虑算法的计算复杂度和数据的特性。

clear;clc;clf;
% 假设你有一个名为data的数据集,它是一个n×d的矩阵,其中n是数据点的数量,d是每个数据点的维度。  
% 你想将数据点划分为k个集群。  rng(1314);%固定随机数种子
% 生成一些随机数据作为示例  
data = rand(100, 3);  % 100个2维数据点  %绘图
figure(1);
scatter3(data(:,1),data(:,2),data(:,3),'filled');% 定义要测试的K值范围  
K_values = 1:9; % 例如,测试从1到9的K值  % 初始化一个用于存储SSE的数组  
SSE = zeros(size(K_values));  % 对每个K值运行K-means算法并计算SSE  
for i = 1:length(K_values)  k = K_values(i);  [C,idx] = mykmeans(data, k);  % 计算SSE  SSE(i) = sum(sum((data - C(idx,:)).^2,2));  
end  % 绘制肘部图  
figure(2);  
plot(K_values, SSE, 'bx-');  
xlabel('Number of clusters K');  
ylabel('Sum of squared errors (SSE)');  
title('Elbow Method For Optimal K');  
grid on;  % 找出“肘部”点,这里简单地通过观察图形来确定  
% 在实际应用中,可以使用更复杂的策略,比如计算SSE变化的百分比等  
dsse = abs(diff(SSE));
bestK = find(dsse < 1 , 1, 'first'); 
fprintf('Suggested number of clusters: %d\n', bestK);  
hold on;  
plot(bestK, SSE(bestK), 'ro', 'MarkerSize', 10, 'LineWidth', 2); % 在图上标出建议的K值点  
legend('SSE for each K', 'Suggested K');  
hold off;

在下图可以观察到,k<4时曲线下降迅速,k>4时曲线下降出现明显放缓,因此K取4: 

K-means算法是一种非常常见的聚类算法,用于将数据点划分为K个集群。在上述数据和K取4的条件下,以下是一个简单的K-means算法的MATLAB实现示例:

% 选择要划分的集群数量  
k = bestK;  % 运行k-means算法  
[centroids, idx] = mykmeans(data, k);  % 绘制结果  
colors = {'r','b','g','y'}; % 生成k种不同的HSV颜色 
figure;  
for i = 1:k  % 提取属于当前组别的数据点  new_data = data(idx == i, :);  % 绘制当前组别的数据点,使用不同的颜色和标记  scatter3(new_data(:,1), new_data(:,2), new_data(:,3),colors{i},'filled');hold on; 
end 
% scatter3(data(:,1),data(:,2),data(:,3),idx);  
h2 = plot3(centroids(:,1), centroids(:,2),centroids(:,3), 'kx', 'MarkerSize', 15, 'LineWidth', 3);  
legend('类别1','类别2','类别3','类别4','中心点');
hold off;function [centroids, idx] = mykmeans(data, k)  % 初始化  [n, ~] = size(data);  centroids = data(randperm(n, k), :);  % 随机选择k个数据点作为初始质心  prev_centroids = centroids;  max_iters = 100;  % 最大迭代次数  for iter = 1:max_iters  % 分配数据点到最近的质心  idx = zeros(n, 1);  for i = 1:n  distances = sum((data(i,:) - centroids).^2, 2);  [~, min_idx] = min(distances);  idx(i) = min_idx;  end  % 重新计算质心  for i = 1:k  points = data(idx == i, :);  if ~isempty(points)  centroids(i,:) = mean(points);  end  end  % 检查收敛  if all(centroids == prev_centroids)  break;  end  prev_centroids = centroids;  end  
end

初始三维散点图对比k-means聚类后的三维散点图如下: 

需要注意的是,K-means算法对于初始质心的选择非常敏感,并且可能陷入局部最小值。此外,它假设集群的形状是球形的,并且集群的大小和密度大致相同,这在处理复杂形状或大小差异较大的集群时可能不是最优的。因此,在实际应用中,可能需要根据数据的特性和需求来选择和调整算法参数,或者考虑使用其他更复杂的聚类算法。

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

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

相关文章

数据仓库元数据管理

数据仓库元数据管理是数据仓库中至关重要的一环&#xff0c;它涉及到对数据仓库中的元数据进行收集、存储、组织、查询、维护和安全管理等方面的工作。本文将介绍数据仓库元数据管理的定义、分类、应用、价值、管理方案、具体实施和挑战&#xff0c;以帮助读者更好地理解和应用…

STM32有什么高速接口吗?

STM32系列微控制器在高速接口方面也提供了一些强大的功能&#xff0c;虽然没有像Zynq那样的可编程逻辑部分&#xff0c;但有一些特性值得注意。我这里有一套嵌入式入门教程&#xff0c;不仅包含了详细的视频 讲解&#xff0c;项目实战。如果你渴望学习嵌入式&#xff0c;不妨点…

【数据结构与算法】用两个栈实现一个队列

题目 用两个栈&#xff0c;实现一个队列功能 add delete length 队列 用数组可以实现队列&#xff0c;数组和队列的区别是&#xff1a;队列是逻辑结构是一个抽象模型&#xff0c;简单地可以用数组、链表实现&#xff0c;所以数组和链表是一个物理结构&#xff0c;队列是一个逻…

【C语言笔记】strncpy()和strcpy()的异同点

文章目录 一&#xff0c;简介二&#xff0c;相同点&#xff1a;2.1 两者都用于将一个字符串复制到另一个字符串中。2.2 它们都以源字符串的结束符 \0 结尾。 三&#xff0c;不同点&#xff1a;3.1 指定复制的最大长度&#xff1a;3.2 处理目标缓冲区溢出的方式&#xff1a;3.3 …

Docker安装SQL Server 2022

官网&#xff1a;Docker&#xff1a;为 Linux 上的 SQL Server 安装容器 - SQL Server | Microsoft Learn 1. 拉取镜像 sudo docker pull mcr.microsoft.com/mssql/server:2022-latest 2. 运行docker容器 方式一&#xff1a;不挂载数据目录 docker run -e "ACCEPT_EUL…

python借助elasticsearch实现标签匹配计数

给定一组标签 [{“tag_id”: “1”, “value”: “西瓜”}, {“tag_id”: “1”, “value”: “苹果”}]&#xff0c;我想精准匹配到现有的标签库中存在的标签并记录匹配成功的数量。 标签id(tag_id)标签名(tag_name)标签值(tag_name )1水果西瓜1水果苹果1水果橙子2动物老虎 …

用python计算一个人的BMI

1 问题 一个人的身高是1.75m和体重是80.5kg&#xff0c;根据BMI公式&#xff08;体重除以身高的平方&#xff09;帮这个人计算他的BMI指数&#xff0c;并根据BMI指数&#xff1a;低于18.5是过轻&#xff0c;18.5-25是正常&#xff0c;25-28是过重&#xff0c;28-32是肥胖&#…

Go 单元测试基本介绍

文章目录 引入一、单元测试基本介绍1.1 什么是单元测试&#xff1f;1.2 如何写好单元测试1.3 单元测试的优点1.4 单元测试的设计原则 二、Go语言测试2.1 Go单元测试概要2.2 Go单元测试基本规范2.3 一个简单例子2.3.1 使用Goland 生成测试文件2.3.2 运行单元测试2.3.3 完善测试用…

easyexcel升级3.3.4失败的经历

原本想通过easyexcel从2.2.6升级到3.3.3解决一部分问题&#xff0c;结果之前的可以用的代码&#xff0c;却无端的出现bug 1 Sheet index (1) is out of range (0…0) 什么都没有改&#xff0c;就出了问题&#xff0c;那么问题肯定出现在easyexcel版本自身.使用模板填充的方式进…

conda新建环境报错An HTTP error occurred when trying to retrieve this URL.

conda新建环境报错如下 cat .condarc #将 .condarc文件中的内容删除&#xff0c;改成下面的内容 vi .condarc channels:- defaults show_channel_urls: true default_channels:- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main- https://mirrors.tuna.tsinghua.…

权限管理Ranger详解

文章目录 一、Ranger概述与安装1、Ranger概述1.1 Ranger介绍1.2 Ranger的目标1.3 Ranger支持的框架1.4 Ranger的架构1.5 Ranger的工作原理 2、Ranger安装2.1 创建系统用户和Kerberos主体2.2 数据库环境准备2.3 安装RangerAdmin2.4 启动RangerAdmin 二、Ranger简单使用1、安装 R…

Cesium之home键开关及相机位置设置

显隐控制 设置代码中的homeButton var TDT_IMG_C "https://{s}.tianditu.gov.cn/img_c/wmts?servicewmts&requestGetTile&version1.0.0" "&LAYERimg&tileMatrixSetc&TileMatrix{TileMatrix}&TileRow{TileRow}&TileCol{TileCol}…

【Java NIO】那NIO为什么速度快?

Java IO在工作中其实不常用到&#xff0c;更别提NIO了。但NIO却是高效操作I/O流的必备技能&#xff0c;如顶级开源项目Kafka、Netty、RocketMQ等都采用了NIO技术&#xff0c;NIO也是大多数面试官必考的体系知识。虽然骨头有点难啃&#xff0c;但还是要慢慢消耗知识、学以致用哈…

# RAG | Langchain # Langchain RAG:打造Markdown文件的结构化分割解决方案

【文章简介】 在信息技术的现代背景下&#xff0c;高效地处理和分析文本数据对于知识获取和决策支持至关重要。Markdown文件因其易读性和高效性&#xff0c;在文档编写和知识共享中占据了重要地位。然而&#xff0c;传统的文本处理方法往往忽视了Markdown的结构化特性&#xff…

KNIME 国际化支持投票

你的投票也许能让 KNIME 中文化快一点点。 i18n 是个很搞笑的单词&#xff0c;它是英文 internationalization 国际化的缩写。18 指的是首字母i和末字母n中间有18个字母。另外还有什么 K8s 也是一样&#xff0c;中间省去了8个字母 ... 真是懒的可以。指北君还想起一个类似的笑话…

数字革命的先锋:Web3对社会的影响

引言 在信息技术飞速发展的当下&#xff0c;Web3作为一个新兴的互联网模式&#xff0c;正在逐渐改变我们的生活方式、商业模式和社会结构。本文将深入探讨Web3的核心特点、它在各个领域中的应用以及对社会产生的深远影响。 1. Web3的核心特点 1.1 去中心化 Web3强调去中心化…

记【k8s】:访问 Prometheus UI界面:kubernetes-etcd (0/1 up) Error : out of bounds

记【k8s】&#xff1a;访问 Prometheus UI界面&#xff1a;kubernetes-etcd &#xff08;0/1 up&#xff09; Error &#xff1a; out of bounds 1、报错详情2、解决方法 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 出现 “out of bound…

Synchronized锁详解(全网最细)

目录 以下知识基于HotSpot虚拟机实现 1.前置知识 1.1 锁的作用 1.2 Java中常见的锁类型 1.3 锁的重入 2.使用场景 2.1 修饰实例方法 2.1.1 用法 2.1.2 原理 2.1.3 特点 2.2 修饰静态方法 2.2.1 用法 2.2.2 原理 2.3 修饰代码块 2.3.1 用法 3.原理 3.1 对象锁 …

Docker搭建Gazee

Gazee 是一个 Web 应用&#xff0c;专门用于阅读和管理数字漫画。它提供了一个用户友好的界面&#xff0c;让用户能够轻松地访问和阅读存储在本地或远程服务器上的漫画书籍。Gazee 支持多种漫画格式&#xff0c;并允许用户对漫画进行分类、标签管理和搜索。 实际应用场景 个人…

正则表达式笔记

目录 01正则的基本使用 02 正则的五大类的使用 03 正则边界的使用 04 正则量词的使用 05 正则表达式案例 06 字符串中关于正则的一些方法 01正则的基本使用 正则分类: 普通字符元字符 创建正则对象 1.new创建 var regnew RegExp(/正则规则/) 2.字面量创建 var reg/正则规…