c 實現K means聚類演算法(模式識別課設)

2021-08-03 04:12:04 字數 3821 閱讀 4215

原理網上很多,我隨便找兩篇作為參考:

原理介紹計算法實現:

演算法質量提高分析:

**裡寫了很多注釋,就不解釋了

#include

using

namespace

std;

#include

#include

#include

#include

#include

ifstream fin; //輸入檔案

ofstream fout1; //輸出檔案

ofstream fout2;

ofstream fout3;

ofstream fout4;

const

int maxdatanum=200;//可處理的最大資料量,可自己設定

const

int k=3;//資料需要分成多少類

int datanum;//實際資料的個數

const

int dimension=4;//維度,資料的維數

double data[maxdatanum][dimension];//存放樣本資料的陣列,maxdatanum表示取得最大資料量,dimension表示每個資料的維數

double oldkmeans[k][dimension];//用於存放老聚類中心

double newkmeans[k][dimension];//用於存放新聚類中心

double tempdist[k];//臨時存放與每個聚類中心的距離

double tempnum[k];//每次聚類時每個聚類中心包含的最終資料個數,每次初始化為1

int index[maxdatanum];//儲存每個資料屬於哪個分類

void getdatenum()//從資料庫中獲取資料

datanum++;

}fin.close();

}double calcdist(double a[dimension],double b[dimension]) //計算兩點之間的距離的平方(歐氏距離的平方)

int getmin(double tempdist[k])//返回陣列最小值所在的下標

double getminvalue(int a,double

array)//返回陣列最小值

return temp;

}void getnewkmeans(double data[maxdatanum][dimension],double oldkmeans[k][dimension])//求聚類中心,存放在newkmeans裡

for(int i=0;i//每個資料分別於聚類中心進行計算,判斷該資料屬於哪個聚類中心

for(int j=0;j//計算資料與每個聚類中心的距離,存放在tempdist中

tempdist[j]=calcdist(data[i],oldkmeans[j]);

}sign=getmin(tempdist);//返回最小距離所對應的下標,也就是該資料屬於哪個聚類中心

tempnum[sign]++;//第sign個聚類中心包含的資料+1

index[i]=sign;//標記第i個資料屬於第幾個聚類中心

for(int k=0;k//將每個聚類中心的資料求和

newkmeans[sign][k]+=data[i][k];

}

}for(int j=0;j//取平均值

for(int n=0;n//先減去原來的聚類中心,因為最開始new等於old,所以就是減去old,那就僅是資料了

newkmeans[j][n]-=oldkmeans[j][n];

}for(int k=0;k//除以每個聚類中心所包含的資料個數,得出平均值}}

}bool compare(double oldkmeans[k][dimension],double newkmeans[k][dimension]) //比較新舊聚類中心是否相等

return

true;

}void initialize()//初始化聚類中心

int next=1;//記錄現在已經初始化了多少個聚類中心,上面已經初始化了乙個,所以這裡初始化為1

int sign[k-1];//記錄初始聚類中心位於原始資料data陣列中的下標

double dist=0;//記錄資料與前面已經找到的聚類中心的距離的最小中的最大的那個(有點繞),見參考文章

double temp[k-1];//記錄某乙個資料與前面已經找到的聚類中心的距離

while(next//該演算法就是參考第二篇博文寫的,感謝分享

for(int j=1;jfor(int i=0;idouble b=getminvalue(next,temp);

if(dist1]=j;

dist=b;

}

}int a=sign[next-1];

cout

}}void main()

while(!compare(oldkmeans,newkmeans) && mask<100);//當新舊聚類中心相等(一定誤差)時退出

//計算正確率

double accuracy0=0;//記錄分類的正確率

double accuracy1=0;

double accuracy2=0;

for(int h=0;hwhile(h<50)

while(h<100)

while(h<150)

}double result=(accuracy0+accuracy1+accuracy2)/150;//這是總正確率

accuracy0=accuracy0/50;//這是每一部分的正確率

accuracy1=accuracy1/50;

accuracy2=accuracy2/50;

//輸出相關資料

cout

<<"訓練資料個數:"

<<"迭代次數:"

<<"三個聚類中心的正確率分別為:"

<2)<" "

<" "

cout

<<"第"

<1

<<"個聚類中心:"

<" ";

}cout

/* fout1.open("k1.txt",ios::out);

fout2.open("k2.txt",ios::out);

fout3.open("k3.txt",ios::out);

for(int j=0;j

本身**可以縮減一部分的,只是我為了方便測試不同的資料樣本,把**整理好了,基本上除了fout那幾個輸出到txt的地方需要修改外,只需要修改「k」,」maxdatanum」,」dimension」這三個變數就好了,其他和資料有關的地方也可以根據注釋提示修改,挺方便的。

放一下測試結果:

訓練資料個數:150

迭代次數:5

三個聚類中心的正確率分別為:1.00

0.96

0.72

第1個聚類中心:

5.01

3.43

1.46

0.25

第2個聚類中心:

6.85

3.07

5.74

2.07

第3個聚類中心:

5.90

2.75

4.41

1.43

press any key

tocontinue

測試資料是經典的鳶尾花資料集,**

執行環境是vc++6.0,其他環境未測試。

k means聚類演算法C 實現

clustering 中文翻譯作 聚類 簡單地說就是把相似的東西分到一組,同 classification 分類 不同,對於乙個 classifier 通常需要你告訴它 這個東西被分為某某類 這樣一些例子,理想情況下,乙個 classifier 會從它得到的訓練集中進行 學習 從而具備對未知資料進行...

kmeans聚類 c 實現

num class 聚類數 num data 資料個數 dimension 資料維度 每個資料是多少維的 data 待聚類資料指標 cluster center 聚類中心指標 max error 前後兩次誤差降低到此值迭代終止 max iters 最大迭代次數 1 隨機初始化聚類中心 2 根據聚類中...

Matlab實現k means聚類演算法

k means是聚類中的乙個十分經典的演算法,具體的思想可以參考andrew ng的講義 the k means clustering algorithm 這裡不再贅述。需要用到matlab中的核心函式kmeans,具體用法可以參考matlab命令 doc kmeans idx kmeans x,k...