點雲K Means聚類演算法

2021-10-05 16:00:46 字數 4393 閱讀 8769

因為是老師的作業,所以最近就研究了一下k-means演算法,也就做一下關於這個演算法的筆記。

在諸多的聚類方法中,k-means聚類方法是屬於「基於原型的聚類」(也稱為原型聚類)的方法,此類方法均是假設聚類結構能通過一組原型刻畫,在現實聚類中極為常用。通常情況下,該類演算法會先對原型進行初始化,然後再對原型進行迭代更新求解。採用不同的原型表示、不同的求解方式,也將會產生不同的演算法。

k-means演算法作為一種經典的「原型聚類」演算法,其原型選擇的是「k個聚類中心」,迭代求解的方式是以相鄰兩次求解的「質心」(同一類所有的點的x,y,z座標的平均值)變化程度而進行的,這也可能就是k-means聚類名字的由來:k個聚類中心+質心(座標平均值)。

過程其實相對簡單:

1、初始化原型,也就是指定k值和k個聚類中心。這其中聚類中心的指定可以人為的輸入、也可以隨機選擇或者其他方式都可以,不過盡量保證聚類中心之間的距離不要選的太近。

2、聚類。遍歷所有資料點,計算每個資料點到這k個聚類中心的距離(我這裡選擇的是歐式距離,也可以選擇馬氏距離或者其他距離),將每個資料點分配給距離該點最近的聚類中心所屬的類別,直到最後乙個資料點。

3、更新聚類中心。也就是計算每一類的質心,並將本次計算出的聚類中心與上一次的聚類中心進行比較,如果所有的聚類中心都沒有變化,則停止;如果有所變化,則將本次的聚類中心作為新的聚類中心,重複上述的2、3過程,直到所有的聚類中心都沒有變化時停止該過程。

原始資料圖:

**如下:

main.cpp:

#include

"kmeans.h"

#include

#include

#include

using

namespace kmeans;

intmain()

std::stof(vec[1]), std::stof(vec[2]));

std::stringstream words

(line)

; words >> x;

//可以通過這種方式來提取出相應的字串數值,不用使用分割函式

words >> y;

words >> z;

/*x = static_cast(atof(_x.c_str()));

y = static_cast(-atof(_z.c_str()));

z = static_cast(atof(_y.c_str()));*/

pointcloud.

emplace_back

(x,y,z);}

input.

close()

; kmeans<

float

>

k_mean(2

,pointcloud)

; std::vector<:vector>> cluster = k_mean.

getclusterpoint()

; std::ofstream output;

for(

int i =

0; i < cluster.

size()

; i++

) output.

close()

;}std::cout <<

"執行成功!"

<< std::endl;

system

("pause");

return0;

}

point3.h:

#ifndef point3

#define point3

#include

namespace kmeans

~point3()

point3 operator-(

const point3& other)

point3 operator+(

const point3& other)

t getsquareddistanceto

(const point3& other)

private:}

;}#endif

// !point3

pointdatasource.h:

#ifndef pointdatasource

#define pointdatasource

#include

"point3.h"

namespace kmeans

pointdatasource

(const std::vector>

& points)

:m_ptr

(&points[0]

),m_count

(points.

size()

)pointdatasource()

:m_ptr

(nullptr),

m_count(0

) pointdatasource&

operator=(

const pointdatasource& other)

=default;~

pointdatasource()

size_t size()

const

const point3

&operator

(size_t index)

const

const point3

*begin()

const

const point3

*end()

const

private

:const point3

* m_ptr;

//點的指標

size_t m_count;};

}#endif

// !pointdatasource

kmeans.h:

#ifndef kmeans

#define kmeans

#include

#include

"point3.h"

#include

"pointdatasource.h"

namespace kmeans

return point3

(x / clusterpoints.

size()

, y / clusterpoints.

size()

, z / clusterpoints.

size()

);}public

:kmeans()

=default

;kmeans

(int k,

const std::vector>

& pointcloud):k

(k),

pointcloud

(pointcloud)

~kmeans()

std::vector<:vector>>

getclusterpoint()

std::vector> clustercenter,oldclustercenter;

clustercenter.

resize

(k);

for(

int i =

0; i < k; i++

)//迭代迴圈進行聚類運算

while

(true)}

cluster[maxdistindex]

.push_back

(i);

}//更新各個聚類簇的中心點

oldclustercenter = clustercenter;

int unupdateflag =0;

for(

int i =

0; i < k; i++)}

//判斷聚類中心是否均未更新

if(unupdateflag == k)

//清除所有聚類簇中的資料

for(

int i =

0; i < k; i++)}

return cluster;}}

;}#endif

處理效果:

從處理效果圖可以看出,k-means演算法可以很好的將在距離上有著明顯差異的地物進行聚類識別,但是該演算法也會對雜訊進行聚類。所以如果資料量很大,那麼在使用該方法時可以先進行簡單的去噪處理,這樣可以降低k-means演算法進行聚類時的計算量。

K Means聚類演算法

k means聚類演算法 intergret kmeans演算法的基本思想是初始隨機給定k個簇中心,按照最鄰近原則把待分類樣本點分到各個簇。然後按平均法重新計算各個簇的質心,從而確定新的簇心。一直迭代,直到簇心的移動距離小於某個給定的值。k means聚類演算法主要分為三個步驟 1 第一步是為待聚類...

聚類演算法 K means

演算法接受引數 k 然後將事先輸入的n個資料物件劃分為 k個聚類以便使得所獲得的聚類滿足 同一聚類中的物件相似度較高 而不同聚類中的物件相似度較小。聚類相似度是利用各聚類中物件的均值所獲得乙個 中心物件 引力中心 來進行計算的。k means演算法是最為經典的基於劃分的聚類方法,是十大經典資料探勘演...

k means聚類演算法

說到聚類,得跟分類區別開來,分類是按人為給定的標準將樣本歸到某個類別中去,在機器學習中多是監督學習,也就是訓練樣本要給標籤 正確的類別資訊 而聚類是在某種規則下自動將樣本歸類,在機器學習中是無監督學習,不需要提前給樣本打標籤。k means聚類演算法,就是在某種度量方式下,將樣本自動劃分到k個類別中...