K均值聚类的理解和实现
目錄
1. 距離的測(cè)度
1.1 歐式距離
1.2 馬氏距離
1.2.1 利用馬氏距離對(duì)數(shù)據(jù)進(jìn)行歸一化
1.2.2 利用馬氏距離進(jìn)行分類
2. K均值的基本理論
2.1 K均值的原理和實(shí)現(xiàn)
2.2 K均值的缺點(diǎn)
2.3 K均值改進(jìn)
3. 算法實(shí)現(xiàn)
3.1 獲取樣本
3.2 協(xié)方差逆陣方根的計(jì)算方法
3.3 聚類實(shí)驗(yàn)
3.3.1 一般的K均值聚類
3.3.2 基于馬氏距離K-means++聚類
3.3.3 基于肘部法則的K-means++聚類
4.參考資料
1. 距離測(cè)度
1.1 歐式距離
在數(shù)學(xué)中,歐氏距離或歐幾里德度量是歐幾里得空間中兩點(diǎn)之間的“普通” 直線距離。通過(guò)這個(gè)距離,歐幾里德空間成為度量空間。相關(guān)的規(guī)范稱為歐幾里得范數(shù)。較早的文獻(xiàn)將度量指為畢達(dá)哥拉斯度量。廣義的歐幾里得范數(shù)項(xiàng)是L2范數(shù)或L2距離。
通常,對(duì)于n維空間來(lái)說(shuō),歐幾里得距離可以表示為:
中的歐式距離如圖1.1-1所示:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 圖1.1-1?中歐幾里得距離的表達(dá)
標(biāo)準(zhǔn)的歐幾里德距離可以是平方的,以便逐漸將更大的重量放置在更遠(yuǎn)的物體上。在這種情況下,等式變?yōu)?#xff1a;
? ? ? ? ? ? ? ? ? ? ? ? ? ?
平方歐幾里德距離不是一個(gè)度量,因?yàn)樗粷M足三角不等式 ;?然而,它經(jīng)常用于僅需要比較距離的優(yōu)化問(wèn)題。
它在理性三角學(xué)領(lǐng)域也被稱為quadrance。
1.2 馬氏距離
馬氏距離是對(duì)點(diǎn)P和分布D的距離度量。馬氏距離對(duì)多維數(shù)據(jù)進(jìn)行了歸一化,并測(cè)量了P點(diǎn)相對(duì)于D的平均值的標(biāo)準(zhǔn)差。如果P在D分布中心,那么馬氏距離為0。如果對(duì)數(shù)據(jù)進(jìn)行主成分分析,如圖1.2-1所示,那么,當(dāng)P相對(duì)于主軸越遠(yuǎn),馬氏距離的數(shù)值也就隨之增長(zhǎng)。當(dāng)我們對(duì)主軸進(jìn)行進(jìn)行歸一化后,馬氏距離也就等同于在歐式空間的仿射變換。因此,馬氏距離具有“無(wú)單位”和“尺度不變性”的特性,并且考慮了數(shù)據(jù)集的相關(guān)性。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 圖1.2-1 數(shù)據(jù)的主成分分析
馬哈拉諾比斯觀察距離 :
?從一組帶有均值的觀察中得出:
那么,觀察值與集合的距離使用協(xié)方差矩陣S表示為:
集合中兩個(gè)隨機(jī)變量的距離為:
如果協(xié)方差矩陣是單位矩陣,則馬哈拉諾比斯距離減小到歐幾里得距離。如果協(xié)方差矩陣是對(duì)角矩陣,那么得到的距離度量稱為標(biāo)準(zhǔn)歐式距離:
其中,表示變量的標(biāo)準(zhǔn)差。
1.2.1 利用馬氏距離進(jìn)行數(shù)據(jù)歸一化
如圖1.2.1-1所示,當(dāng)數(shù)據(jù)在空間中以非常不對(duì)稱的形式進(jìn)行分布時(shí),k-means算法總是試圖挖掘出一些與聚類相關(guān)的信息,因?yàn)閗-means聚類的核心觀點(diǎn)在于數(shù)據(jù)是以不均勻的方式進(jìn)行聚類的。然而,“不對(duì)稱”和“不均勻”之間卻有著重要的區(qū)別。例如,當(dāng)數(shù)據(jù)在某個(gè)維度上分布很遠(yuǎn),而在其他維度上距離相對(duì)較小時(shí),k-means必然不會(huì)收斂到好的結(jié)果。
? ? ? ?? 圖1.2.1-1 (a)原始數(shù)據(jù)的垂直距離比水平距離小 (b)對(duì)空間進(jìn)行方差歸一化,數(shù)據(jù)之間的水平距離小于垂直距離
這種情況往往只是因?yàn)閿?shù)據(jù)向量在不同的維度有不同的底層單位。例如,如果使用身高、年齡和學(xué)齡代表一個(gè)人,那么由于單位的不同,數(shù)據(jù)在不同的維度上必然產(chǎn)生不同的分布。同樣,年齡和學(xué)齡雖有著相同的單位,但是,在自然人口中也存在差異。
當(dāng)我們將整個(gè)數(shù)據(jù)集作為一個(gè)整體來(lái)看待時(shí),我們可以通過(guò)協(xié)方差矩陣來(lái)重新調(diào)整整個(gè)數(shù)據(jù)集,這種技術(shù)也稱之為數(shù)據(jù)歸一化。
傳統(tǒng)意義上,馬氏距離是以該點(diǎn)在特定的方向上的方差來(lái)度量數(shù)據(jù)點(diǎn)與分布之間的距離。我們使用分布的協(xié)方差的倒數(shù)來(lái)計(jì)算馬氏距離:
其中, 表示數(shù)學(xué)期望,馬氏距離可表示為:
對(duì)此有以下兩種方式來(lái)解決:在K-means算法中使用馬氏距離而不是歐式距離,或?qū)?shù)據(jù)進(jìn)行尺度變化,然后在放縮的空間中使用歐幾里得距離。第一種方法更為直觀,但第二種方法更容易計(jì)算,因?yàn)閿?shù)據(jù)轉(zhuǎn)化是線性的。
數(shù)據(jù)集的轉(zhuǎn)化:
在這里,是即將使用的一組新的數(shù)據(jù)向量,D是原始數(shù)據(jù)。的因子是逆協(xié)方差的平方根。
1.2.2 利用馬氏距離分類
利用K-means聚類或者任何其他的方法給定一組聚類標(biāo)簽,利用這些標(biāo)簽可以預(yù)測(cè)一些新的數(shù)據(jù)點(diǎn)最可能屬于哪個(gè)聚類。假設(shè)聚類本身服從高斯分布,將馬氏距離的概念引進(jìn)該分類問(wèn)題也是非常有意義的。
分類方法:對(duì)每個(gè)聚類計(jì)算平均協(xié)方差,這樣我們可以基于協(xié)方差來(lái)計(jì)算新的數(shù)據(jù)點(diǎn)到每個(gè)聚類中心的馬氏距離,從而確定分類。
但是,是不是說(shuō)具有最小馬氏距離的類是最優(yōu)的解呢?
事實(shí)并非如此,當(dāng)且僅當(dāng)所有的聚類都擁有相同數(shù)量的數(shù)據(jù)點(diǎn)時(shí)(每個(gè)集群內(nèi)的數(shù)據(jù)點(diǎn)的先驗(yàn)概率大小相等),此結(jié)論才成立。
貝葉斯規(guī)則簡(jiǎn)明扼要的說(shuō)了這一區(qū)別:
對(duì)于給定的命題A和命題B,給定B的情況下,A發(fā)生的概率一般來(lái)說(shuō)并不等于給定A的情況下,B發(fā)生的概率:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
相反,給定A的情況下B發(fā)生的概率,乘以A的概率必然等于給定B的情況下A發(fā)生的概率誠(chéng)意B發(fā)生的概率:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
同樣的道理,馬氏距離表示的是一個(gè)特定樣本來(lái)自特定聚類的概率,事實(shí)上,我們想知道的是:給定變量x,它出現(xiàn)在某一特定類中的概率。顯然,馬氏距離告訴我們的結(jié)論恰恰是相反的。例如,對(duì)于給定的變量x出現(xiàn)在C類的概率:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
其中,表示聚類的數(shù)據(jù)量和整體數(shù)據(jù)里。
也就是說(shuō),為了比較不同聚類的馬氏聚類,我們必須考慮聚類的大小。考慮到每個(gè)聚類的概率服從高斯分布,聚類之間的似然性可以表示如下:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
這就好比說(shuō),發(fā)現(xiàn)一只看似恐龍的蜥蜴屬于恐龍的概率遠(yuǎn)遠(yuǎn)小于它屬于蜥蜴的概率,正是因?yàn)閮蓚€(gè)集群的先驗(yàn)概率是不同的。
2. K均值的基本理論
2.1 K均值的基本原理和實(shí)現(xiàn)
K-means嘗試尋找數(shù)據(jù)的自然類別,用戶設(shè)置類別的個(gè)數(shù),從而尋找到好的類別中心。
算法的流程如下:
1.輸入數(shù)據(jù)集合和類別數(shù)K;
2.隨機(jī)分配類別中心點(diǎn)的位置;
3.將每個(gè)點(diǎn)放入離它最近的類別中心點(diǎn)所在的集合;
4.移動(dòng)類別中心點(diǎn)到它所在的集合;
5.轉(zhuǎn)到第3步,直至收斂。
K均值的迭代示意圖如圖2.1-1所示:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖2.1-1 K均值的迭代示意圖
2.2 K均值的缺點(diǎn)
K-means是一個(gè)極其高效的聚類算法,但是它存在以下三個(gè)問(wèn)題:
1.它不能保證定位到聚類中心的最佳方案,但能保證收斂到某個(gè)解決方案;
2.K-means無(wú)法指出應(yīng)該使用多少個(gè)類別。在同一數(shù)據(jù)集中,選擇不同的類別得到的結(jié)果是不一樣的,甚至是不合理的;
3.K-means假定空間的協(xié)方差矩陣不會(huì)影響到結(jié)果。
2.3 K-means的改進(jìn)
1.多進(jìn)行幾次聚類,每次初始化的聚類中心不一樣,最后選擇方差最小的那個(gè)結(jié)果;
2.首先將類別設(shè)置為1,然后提高類別數(shù)(到達(dá)某個(gè)上限),一般情況下,總方差會(huì)快速下降直到達(dá)到某個(gè)拐點(diǎn),這意味著再加一個(gè)新的聚類中心也不會(huì)顯著減少總體方差。在拐點(diǎn)處停止,保存此時(shí)的類別數(shù);
3.將數(shù)據(jù)乘以逆協(xié)方差矩陣進(jìn)行數(shù)據(jù)的歸一化。
3.算法實(shí)現(xiàn)
3.1獲取樣本
基本思路:利用隨機(jī)數(shù)RNG函數(shù)算子對(duì)矩陣進(jìn)行填充,這里采用了正態(tài)分布生成點(diǎn)集。
實(shí)現(xiàn)代碼:
//定義實(shí)驗(yàn)允許的最大類別數(shù)const int MAX_CLUSTERS = 5;//定義數(shù)據(jù)點(diǎn)的顏色Scalar colorTab[] = { Scalar(0,0,255),Scalar(0,255,0),Scalar(255,100,100),Scalar(255,0,255),Scalar(0,255,255)};//基于均勻分布生成隨機(jī)的K值和樣本數(shù)量RNG rng(12345);int k=rng.uniform(2, MAX_CLUSTERS);int sampleCount = rng.uniform(100,1000);Mat points(sampleCount, 1, CV_32FC2);Mat lables;Mat centers(k,1,CV_32FC1);Mat img(500, 500,CV_8UC3);//基于初始化的K值和sampleCount生成點(diǎn)集for (int i = 0; i < k; i++){//指定ROIMat pointChunk = points.rowRange(i*sampleCount/k,i==k-1?sampleCount:(i+1)*sampleCount/k);//基于正態(tài)分布填充ROIrng.fill(pointChunk,RNG::NORMAL,Scalar(rng.uniform(0,img.cols),rng.uniform(0,img.rows)),Scalar(img.cols*0.05, img.rows*0.05));}//打亂點(diǎn)的生成順序randShuffle(points,1,&rng);3.2 協(xié)方差逆陣平方根的計(jì)算方法
傳統(tǒng)意義上,馬氏距離是以該點(diǎn)在特定的方向上的方差來(lái)度量數(shù)據(jù)點(diǎn)與分布之間的距離。我們使用分布的協(xié)方差的倒數(shù)來(lái)計(jì)算馬氏距離:
其中, 表示數(shù)學(xué)期望,馬氏距離可表示為:
對(duì)此有以下兩種方式來(lái)解決:在K-means算法中使用馬氏距離而不是歐式距離,或?qū)?shù)據(jù)進(jìn)行尺度變化,然后在放縮的空間中使用歐幾里得距離。第一種方法更為直觀,但第二種方法更容易計(jì)算,因?yàn)閿?shù)據(jù)轉(zhuǎn)化是線性的。
數(shù)據(jù)集的轉(zhuǎn)化:
在這里,是即將使用的一組新的數(shù)據(jù)向量,D是原始數(shù)據(jù)。的因子是逆協(xié)方差的平方根。
那么如何求解呢?
由于協(xié)方差矩陣是對(duì)稱矩陣,基于特殊矩陣而言采用特征值分解的方法可以更準(zhǔn)確的解出逆矩陣,現(xiàn)在我們假設(shè)已經(jīng)求出,且有:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
由線性代數(shù)的基本理論知道,計(jì)算矩陣的冪的基本思想是對(duì)矩陣進(jìn)行對(duì)角化,即:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
當(dāng)n=2時(shí),只需要對(duì)特征向量計(jì)算平方,隨后反乘特征向量S即可,計(jì)算代碼如下:
//矩陣對(duì)角化計(jì)算A的平方Mat A = (Mat_<float>(4,4)<<0,1,1,-1,1,0,-1,1,1,-1,0,1,-1,1,1,0);Mat value;Mat vector;bool M=eigen(A,value,vector);Mat eigenValueMat= Mat::zeros(Size(value.rows,value.rows),CV_32FC1);value.convertTo(value,CV_32FC1);vector.convertTo(vector,CV_32FC1);for (int i = 0; i < value.rows; i++){eigenValueMat.at<float>(i, i) = pow(value.at<float>(i),2);}Mat eigenVectorMat;transpose(vector, eigenVectorMat);//對(duì)角化方法計(jì)算的解Mat A_1 = eigenVectorMat*eigenValueMat* eigenVectorMat.inv();//理論解Mat A_2 = A*A;//誤差Mat error = A_1 - A_2;最終的誤差矩陣error如圖3.2-1所示:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 圖3.2-1 誤差矩陣
顯然,這個(gè)解是完全可以接受的。
3.3 聚類實(shí)驗(yàn)
3.3.1 一般的K均值聚類方法
在該條件下,對(duì)數(shù)據(jù)的樣本點(diǎn)不加任何歸一化處理,并基于已知的K值來(lái)對(duì)3.1中的樣本進(jìn)行聚類分析,實(shí)現(xiàn)的代碼如下:
//1.一般的均值聚類//1.1 直接調(diào)用聚類函數(shù)kmeans(points,k,lables,TermCriteria(TermCriteria::EPS | TermCriteria::EPS,10,1.0),3,KMEANS_RANDOM_CENTERS,centers);//1.2 繪制聚類結(jié)果for (int i = 0; i < sampleCount; i++){int colorIndex = lables.at<int>(i);Point pt = points.at<Point2f>(i);circle(img,pt,2,colorTab[colorIndex],-1);}聚類的結(jié)果如下圖3.3.1-1所示:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 圖3.3.1-1 一般的均值聚類
3.3.2 基于馬氏距離k-means++的聚類方法的實(shí)現(xiàn)
首先,為了創(chuàng)造馬氏距離聚類的基本條件,在這里為了更好的可視化,數(shù)據(jù)采用二維矢量,但是在x和y兩個(gè)維度上的服從不同的分布,為了使數(shù)據(jù)更具可信度,我參考了《機(jī)器學(xué)習(xí)》(周志華著)原型聚類章節(jié)里面的樣本數(shù)據(jù),如表3.3.2-1:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 表3.3.2-1 西瓜數(shù)據(jù)集
其次,在原型聚類的實(shí)例中,書(shū)中給出的最終的迭代解,如圖3.3.2-1所示:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖3.3.2-1 西瓜數(shù)據(jù)集均值聚類的結(jié)果
因此,為了方便進(jìn)行數(shù)據(jù)實(shí)驗(yàn),不妨設(shè)置聚類數(shù)目為k=3,實(shí)驗(yàn)的代碼如下:
//2.基于馬氏距離的k-means++聚類//定義實(shí)驗(yàn)允許的最大類別數(shù)const int MAX_CLUSTERS = 5;//定義數(shù)據(jù)點(diǎn)的顏色Scalar colorTab[] = { Scalar(0,0,255),Scalar(0,255,0),Scalar(255,100,100),Scalar(255,0,255),Scalar(0,255,255) };//設(shè)置基本參數(shù),k=3RNG rng(12345);int k = 3;Mat lables;Mat centers(k, 1, CV_32FC1);Mat img(500, 500, CV_8UC3, Scalar(0));Mat re_points = (Mat_<float>(30, 2) << 0.697,0.460,0.774,0.376,0.634,0.264,0.608,0.318,0.556,0.215,0.403,0.237,0.481,0.149,0.437,0.211,0.666,0.091,0.243,0.267,0.245,0.057,0.343,0.099,0.639,0.161,0.657,0.198,0.360,0.370,0.593,0.042,0.719,0.103,0.359,0.188,0.339,0.241,0.282,0.257,0.748,0.232,0.714,0.346,0.483,0.312,0.478,0.437,0.525,0.369,0.751,0.489,0.532,0.472,0.473,0.376,0.725,0.445,0.446,0.459);//求解協(xié)方差矩陣Mat covar;Mat mean;calcCovarMatrix(re_points, covar,mean,CV_COVAR_NORMAL | CV_COVAR_ROWS);//求解協(xié)方差的逆陣的方根Mat covar_inv;double inv=invert(covar,covar_inv,DECOMP_EIG);Mat value;Mat vector;bool M = eigen(covar_inv, value, vector);Mat eigenValueMat = Mat::zeros(Size(value.rows, value.rows), CV_32FC1);value.convertTo(value,CV_32FC1);vector.convertTo(vector, CV_32FC1);for (int i = 0; i < value.rows; i++){float tem = sqrt(value.at<float>(i, 0));eigenValueMat.at<float>(i, i) = tem;}Mat eigenVectorMat;transpose(vector, eigenVectorMat);Mat result = eigenVectorMat*eigenValueMat* eigenVectorMat.inv();//基于馬氏距離進(jìn)行歸一化,重新生成點(diǎn)集Mat New_points = re_points*result;//聚類kmeans(New_points, k, lables, TermCriteria(TermCriteria::EPS | TermCriteria::EPS, 10, 1.0), 3, KMEANS_PP_CENTERS, centers);for (int i = 0; i < 30; i++){int colorIndex = lables.at<int>(i);int x = re_points.at<float>(i, 0) * 500;int y= 500-re_points.at<float>(i, 1) * 500;Point pt = Point(x,y);circle(img, pt, 2, colorTab[colorIndex], -1);}最后,我想說(shuō)的是k-means++與k-means方法最大的不同點(diǎn)在于中心的初始化方法,因?yàn)閷?duì)于不同的初始點(diǎn),聚類的結(jié)果必然會(huì)有差異,如果初始點(diǎn)選擇的不好,那么極有可能陷入局部最小值下,從而得不到好的分類結(jié)果,而cv::KMEANS_PP_CENTERS選項(xiàng)會(huì)使cv::kmeans使用文獻(xiàn)"Arthur, David, and S. Vassilvitskii. "k-means++: the advantages of careful seeding"中所謂的kmeans++的方法來(lái)重新分配聚類中心。這種方法謹(jǐn)慎的選擇了聚類的中心起點(diǎn),通常能以少于默認(rèn)方法的迭代得出更好的結(jié)果。
上述代碼的結(jié)果如圖3.3.2-2所示:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖3.3.2-2 基于馬氏距離的kmeans++聚類結(jié)果
3.3.3 基于肘部法則的K-means++聚類
? ? ? ? 如果問(wèn)題中沒(méi)有指定的值,可以通過(guò)肘部法則這一技術(shù)來(lái)估計(jì)聚類數(shù)量。肘部法則會(huì)把不同值的成本函數(shù)值畫(huà)出來(lái)。隨著值的增大,平均畸變程度會(huì)減小;每個(gè)類包含的樣本數(shù)會(huì)減少,于是樣本離其重心會(huì)更近。但是,隨著值繼續(xù)增大,平均畸變程度的改善效果會(huì)不斷減低。值增大過(guò)程中,畸變程度的改善效果下降幅度最大的位置對(duì)應(yīng)的值就是肘部。
在這里,我將畸變程度定義為所有類的樣本點(diǎn)距該類中心的方差和。
考慮k從k=2到k=5逐步進(jìn)行迭代,求解產(chǎn)生的畸變系數(shù)的程序如下:
//肘部法則的聚類//定義實(shí)驗(yàn)允許的最大類別數(shù)const int MAX_CLUSTERS = 5;//定義數(shù)據(jù)點(diǎn)的顏色Scalar colorTab[] = { Scalar(0,0,255),Scalar(0,255,0),Scalar(255,100,100),Scalar(255,0,255),Scalar(0,255,255) };//設(shè)置基本參數(shù)RNG rng(12345);int k;Mat lables;Mat img(500, 500, CV_8UC3, Scalar(0));Mat points = (Mat_<float>(30, 2) << 0.697, 0.460, 0.774, 0.376,0.634, 0.264, 0.608, 0.318, 0.556,0.215, 0.403, 0.237, 0.481, 0.149, 0.437, 0.211, 0.666, 0.091, 0.243, 0.267, 0.245, 0.057, 0.343, 0.099,0.639, 0.161, 0.657, 0.198, 0.360, 0.370, 0.593, 0.042,0.719, 0.103, 0.359, 0.188, 0.339, 0.241, 0.282,0.257, 0.748, 0.232, 0.714, 0.346, 0.483, 0.312, 0.478,0.437, 0.525, 0.369, 0.751, 0.489, 0.532, 0.472,0.473, 0.376, 0.725, 0.445, 0.446, 0.459);//定義方差Mat varMat(5, 1, CV_32FC1, Scalar(0));for (int k = 2; k <= MAX_CLUSTERS; k++){Mat centers(k, 1, CV_32FC1);kmeans(points, k, lables, TermCriteria(TermCriteria::EPS | TermCriteria::EPS, 10, 1.0), 3, KMEANS_PP_CENTERS, centers);vector<float> sumVar(k, 0);//統(tǒng)計(jì)每類點(diǎn)的數(shù)量Mat lableCount(k, 1, lables.type(), Scalar(0));for (int i = 0; i < 30; i++){lableCount.at<int>(lables.at<int>(i)) += 1;}//計(jì)算方差for (int i = 0; i < 30; i++){int index = lables.at<int>(i);float x = points.at<float>(i, 0);float y = points.at<float>(i, 1);Point2f center = Point2f(centers.at<float>(index, 0), centers.at<float>(index, 1));sumVar[index] += ((x - center.x)*(x - center.x) + (y - center.y)*(y - center.y)) / lableCount.at<int>(index);}for (auto m : sumVar){varMat.at<float>(k - 2, 0) += m;}}//數(shù)據(jù)歸一化[0,500]normalize(varMat,varMat,0,400,NORM_MINMAX);//繪圖vector<Point> pts;for (int i = 0; i < varMat.rows; i++){Point tem;tem.x = i*400/4+50;tem.y = 450 - varMat.at<float>(i);pts.push_back(tem);}for (int i = 0; i < pts.size()-1;i++){circle(img,pts[i],3,colorTab[i],-1);}line(img,pts[0],pts[1],Scalar(255,255,255));line(img, pts[1], pts[2], Scalar(255, 255, 255));line(img, pts[2], pts[3], Scalar(255, 255, 255));最終的結(jié)果如圖3.3.3-1所示:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖3.3.3-1 基于肘部法則確定拐點(diǎn)
很顯然,拐點(diǎn)發(fā)生在k=3的地方,因此最佳的聚類結(jié)果為k=3;
4.相關(guān)資料
1.OpenCV隨機(jī)數(shù)發(fā)生器RNG:
《學(xué)習(xí)OpenCV3》:Page 157-161
2.對(duì)小矩陣使用逗號(hào)分隔式初始化函數(shù):
《OpenCV編程入門》:Page 91
3.矩陣對(duì)角化理論、矩陣對(duì)角化Matlab實(shí)現(xiàn):
https://blog.csdn.net/qq_18343569/article/details/49823441
https://blog.csdn.net/compression/article/details/49180775
4.聚類算法的一些思考:
https://blog.csdn.net/u013719780/article/details/51755124?utm_source=blogxgwz2
https://www.jianshu.com/p/95a4bcff2198
https://www.cnblogs.com/data-miner/p/6288227.html
5.原型聚類的基本理論:
《機(jī)器學(xué)習(xí)》-周志華:Page 202-211
6.維基百科:歐式距離與馬氏距離
https://en.wikipedia.org/wiki/Euclidean_distance
https://en.wikipedia.org/wiki/Mahalanobis_distance
?
?
總結(jié)
以上是生活随笔為你收集整理的K均值聚类的理解和实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【项目】区块链+人工智能 ---PAI白
- 下一篇: 漫画 | 揭密微信诞生记之民间传说