聚类算法——K-Means算法

聚类学习

一、聚类概念:1.无监督问题:我们的手里没有标签了,需要计算机自己学习得出标签。

                         2.聚类:在一堆数据里面,把相似的东西分到一组,一组为一类,也叫一个簇。

                         3.难点:如何去评价聚类的结果的好坏,怎样把参数调到适合数据聚类的大小。

二、K-Means算法:

(一)、基本概念:

  1. 我们要选择簇的个数,即你想把数据分成多少类,也就是要制定k的值。
  2. 质心:就是均值,只要在向量的各维度取平均就能得到。
  3. 距离的度量:常用的是欧几里得和余弦相似度的距离,但是在计算距离前需要进行标准化。
  4. 优化目标:min\sum_{i=1}^{k}\sum_{x\in {c_{i}}^{}}^{}({c_{i}}^{},x)^{2},要对k个簇都进行优化,然后每个簇的每一个中心点都需要计算所在簇的所有点到中心点的距离,我们要让这个距离越小越好,这也就说明了每个数据之间尽可能的挨近,聚类结果自然而然就更好。

三、在计算距离的时候,常用的就是欧氏距离计算,其计算思想如下:

  1. 二维数据:如果有两个点A(x_{1},y_{1}) ,B(x_{2},y_{2}) ,记欧氏距离为d,则有
    d=\sqrt{(x_{2}-x_{1})^{2}+(y_{2}-y_{1})^{2}}
  2. n维数据:如果有两个n维向量,A(x_{1},x_{2},...,x_{n})B(y_{1},y_{2},...,y_{n})
    d=\sqrt{\sum_{i=1}^{n}(x_{i}-y_{i})^{2}}=\sqrt{(x_{1}-y_{1})^{2}+(x_{2}-y_{2})^{2}+...+(x_{n}-y_{n})^{2}}
  3. 在使用欧式距离的时候要先标准化数据,即归一化,让数据的范围在0~1内。操作如下:
    d_{normalized}=\frac{\mathrm{d-min(D)} }{\mathrm{max(D)-min(D)} }
    其中:d为原始的欧氏距离
               D是所有样本之间的欧式距离的一个大集合
               max(D)是所有距离中的最大值
               min(D)是所有距离中的最小值
  4. 优化:通过这样一次又一次的迭代,每一次的计算让每个点到中心点即质心的距离之和变得越来越小,越小就越好,越小就越相似,聚类效果也就越好。

四、工作流程 :

  1. 遍历:随机选定k_{i}(自己设置)个点,然后进行欧式距离计算,离k点越进的那个点就属于k这个点所代表的簇,例如A,B,C三个点的欧式距离都距离k_{2}最近,这三个点就属于k_{2}所代表的这个簇。
  2. 更新:每一次的聚类结束之后,根据结束之后的聚类结构重新计算出质心,每个簇的质心更新之后,又重复第一步遍历所有的点,再进行一次聚类。
  3. 不断更新:当所有的样本点几乎不发生变化之后,这个聚类的结果就是最终的聚类结果。

五、K-Mwans算法的优缺点:

优点:

  1. 很简单,非常容易理解原理和操作。
  2. 很快速,需要计算的也就是不断更新每个样本点距离质心点的距离。
  3. 适合常规的数据集。 

缺点:

  1. k值难以确定:当数据量很大或者分布较为散的时候不容易看出应当分为几个簇,因此需要设置多组的k值,然后比较性能最好的那个k值作为簇的总数。
  2. 复杂度与样本呈线性关系:当样本的量非常大的时候,所需要的时间复杂度与空间复杂度将随之上升。
  3. 很难实现任意形状的簇:例如一个笑脸形的数据集,运用k-means算法就不能合理的进行聚类。笑脸形数据可视化k-means聚类如图所示 
  4. k-means算法对初值的要求非常严格,你所选择的不相等的初值对你最终的聚类结果会产生非常大的影响。

五、MATLAB的K-MEANS算法代码实现:

% 输入数据矩阵,每一行是一个样本,每一列是一个特征
data = [1, 2; 1.5, 1.8; 5, 8; 8, 8; 1, 0.6; 9, 11];

% 设置聚类数目
k = 2;

% 初始化聚类中心,从数据中随机选择 k 个样本作为初始中心
initialCentroids = data(randperm(size(data, 1), k), :);

% 设置迭代次数
maxIter = 100;

% 运行 k-means 算法
[centroids, assignments] = kMeans(data, initialCentroids, maxIter);

% 输出聚类中心和每个样本的分配结果
disp('聚类中心:');
disp(centroids);

disp('每个样本的分配结果:');
disp(assignments);

% 定义 k-means 算法函数
function [centroids, assignments] = kMeans(data, initialCentroids, maxIter)
    centroids = initialCentroids;
    numData = size(data, 1);
    numFeatures = size(data, 2);
    k = size(initialCentroids, 1);
    assignments = zeros(numData, 1);

    for iter = 1:maxIter
        % 分配每个样本到最近的聚类中心
        for i = 1:numData
            distances = sqrt(sum((centroids - data(i, :)).^2, 2));
            [~, assignments(i)] = min(distances);
        end

        % 更新聚类中心
        for j = 1:k
            clusterPoints = data(assignments == j, :);
            centroids(j, :) = mean(clusterPoints, 1);
        end
    end
end

代码描述:

  1. 运行操作步骤

    a. 准备数据:在代码中,通过定义 data 矩阵输入数据。每一行是一个样本,每一列是一个特征。

    b. 设置聚类数目:通过变量 k 指定要将数据分成的聚类数目。

    c. 初始化聚类中心:从数据中随机选择 k 个样本作为初始聚类中心。

    d. 设置迭代次数:通过 maxIter 指定算法运行的最大迭代次数。

    e. 运行 k-means:调用 kMeans 函数执行 k-means 算法,得到聚类中心 centroids 和每个样本的分配结果 assignments

    f. 输出结果:输出聚类中心和每个样本的分配结果。

  2. 变量含义

    • data:输入数据矩阵,每一行代表一个样本,每一列代表一个特征。

    • k:聚类的数目,指定将数据分成的簇的数量。

    • initialCentroids:初始聚类中心,从数据中随机选择的样本。

    • maxIter:最大迭代次数,指定算法运行的最大迭代次数。

    • centroids:聚类中心的最终结果,表示每个聚类的中心点。

    • assignments:每个样本的分配结果,表示每个样本被分配到的聚类簇的索引。

  3. 运行示例

    在 MATLAB 中,将上述代码复制粘贴到编辑器中,然后执行整个脚本。确保提前准备好数据,并根据实际需求调整聚类数目等参数。最后,查看输出结果,即聚类中心和每个样本的分配情况。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麻辣小凉皮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值