无监督学习——K-means算法

本文深入探讨了无监督学习中的K-means算法,包括算法流程、目标函数、随机初始化及聚类数K的选择,旨在帮助读者理解并掌握K-means算法的核心原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、前言

聚类算法是一种无监督学习算法。k均值算法是其中应用最为广泛的一种,算法接受一个未标记的数据集,然后将数据聚类成不同的组。

2、算法简述

K均值是一个迭代算法,假设我们想要将数据聚类成K个组,其方法为:

  1. 随机选择K个随机的点(称为聚类中心);
  2. 对与数据集中的每个数据点,按照距离K个中心点的距离,将其与距离最近的中心点关联起来,与同一中心点关联的所有点聚成一类;
  3. 计算每一组的均值,将该组所关联的中心点移动到平均值的位置;
  4. 重复执行2-3步,直至中心点不再变化
  • 简单Demo说明
    在这里插入图片描述

3、K-means算法思考

3.1、K-means算法

无标签训练集,其中每个输入是都是一个n维的实数向量,即假设分别表示K个类别的聚类中心,用来存储与第i个实例数据最近的聚类中心的索引(1,2,…,k),则K-均值算法的伪代码如下:
在这里插入图片描述
算法分为2个步骤,
第一个for循环是赋值步骤,即:对于每一个样例i,计算其应该属于的类。
第二个for循环是聚类中心的移动,即:对于每一个类k,重新计算该类的质心。(注:算法执行过程中若出现没有分配点的聚类中心,可以直接移除该聚类中心)

3.2、目标函数

K均值最小化的问题,是要最小化所有数据点与其所关联的聚类中心点之间的距离之和。
因此k均值的代价函数为:
在这里插入图片描述
在这里插入图片描述

3.3、随机初始化

K均值算法执行开始时,通常随机初始化聚类中心点,即:随机选择K个训练实例,然后令K个聚类中心分别等于这K个训练实例。
这就使得Kmeans算法存在一个缺陷:最后结果会依赖于初始化的情况,并且有可能使得代价函数停留在局部最小值处。
为了解决该问题,我们通常需要多次(50到1000次)运行K均值算法,每一次都重新进行初始化,最后再比较多次运行K-均值的结果,选择代价函数最小的结果。
通常这种方法在K较小的时候(2-10)还是可行的;但是K较大,这么做可能不会有明显的改善,并且K较大时,通常第一次执行K均值也会得到一个不错的结果。
典型的执行次数为100次。伪代码如下:
在这里插入图片描述

3.4、选择聚类数K

没有所谓最好的选择聚类数的方法,通常是需要根据不同的问题,人工的进行选择。
但是,当你想要确定最优聚类数K时,有一个值得一试的方法 - “肘部法则(Elbow method)”。
该方法所做的就是不断的改变K值(from 1 to x),执行k-均值,然后画出代价函数与K值的变化曲线,选择“肘点处”的值作为K的取值。
如下图:
在这里插入图片描述
事实上,该方法并不常用,因为大多数情况下,我们通常会得到一个光滑下降的曲线,没有一个清晰的“肘点”,这样就不能果断的确定K的取值;即便若此,该方法还是值得推荐和尝试的。

### K-means 聚类算法在 MATLAB 中的实现 K-means 是一种常用的无监督学习方法,用于将数据集划分为若干个簇。该算法通过迭代优化过程最小化各簇内样本之间的距离平方和。 #### 初始化参数 首先定义输入矩阵 `X` 的结构,其中每一行代表一个观测点,每列对应不同的特征维度[^2]。 ```matlab % 设置随机种子以获得可重复结果 rng(1); % 假设我们有如下二维数据集作为例子 dataSet = [randn(100, 2)+ones(100, 2); randn(100, 2)-ones(100, 2)]; ``` #### 定义辅助函数 创建两个帮助函数分别用来分配最近质心以及更新新的质心位置: ```matlab function idx = findClosestCentroids(X, centroids) % 计算每个点到各个质心的距离并返回最短的那个索引 [~, idx] = min(sum(bsxfun(@minus, X, centroids).^2, 2)); end function centroids = computeCentroids(X, idx, K) n = size(X, 2); centroids = zeros(K, n); for i = 1:K centroids(i,:) = mean(X(idx==i,:), 1); end % 处理可能存在空簇的情况 emptyClusters = sum(isnan(centroids), 2) > 0; while any(emptyClusters) newIdx = randsample(numel(X), nnz(emptyClusters)); centroids(emptyClusters, :) = X(newIdx, :); emptyClusters = sum(isnan(centroids), 2) > 0; end end ``` #### 主程序逻辑 编写主脚本来执行完整的 k-means 流程: ```matlab function [finalCentroids, clusterIndices] = runKMeans(X, initialCentroids, maxIterations) m = size(X, 1); n = size(X, 2); K = size(initialCentroids, 1); centroids = initialCentroids; previousCentroids = centroids; for iter = 1:maxIterations fprintf('Iteration number %d/%d...\n', iter, maxIterations); % 分配给最近的质心 clusterIndices = findClosestCentroids(X, centroids); % 更新质心的位置 centroids = computeCentroids(X, clusterIndices, K); % 如果连续两次迭代中质心不再变化,则提前终止 if all(previousCentroids(:)==centroids(:)) break; else previousCentroids = centroids; end end finalCentroids = centroids; end ``` #### 可视化结果 最后利用散点图展示最终分类效果及对应的质心位置[^3]: ```matlab figure; scatter(dataSet(:, 1), dataSet(:, 2), [], clusterIndices, 'filled'); title('K-Means Clustering Results'); xlabel('Feature 1'); ylabel('Feature 2'); legend('Cluster Centers'); hold on; plot(finalCentroids(:, 1), finalCentroids(:, 2), 'kx', 'MarkerSize', 12, 'LineWidth', 3); hold off; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值