原理網上很多,我隨便找兩篇作為參考:
原理介紹計算法實現:
演算法質量提高分析:
**裡寫了很多注釋,就不解釋了
#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...