日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

k均值聚类算法优缺点_Grasshopper实现K均值聚类算法

發(fā)布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 k均值聚类算法优缺点_Grasshopper实现K均值聚类算法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文很長很長,有很多很多圖,包含以下部分:

1.算法簡介

2.如何分類平面點

3.如何分類空間點

4.如何分類多維數(shù)據(jù)

5.后記

提醒:以下內(nèi)容包括:智障操作,無中生友,重復造輪子 等

1.算法簡介

k均值聚類算法(k-means),這東西是什么意思?

k均值聚類算法(k-means clustering algorithm)是一種迭代求解的聚類分析算法,其步驟是隨機選取K個對象作為初始的聚類中心,然后計算每個對象與各個種子聚類中心之間的距離,把每個對象分配給距離它最近的聚類中心。聚類中心以及分配給它們的對象就代表一個聚類。每分配一個樣本,聚類的聚類中心會根據(jù)聚類中現(xiàn)有的對象被重新計算。這個過程將不斷重復直到滿足某個終止條件。終止條件可以是沒有(或最小數(shù)目)對象被重新分配給不同的聚類,沒有(或最小數(shù)目)聚類中心再發(fā)生變化,誤差平方和局部最小。——百度百科

我用人話解釋一下:

假如你有一些平面上的點,大概如下圖。你想把它們分組,離得近的點分到同一組去,離得遠的分到不同的組。

你估摸了一下,大概知道要分9組,別的限制條件一概不知,這時候就非常適合用這種簡單粗暴的方法。

方法是這樣的:

1.在這些點的范圍內(nèi),隨機取9個點,取名為“聚類中心”。注意,是隨機的,想怎么取就怎么取。

2.對每一個點,計算它到9個聚類中心的位置,找到最近的聚類中心,并將其劃分到那一組中

很明顯,分組的情況相當糟糕,畢竟聚類中心是隨機的嘛。

3.對每一個組內(nèi)的點,求出平均點,并將其作為新的聚類中心,在下圖中,綠色點是新的聚類中心。

4.重復2、3的步驟,直到分組情況不再變化

這就是k均值聚類算法的平面應(yīng)用方式,接下來介紹在grasshopper里如何實現(xiàn)它。

2.如何分類平面點

首先畫一些點,拾取進grasshopper中;求出這些點的bounding box,以此為邊界,使用populate 3d/2d生成9個點作為聚類中心。

以聚類中心為起始點,生成泰森多邊形,泰森多邊形內(nèi)的點就是被分到該組的點。使用Point In Curve搭配 Cull Pattern實現(xiàn)這一步

(當然,可以計算距離然后排序,這兩種方法是等效的。只不過在平面的情況下,這里選擇了更直觀的方法)

使用average,求出各組平均點。

使用插件anemone,根據(jù)上文所述,在Populate 3D后設(shè)立循環(huán)起點,在average后設(shè)立循環(huán)終點,并讓控制循環(huán)的兩個電池對應(yīng),設(shè)立最大循環(huán)次數(shù)。

OK,完美!我們的“平面kmeans.gh”正式完成!

望著簡單優(yōu)雅的電池圖和靈巧變動的迭代動畫,電腦前的你獲得了前所未有的滿足感。

然而,你很快發(fā)現(xiàn)這個電池并不完美。

首先它沒有顯示結(jié)果。雖然分組完畢,但是并不直觀。

你拖出了Convex Hull,解決了這一問題。

顯示分組結(jié)果之后你馬上發(fā)現(xiàn),即便是迭代了十余次,分組結(jié)果已經(jīng)穩(wěn)定,這個結(jié)果還是不能讓你滿意。

首先,本來是要分9組的,現(xiàn)在它只有8組,;而且右邊有兩組緊挨著的點,憑什么他們不能分到一組去?

原因在于初始聚類中心上。因為它是隨機的,所以可能有一個聚類中心和所有點都距離很遠,沒有點在它那一組,導致它成了光桿司令。

因為第一次分組它就沒有組員,所以以后也不再會有,最終導致結(jié)果少了一組。

同理,兩個聚類中心之間存在一大批點,最終會導致兩個中心勢均力敵,平分這些點。

要解決這些問題,只能調(diào)整隨機的種子,直到結(jié)果令人滿意。

解決了分組問題,你隱隱約約覺得還有哪里不對勁,沒錯,就是循環(huán)的部分。

現(xiàn)在,運算結(jié)果會不停迭代直至最大次數(shù),這就面臨著“最大迭代次數(shù)設(shè)置為多少是合適的”的問題。太大,浪費資源;太小,分組情況不穩(wěn)定。一般來說,人們習慣性地設(shè)為100,當然這只是權(quán)宜之計,略有強迫癥的你決定做出可以終止迭代的部分。

根據(jù)算法定義,當分組情況不變時,停止迭代。

Loop End電池的exit端等于TRUE時,停止迭代。

也就是說,比較一下本次運算和上次運算時的分組情況,如果相同,則輸出true到exit端。

“分組情況”是什么?

是每一組內(nèi)點的數(shù)量(列表長度)。把這些數(shù)據(jù)轉(zhuǎn)換成一個數(shù)據(jù),而且還能避免誤判的一個最簡便的方式,就是Construct Path。

這樣,“分組情況”就能被一行唯一的文字代表,只要用match text把它和上一次迭代時的文字比較就行了。

但是可惜,anemone沒有查看迭代過程中的上次數(shù)據(jù)的功能,(如果有,請教教我)只能自己做了。如下圖:

這一部分是什么意思呢?

Data Recorder記錄所有通過的數(shù)據(jù)。

List Item列出本次和上次迭代的文字。

Replace Nulls是為了用隨便什么別的文字替換掉null。因為如果Data Recorder記錄的數(shù)據(jù)不足兩個,list item的-1端會和i端一致,使得循環(huán)結(jié)束,所以必須將wrap設(shè)為false;這樣就導致-1端會變成null,所以必須將它替換掉。

最后就是match text,當兩輸入端一致時輸出true,搞定。

最終成果如下

OK,完美!我們的“平面kmeans改.gh”正式完成!

望著簡單粗暴的電池圖和完全自動的迭代過程,電腦前的你獲得了前所未有的滿足感。

隨著鼠標的一陣抖動,整個電池圖索然無味。

處于賢者時間的你不禁想到,這個方法可以拓展到3維空間里嗎?


3.如何分類空間點

靈巧的雙手穿針引線,類比的思維高速運轉(zhuǎn)——頃刻,能夠處理空間點的電池組橫空出世,它在算法上完全繼承了“平面kmeans改.gh”的衣缽:

但是,麻煩也如期而至——會建立曲面的Voronoi 3D 和求交集的Point In Brep兩個電池大大拖慢了運算速度。在平面情況下,這種方法的劣勢還不明顯,現(xiàn)在則已經(jīng)成為必須要解決的問題了。

所以只能根據(jù)定義中的計算方式來分組了。

首先調(diào)整數(shù)據(jù)結(jié)構(gòu),計算點到聚類中心的距離,依照距離將聚類中心排序

可見,現(xiàn)在有1295個點,23個聚類中心,每一條路徑都代表著一個點,路徑內(nèi)的23個點依照距離從小到大排列。

重點來了。現(xiàn)在提取每一條路徑中的第一個數(shù)據(jù)——那是距離某一個特定點最近的聚類中心。

現(xiàn)在有1295條路徑,也就是每一個點都從23個聚類中心里面,找到了一個距離它最近的。

之后將它flatten,使用Create Set、Member Index和List Item素質(zhì)三連,就得到了分好組的點。

這套連招究竟做了什么?是什么原理?

看一下flatten后的數(shù)據(jù)。有1295個點物件,他們是1295個點各自對應(yīng)的最近的聚類中心。

目標是:將要處理的點分組,對應(yīng)同一個聚類中心的點處在相同路徑下。

很明顯,圖中有很多的重復點,使用Create Set得到一個沒有重復點的集合,該集合有23個點物件,正是那23個聚類中心。

Member Index的功能是:對于某個列表中的數(shù)據(jù),返回它在這個列表中的索引。輸入23個獨特的聚類中心,輸出這23個聚類中心在原列表中的索引。在原列表中,每個聚類中心都重復了很多次,所以,索引的數(shù)目一共1295個。

既然有了索引,只需要用List Item將數(shù)據(jù)取出來就好了,只不過這次輸入的列表要是待處理的點

費了老鼻子勁,終于得到了分好組的點,接下來只要照搬原先寫好的電池就行了。

最終結(jié)果如下:

OK,完美!我們的“空間kmeans.gh”正式完成!

望著精準高效的電池圖和高端酷炫的迭代過程,電腦前的你獲得了前所未有的滿足感。

隨著鼠標的一陣抖動,整個電池圖索然無味。

處于賢者時間的你不禁想到,平面點由xy坐標確定,凡是有兩個屬性的數(shù)據(jù)(比如某人的身高和體重)就可以用唯一的平面點來代表;同理,有三個屬性的數(shù)據(jù)(比如某人的三圍)就可以用唯一的空間點來代表。

而你剛剛做出了可以給這些點自動分類的算法,雖然不知道有什么用——

但是電腦前的你還是獲得了前所未有的滿足感。

不過你很快就意識到,現(xiàn)實中的數(shù)據(jù)基本上都有三個及以上的屬性,如果不將算法拓展到n維空間,也就無法處理這些數(shù)據(jù),算法的能力將大大減弱——而且這個算法本來就不局限于三維空間坐標。

但是由于grasshopper自身的限制,它不支持多維空間中的點和向量。

即便如此,你還是在想:到底能不能拓展到n維空間中呢?

4.如何分類多維數(shù)據(jù)

幸運的是,grasshopper在關(guān)閉一扇門的同時,也打開了一扇窗——

矩陣

雖然grasshopper不支持n維向量,但是可以用1行n列的矩陣來代替。通過把多維空間中的點轉(zhuǎn)化成矩陣,你看到了希望。

很快,麻煩來了:

由于人不能理解多維空間,數(shù)據(jù)的可視化就成了一個大難題。不過可以通過在空間點上附加額外的屬性來表示多維點——比如在空間點上畫球,用球的半徑代表第四維數(shù)據(jù)

空間點上畫立方體,用立方體的長寬高代表第四、五、六維數(shù)據(jù)

此外,生成隨機點的部分也不再多維點中適用,只能手動求出各維度數(shù)據(jù)區(qū)間,生成隨機數(shù)再合成一個多維點。下圖是 生成隨機矩陣和將多維點轉(zhuǎn)化為矩陣的部分。

由于矩陣不是幾何物件,不能用Distance計算距離,若要求矩陣所代表的多維點的歐氏距離,則需要手動計算。而且矩陣本身又自帶一層數(shù)據(jù)結(jié)構(gòu),處理起來相當麻煩。下圖是計算距離的部分。

其他部分都和三維kmeans相似。

不知過了多長時間,重啟了多少次grasshopper,數(shù)據(jù)結(jié)構(gòu)出錯多少次,終于,電池運行成功了。

在最終結(jié)果如下:

稍加改動,就可以直接從Excel中導入數(shù)據(jù)并計算了。

OK,完美!我們的“多維kmeans.gh”正式完成!

5.后記

望著并不復雜的電池圖和前途無量的算法,電腦前的你獲得了前所未有的滿足感。

隨著鼠標的一陣抖動,整個電池圖索然無味。

處于賢者時間的你不禁想到,整個過程可以寫成文章發(fā)到知乎上,或許能幫到別人。

在碼字之前,你覺得,也許應(yīng)該問問之前是否有人做過類似的事情,通過對比學習,一定大有收獲。

受群友的指引,你下載了owl和最新版的Lunchbox

https://www.food4rhino.com/app/owl

https://provingground.io/tools/lunchbox/download-lunchbox-for-grasshopper/

打開插件的一瞬間,空氣凝固了

你倚在陽臺上,晚風試圖把你從無奈中解救出來。

效果并不怎樣。用grasshopper久了,就連月亮都看起來有兩個輸入端。

“如果我的腦袋是一個電池的話,輸出端一定是水。”你抱著這樣的想法坐回電腦前。

你沒有放棄寫知乎,只不過,在羞恥和自嘲的慫恿下,文章用的是第二人稱的視角。

文件下載:https://pan.baidu.com/s/1PYaVuVw7dIViXYVeLk0kTQ

提取碼:75u1

需要lunchbox(讀取Excel)

需要meshedit(建立三維點分組預覽)

總結(jié)

以上是生活随笔為你收集整理的k均值聚类算法优缺点_Grasshopper实现K均值聚类算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。