简单易学的机器学习算法——K-Means算法

本文介绍了一种无监督学习算法——聚类算法的基本概念,并详细解释了K-Means算法的工作原理及其具体实现步骤。包括算法流程、初始化过程、质心选择与更新等关键环节。

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

一、聚类算法的简介

    聚类算法是一种典型的无监督学习算法,主要用于将相似的样本自动归到一个类别中。聚类算法与分类算法最大的区别是:聚类算法是无监督的学习算法,而分类算法属于监督的学习算法。

    在聚类算法中根据样本之间的相似性,将样本划分到不同的类别中,对于不同的相似度计算方法,会得到不同的聚类结果,常用的相似度计算方法有欧式距离法。

二、K-Means算法的概述

   基本K-Means算法的思想很简单,事先确定常数K,常数K意味着最终的聚类类别数,首先随机选定初始点为质心,并通过计算每一个样本与质心之间的相似度(这里为欧式距离),将样本点归到最相似的类中,接着,重新计算每个类的质心(即为类中心),重复这样的过程,知道质心不再改变,最终就确定了每个样本所属的类别以及每个类的质心。由于每次都要计算所有的样本与每一个质心之间的相似度,故在大规模的数据集上,K-Means算法的收敛速度比较慢。

三、K-Means算法的流程

  • 初始化常数K,随机选取初始点为质心
  • 重复计算一下过程,直到质心不再改变
    • 计算样本与每个质心之间的相似度,将样本归类到最相似的类中
    • 重新计算质心
  • 输出最终的质心以及每个类

四、K-Means算法的实现

    对数据集进行测试

原始数据集
MATLAB代码
主程序
%% input the data
A = load('testSet.txt');

%% 计算质心
centroids = kMeans(A, 4);

随机选取质心
%% 取得随机中心
function [ centroids ] = randCent( dataSet, k )
    [m,n] = size(dataSet);%取得列数
    centroids = zeros(k, n);
    for j = 1:n
        minJ = min(dataSet(:,j));
        rangeJ = max(dataSet(:,j))-min(dataSet(:,j));
        centroids(:,j) = minJ+rand(k,1)*rangeJ;%产生区间上的随机数
    end
end

计算相似性
function [ dist ] = distence( vecA, vecB )
    dist = (vecA-vecB)*(vecA-vecB)';%这里取欧式距离的平方
end

kMeans的主程序
%% kMeans的核心程序,不断迭代求解聚类中心
function [ centroids ] = kMeans( dataSet, k )
    [m,n] = size(dataSet);
    %初始化聚类中心
    centroids = randCent(dataSet, k);
    subCenter = zeros(m,2);%做一个m*2的矩阵,第一列存储类别,第二列存储距离
    change = 1;%判断是否改变
    while change == 1
        change = 0;
        %对每一组数据计算距离
        for i = 1:m
            minDist = inf;
            minIndex = 0;
            for j = 1:k
                 dist= distence(dataSet(i,:), centroids(j,:));
                 if dist < minDist
                     minDist = dist;
                     minIndex = j;
                 end
            end
            if subCenter(i,1) ~= minIndex
                change = 1;
                subCenter(i,:)=[minIndex, minDist];
            end        
        end
        %对k类重新就算聚类中心
        
        for j = 1:k
            sum = zeros(1,n);
            r = 0;%数量
            for i = 1:m
                if subCenter(i,1) == j
                    sum = sum + dataSet(i,:);
                    r = r+1;
                end
            end
            centroids(j,:) = sum./r;
        end
    end
    
    %% 完成作图
    hold on
    for i = 1:m
        switch subCenter(i,1)
            case 1
                plot(dataSet(i,1), dataSet(i,2), '.b');
            case 2
                plot(dataSet(i,1), dataSet(i,2), '.g');
            case 3
                plot(dataSet(i,1), dataSet(i,2), '.r');
            otherwise
                plot(dataSet(i,1), dataSet(i,2), '.c');
        end
    end
    plot(centroids(:,1),centroids(:,2),'+k');
end

最终的聚类结果
### 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; ```
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值