zoukankan      html  css  js  c++  java
  • k-means算法及matlab实现

    K-means算法很简单,它属于无监督学习算法中的聚类算法中的一种方法吧,利用欧式距离进行聚合啦。

    解决的问题如图所示哈:有一堆没有标签的训练样本,并且它们可以潜在地分为K类,我们怎么把它们划分呢?     那我们就用K-means算法进行划分吧。

    image

    算法很简单,这么做就可以啦:

    第一步:随机初始化每种类别的中心点,u1,u2,u3,……,uk;

    第二步:重复以下过程:

    image

    然后 ,就没有然后了,就这样子。

    太简单, 不解释。

    2017年10月14日补:

    今晚造了一个轮子,k-means算法在matlab中的实现,使用的是欧氏距离; 共有两个文件,分别为euclidean_distance.m 与k_means.m;   代码如下(或:http://pan.baidu.com/s/1o8p6sfo 密码:4hhb):

    euclidean_distance.m文件:

    function [ output ] = euclidean_distance(data, center)
    % 用于计算训练样本与聚类中心的的欧氏距离的平方;
    % 其中  data为一个 矩阵 M×N, 表示样本集,其中M表示共有M个样本, N表示每一个样本的维度;
    %      centre 为一个矩阵 K×N,表示K个聚类中心,N表示样本的维度;
    %      output 为一个矩阵,大小为M×K; 第x行y列表示第X个样本与第Y个聚类中心的距离;(每一行表示一个样本与K个聚类中心的距离);
    
    
    % 作者:殷和义;
    % 时间:2017年10月14日;
    
    
    
    
    data_num = size(data, 1);
    center_num = size(center, 1);
    output = zeros(data_num, center_num);
    for i = 1:center_num
        difference = data - repmat(center(i,:), data_num, 1);    %求样本集与第i个聚类中心的差;
        sum_of_squares = sum(difference .* difference, 2);        %求平方, 并对每一行求和;
        output(:, i) = sum_of_squares;             
    end
    
    end

    k_means.m 文件

    function [ output ] = k_means(data, k_value)
    % 功能:实现K-means算法的聚类功能;
    % 输入:    data, 为一个 矩阵 M×N, 表示样本集,其中M表示共有M个样本, N表示每一个样本的维度;
    %           k_value, 表示聚类的类别数目;
    % 输出:    output, 是一个列向量 M×,表示每一个样本属于的类别编号;
    
    % 作者: 殷和义;
    % 时间: 2017年10月14日
    
    
    %从样本中,随机选取K个样本作为初始的聚类中心;
    data_num = size(data, 1);
    temp = randperm(data_num, k_value)';     
    center = data(temp, :);
    
    %用于计数迭代次数:
    iteration = 0;
    while 1
        %获得样本集与聚类中心的距离;
        distance = euclidean_distance(data, center);
        %将距离矩阵的每一行从小到大排序, 获得相应的index值,其实我们只需要index的第一列的值;
        [~, index] = sort(distance, 2, 'ascend');
    
        %接下来形成新的聚类中心;
        center_new = zeros(k_value, size(data, 2));
        for i = 1:k_value
            data_for_one_class = data(index(:, 1) == i, :);          
            center_new(i,:) = mean(data_for_one_class, 1);    %因为初始的聚类中心为样本集中的元素,所以不会出现某类别的样本个数为0的情况;
        end
       
        %输出迭代次数,给眼睛一个反馈;
        iteration = iteration + 1;
        fprintf('进行迭代次数为:%d
    ', iteration);
        
        % 如果这两次的聚类中心不变,则停止迭代,跳出循环;
        if center_new == center
            break;
        end
        
        center = center_new;
    end
    
    output = index(:, 1);
        
    end
  • 相关阅读:
    js修改剪切板内容的方法
    使用jq获取文字的宽度
    如何改变placeholder的样式
    如何使用phpmyadmin建立外键约束
    php上传文件中文文件名乱码的解决方法
    如何禁止审查元素扒代码(F12)
    如何使用css影藏滚动条
    webstorm配置babel自动转译es6的方法
    css纯字母或者字母换行显示
    使用Jquery做分页效果
  • 原文地址:https://www.cnblogs.com/yinheyi/p/6132362.html
Copyright © 2011-2022 走看看