1. 程式人生 > >K-Means聚類演算法原理及實現

K-Means聚類演算法原理及實現

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <cmath>

using namespace std;

class Cluster//聚類,每個聚類都包含兩個屬性,一個是簇心的屬性(維數),另一個是距離本簇心最近的樣本點
{
public:
    vector <double> centroid;//存放簇心的屬性(維數)
    vector <int> samples;//存放屬於相同簇心樣本的下標
};

double CalculateDistance(vector<double> a, vector<double> b)//計算兩個向量之間的距離
{
    int len1 = a.size();
    int len2 = b.size();
    if(len1 != len2)
        cerr<<"Dimensions of two vectors must be same!!\n";
    double temp = 0;
    for(int i = 0; i  < len1; ++i)
        temp += pow(a[i]-b[i], 2);
    return sqrt(temp);
}

//max_iteration表示最大的迭代次數,min_move_distance
vector<Cluster> KMeans(vector<vector<double> >data_set, int k, int max_iteration, double threshold)
{
    int row_number = data_set.size();//資料的個數
    int col_number = data_set[0].size();//每個向量(屬性)的維數

    //初始隨機選取k個質心
    vector<Cluster> cluster(k);//存放k個簇心。vector<T> v(n,i)形式,v包含n 個值為 i 的元素
    srand((int)time(0));
    for(int i = 0; i < k; ++i)
    {
        int c = rand()%row_number;
        cluster[i].centroid = data_set[c];//把第c個作為簇心,並把它相應的屬性賦值給centroid
    }

    //iteration
    int iter = 0;
    while(iter < max_iteration)
    {
        iter++;
        for(int i = 0; i < k; ++i)
            cluster[i].samples.clear();
        //找出每個樣本點所屬的質心
        for(int i = 0; i < row_number; ++i)
        {
            double min_distance = INT_MAX;
            int index = 0;
            //計算離樣本點i最近的質心
            for(int j = 0; j < k; ++j)
            {
                double temp_distance = CalculateDistance(data_set[i], cluster[j].centroid);
                if(min_distance > temp_distance)
                {
                    min_distance = temp_distance;
                    index = j;
                }
            }
            cluster[index].samples.push_back(i);//把第i個樣本點放入,距離其最近的質心的samples
        }

        double max_move_distance = INT_MIN;
        //更新簇心
        for(int i = 0; i < k; ++i)
        {
            vector<double> temp_value(col_number, 0.0);
            for(int num = 0; num < cluster[i].samples.size(); ++num)//計算每個樣本的屬性之和
            {
                int temp_same = cluster[i].samples[num];
                for(int j = 0; j < col_number; ++j)
                    temp_value[j] += data_set[temp_same][j];
            }
            vector<double> temp_centroid = cluster[i].centroid;
            for(int j = 0; j < col_number; ++j)
                cluster[i].centroid[j] = temp_value[j]/cluster[i].samples.size();
            //計算從上一個簇心移動到當前新的簇心的距離
            double temp_distance = CalculateDistance(temp_centroid, cluster[i].centroid);
            if(max_move_distance < temp_distance)
                max_move_distance = temp_distance;
        }
        if(max_move_distance < threshold)
            break;
    }
    return cluster;
}

int main()
{
    int threshold = 0.001;//當從上一個簇心移動到當前粗心的距離幾乎不變時,可以結束。這裡用threshold作為閾值
    vector <vector<double> >data_set(9, vector<double>(2, 0.0));
    int point_number;
    cin>>point_number;
    for(int i = 0; i < point_number; ++i)
    {
        for(int j = 0; j < 2; ++j)
            cin>>data_set[i][j];
    }

    int col = data_set[0].size();
    vector<Cluster> cluster_res = KMeans(data_set, 2, 200, threshold);
    for(int i = 0; i < cluster_res.size(); ++i)
    {
        cout<<"Cluster "<<i<<" : "<<endl;
        cout<<"\t"<<"Centroid: ";//<<endl;
        cout<<"(";
        for(int j = 0; j < cluster_res[i].centroid.size()-1; ++j)
            cout<< cluster_res[i].centroid[j]<<",";
        cout<<cluster_res[i].centroid[cluster_res[i].centroid.size()-1]<<")"<<endl;
        cout<<"\t"<<"Samples: ";
        for(int j = 0; j < cluster_res[i].samples.size(); ++j)
        {
            int c = cluster_res[i].samples[j];
            cout<<"(";
            for(int m = 0; m < col-1; ++m)
                cout<<data_set[c][m]<<",";
            cout<<data_set[c][col-1]<<")  ";
        }
        cout<<endl;
    }
    return 0;
}

/**

1 1
2 1
1 2
2 2
3 3
8 8
8 9
9 8
9 9

*/


相關推薦

K-Means演算法原理實現

#include <iostream> #include <cstdlib> #include <ctime> #include <vector> #include <cmath> using namespace std; class Clust

k-means演算法原理python3實現

本文主要內容:                 1.k-means解決的問題;                 2.k-means原理介紹;                 3.k-means的簡單實現。 1.k-means解決的問題          k-

機器學習中K-means演算法原理C語言實現

本人以前主要focus在傳統音訊的軟體開發,接觸到的演算法主要是音訊訊號處理相關的,如各種編解碼演算法和回聲消除演算法等。最近切到語音識別上,接觸到的演算法就變成了各種機器學習演算法,如GMM等。K-means作為其中比較簡單的一種肯定是要好好掌握的。今天就講講K-means的基本原理和程式碼實現。其中基本原

【OpenCV學習筆記 020】K-Means演算法介紹實現

一、K-Means演算法介紹 在資料探勘中,K-Means演算法是一種cluster analysis的演算法,其主要是來計算資料聚集的演算法,主要通過不斷地取離種子點最近均值的演算法。 問題 K-Means演算法主要解決的問題如下圖所示。我們可以看到,在圖的左邊有一些點,

java實現K-means演算法k-means演算法原理

/** * 需要所有point 以及族中心list * * @author:Yien * @when:2018年5月20日下午3:14:09 * @Description:TOD

k-means(k均值)演算法介紹實現(c++)

基本介紹: k-means 演算法接受輸入量 k ;然後將n個數據物件劃分為 k個聚類以便使得所獲得的聚類滿足:同一聚類中的物件相似度較高;而不同聚類中的物件相似度較小。聚類相似度是利用各聚類中物件的均值所獲得一個“中心物件”(引力中心)來進行計算的。 工作過程:   k

K-means演算法原理簡單介紹

K-means演算法 (1. 剛開始隨機選擇兩個點作為簇重心,然後計算每個資料點離這個重心的距離並把這些點歸為兩個類) (上一步的結果如下圖,所有離藍色叉近的點被標為藍色了,紅色亦然)

【無監督學習】1:K-means演算法原理

前言:粗略研究完神經網路基礎——BP、CNN、RNN、LSTM網路後自己算是鬆懈了很多,好長的時間都沒有堅持再更新部落格了。“腐敗”生活了這麼久,還是要找到自己一點樂趣吧,於是想了一想,決定把《機器學習》的演算法研究過得都重新梳理一遍,於是就從無監督學習——聚類

層次演算法原理實現

聚類 聚類是對點集進行考察並按照某種距離測度將他們聚成多個“簇”的過程。聚類的目標是使得同一簇內的點之間的距離較短,而不同簇中點之間的距離較大。 一、聚類演算法介紹      層次法聚類和點分配法聚類。 1.1     點、空間和距離 點集是一種適合於聚類的資料集,每個點都是某空間下的物件。一般意義上,空間

K-Means演算法原理

    K-Means演算法是無監督的聚類演算法,它實現起來比較簡單,聚類效果也不錯,因此應用很廣泛。K-Means演算法有大量的變體,本文就從最傳統的K-Means演算法講起,在其基礎上講述K-Means的優化變體方法。包括初始化優化K-Means++, 距離計算優化elkan K-Means演算法和大資料

K-means演算法原理分析與實際應用案例分析(案例分析另起一篇部落格)

引言 在資料分析中,我們常常想將看上去相似或者行為形似的資料聚合在一起。例如,對一個營銷組織來說,將不同客戶根據他們的特點進行分組,從而有針對性地定製營銷活動,這很重要。又比如,對學校老師來說,將學生分組同樣能夠有所側重的進行教育活動。分類與聚類是資料探勘領域

K-means演算法及其MATLAB實現

clear all;close all;clc; % 第一組資料 mu1=[0 0 ]; %均值 S1=[.1 0 ;0 .1]; %協方差 data1=mvnrnd(mu1,S1,100); %產生高斯分佈資料 %第二組資料 mu2=[1.25 1.25 ]; S2=[.1 0 ;0 .1]; da

【程式碼】K-means詳解實現 (Matlab工具箱和自己實現

一. 聚類 先說說聚類。顧名思義,就是有一團資料,根據某種準則把相似的資料分別聚在一起,形成不同的類別(每個類別稱為一簇)。聚類是一種無監督的演算法。所謂無監督就是說,雖然聚類把物體分類到了不同的簇,只能知道哪些資料是屬於同一類的,至於這一類資料到底是什麼,並不知道。

K-Means演算法原理實現

問題導讀: 1、如何理解K-Means演算法? 2、如何尋找K值及初始質心? 3、如何應用K-Means演算法處理資料?K-Means是聚類演算法中的一種,其中K表示類別數,Means表示均值。顧名思義K-Means是一種通過均值對資料點進行聚類的演算法。K-Means演算

使用Java實現K-Means演算法

第一次寫部落格,隨便寫寫。 關於K-Means介紹很多,還不清楚可以查一些相關資料。 個人對其實現步驟簡單總結為4步: 1.選出k值,隨機出k個起始質心點。  2.分別計算每個點和k個起始質點之間的距離,就近歸類。  3.最終中心點集可以劃分為k類,

單機環境分散式環境下K-Means演算法的執行例項

  單機環境下的K-Means聚類演算法執行例項 參考書籍《Mahout in Action》:要資源的可以找我~(中英文都有) 在eclipse平臺上實現K-Means例項 程式碼如下: package kmeans; import java.io.File; im

Python實現K-Means演算法

       宣告:程式碼的執行環境為Python3。Python3與Python2在一些細節上會有所不同,希望廣大讀者注意。本部落格以程式碼為主,程式碼中會有詳細的註釋。相關文章將會發布在我的個人部落格專欄《Python從入門到深度學習》,歡迎大家關注~

C#實現簡單的K-means演算法

namespace K_means{    public class Kmeans    {        double[,] inPut;//資料        int k;//類別數        int Num;//檔案數        int sub;//特徵值數  

python K-Means演算法實現

K-Means 簡介 聚類演算法有很多種(幾十種),K-Means是聚類演算法中的最常用的一種,演算法最大的特點是簡單,好理解,運算速度快,但是一定要在聚類前需要手工指定要分成幾類。 具體實現步驟如下: 給定n個訓練樣本{x1,x2,x3,…,xn}  

利用python內建K-Means演算法實現鳶尾花資料的

在進去聚類情況分析前,我們需要為我們的IDLE安裝sklearn庫,scikit-learn是Python的一個開源機器學習模組,它建立在NumPy,SciPy和matplotlib模組之上能夠為使用者提供各種機器學習演算法介面,可以讓使用者簡單、高效地進行資料探勘和資料分析