日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

凝聚式层次聚类 java_凝聚法层次聚类之ward linkage method

發(fā)布時(shí)間:2025/3/15 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 凝聚式层次聚类 java_凝聚法层次聚类之ward linkage method 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

凝聚法分層聚類(lèi)中有一堆方法可以用來(lái)算兩點(diǎn)(pair)之間的距離:歐式,歐式平方,manhattan等,還有一堆方法可以算類(lèi)(cluster)與類(lèi)之間的距離,什么single-linkage、complete-linkage、還有這個(gè)ward linkage。(即最短最長(zhǎng)平均,離差平方和)

其他的好像都挺好理解,就是最后這個(gè)有點(diǎn)麻煩。。。

這個(gè)方法說(shuō)白了叫離差平方和(這是個(gè)啥?)。是ward寫(xiě)那篇文章時(shí)候舉的一個(gè)特例。這篇文章是說(shuō)分層凝聚聚類(lèi)方法的一個(gè)通用流程。在選擇合并類(lèi)與類(lèi)時(shí)基于一個(gè)object function optimise value,這個(gè)object function可以是任何反應(yīng)研究目的的方程,所以許多標(biāo)準(zhǔn)的方法也被歸入了。為了闡明這個(gè)過(guò)程,ward舉了一個(gè)例子,用的object function 是error sum of squares(ESS),這個(gè)例子就成為ward's method。

找了N多資料,終于把這個(gè)算法的過(guò)程搞清楚了。首先輸入的是一個(gè)距離矩陣,知道每?jī)蓚€(gè)點(diǎn)之間的距離。然后初始化是每個(gè)點(diǎn)做為一個(gè)cluster,假設(shè)總共N組,此時(shí)每個(gè)組內(nèi)的ESS都是0,ESS的公式,如下(從原稿《Hierarchical Grouping To Optimize An Objective Function》上摘的):

我當(dāng)時(shí)還有點(diǎn)蒙ESS是個(gè)啥?——我現(xiàn)在知道了,凡是蒙的都是概率沒(méi)學(xué)好(我是說(shuō)我)……先從wiki上轉(zhuǎn)個(gè)公式過(guò)來(lái):

這是方差的公式,寫(xiě)的再通俗點(diǎn),就是:

等號(hào)兩邊同時(shí)乘上n,好了,你應(yīng)該知道ESS是啥了——ESS就是【方差×n】!so easy了~~

但是等下——這看起來(lái)是個(gè)一維的公式啊——因?yàn)槟阋呀?jīng)知道ESS是【方差×n】了,那多維的還不會(huì)算嗎?先求所有點(diǎn)的均值點(diǎn)

,然后再算所有點(diǎn)到這個(gè)均值點(diǎn)(central)的距離(距離公式你得自己定,見(jiàn)開(kāi)頭,但是最后算出來(lái)就是一個(gè)數(shù)),然后把所有距離平方后加起來(lái)(此時(shí)即為方差乘上n),就得到ESS了。

說(shuō)了半天光說(shuō)ESS了,列位看官,人只有一張嘴,故ESS此處按下不表,接著說(shuō)ward method。ward method是要求每次合并后ESS的增量最小,這怎么講呢?還是上圖吧(圖是從youtube上的一個(gè)教程里截的):

只看最下面ward's method的兩個(gè)圖好了,先看下面的圖,合并前紅色組和黃色組分別能算各自的ESS,總的ESS是什么呢?很簡(jiǎn)單,加起來(lái)就好了,即:

ESS(總-合并前)=ESS(紅)+ESS(黃)+ESS(其他沒(méi)畫(huà)出來(lái)的組)

如果合并這兩個(gè)組,則可以作為一個(gè)新組再算一個(gè)ESS,此時(shí)

ESS(總-合并后)=ESS(紅黃)+ESS(其他沒(méi)畫(huà)出來(lái)的組)

你注意這里還沒(méi)有真的合并,只是算了一下合并紅黃兩組的“成本”(即:ESS(總-合并后)-ESS(總-合并前),當(dāng)然這個(gè)成本肯定是增加的),如果總共有N個(gè)組,必須把每?jī)蓚€(gè)組合并的成本都算一遍,也就是算N×(N-1)/2個(gè)數(shù)出來(lái),然后找里面合并后成本最小的兩組合并。然后再重復(fù)這個(gè)過(guò)程。

我說(shuō)清楚了吧!?

嗯,至于畫(huà)的那個(gè)樹(shù)狀圖的高度,可以認(rèn)為是上面說(shuō)的這個(gè)“成本”。

對(duì)了,還得說(shuō)一下這個(gè)公式:

啥意思呢,就是說(shuō),如果用ward's method來(lái)度量?jī)蓚€(gè)cluster之間的距離,那么兩個(gè)cluster之間的距離就是把這兩個(gè)cluster合并后新cluster的ESS,其中x就表示合并前兩個(gè)cluster中所有點(diǎn),而

就是合并后那個(gè)新cluster的中心點(diǎn)(均值點(diǎn)),

就表示每個(gè)點(diǎn)x到中心點(diǎn)的距離,平方后加起來(lái),就是ESS了。

好了,總結(jié)一下,ward's method是凝聚法分層聚類(lèi)中一種度量cluster之間距離的方法。按照這個(gè)方法,任意兩個(gè)cluster之間的距離就是這兩個(gè)cluster合并后新cluster的ESS

摘要: ward linkage method是什么不介紹了,只說(shuō)下怎么算,有一個(gè)快速的計(jì)算方法叫Lance-Williams Algorithm可以大大簡(jiǎn)化ward method的計(jì)算

ward's method是分層聚類(lèi)凝聚法的一種常見(jiàn)的度量cluster之間距離的方法,其基本過(guò)程是這樣的(參考:http://blog.sciencenet.cn/blog-2827057-921772.html?)

計(jì)算每個(gè)cluster的ESS

計(jì)算總的ESS

枚舉所有二項(xiàng)cluster【N個(gè)cluster是N*(N-1)/2個(gè)二項(xiàng)集】,計(jì)算合并這兩個(gè)cluster后的總ESS值

選擇總ESS值增長(zhǎng)最小的那兩個(gè)cluster合并

重復(fù)以上過(guò)程直到N減少到1

這個(gè)方法其實(shí)效率比較低,特別是算cluster的ESS值還要先求均值點(diǎn),然后算距離的平方再求和,不過(guò)有一個(gè)快速的計(jì)算方法叫Lance-Williams Algorithm可以大大簡(jiǎn)化ward method的計(jì)算。先來(lái)一個(gè)圖(來(lái)源:https://www.youtube.com/watch?v=aXsaFNVzzfI

然后你其實(shí)可以發(fā)現(xiàn),這個(gè)算法簡(jiǎn)化的是合并后更新ESS的那部分過(guò)程,比如有ABCDE五個(gè)cluster,合并了AB,那么后面要更新CDE到這個(gè)AB的距離,怎么算?ESS唄——平方和——好復(fù)雜!

那用這個(gè)新算法怎么算?答,新算法可以不用ESS的公式計(jì)算ESS,直接套用上面那個(gè)公式(注意最后絕對(duì)值里面應(yīng)該一個(gè)i一個(gè)j,他寫(xiě)錯(cuò)了)。初始的ESS由兩點(diǎn)之間的距離決定——所以就是說(shuō)完全不需要算ESS了!

好了,試著寫(xiě)一下算法:輸入是一個(gè)距離矩陣,輸出是一個(gè)合并序列[(cluster1id, cluster2id, distance), ...]

clusterDistance=dict() #存放cluster之間的距離,形如'1-2':3表示cluster1與cluster2之間的距離為3

clusterMap=dict() #存放cluster的情況,形如'1':4表示cluster1里面有4個(gè)元素(樣本)

clusterCount=0 #每合并一次生成新的序號(hào)來(lái)命名cluster

defward_linkage_method(distance_matrix):

N=len(distance_matrix)

clusterCount=N-1

for i in range(0,N-1):

for j in range(i,N):

name=getName(i,j)

clusterDistance[name]=distance_matrix[i][j]

for k in range(0,N):

clusterMap[k]=1

while True:

# 查找距離最短的兩個(gè)cluster

# clusterDistance里面有冗余(即合并后之前的距離仍在,

# 所以循環(huán)以clusterMap為準(zhǔn),這個(gè)里面沒(méi)有冗余。

tmp=max(clusterDistance.values())

clusterList = clusterMap.keys()

clusterListLength=len(clusterList)

for iii in range(0, clusterListLength-1):

for jjj in range(iii+1, clusterListLength):

name=getName(clusterList[iii], clusterList[jjj])

if tmp > clusterDistance[name]:

i=iii

j=jjj

tmp=clusterDistance[name]

ni=clusterMap[i] # 第i個(gè)cluster內(nèi)的元素?cái)?shù)

nj=clusterMap[j]

del clusterMap[i] # 刪掉原來(lái)的cluster

del clusterMap[j]

clusterCount+=1 # 新增新的cluster

clusterMap[clusterCount]=ni+nj #新cluster的元素?cái)?shù)是之前的總和

print i,j,'->',clusterCount,tmp # 輸出合并信息:i,j合并為clusterCount,合并高度(距離)為tmp

if len(clusterMap)==1:break # 合并到只剩一個(gè)集合為止,然后退出

# 更新沒(méi)合并的cluster到新合并后的cluster的距離

for k in clusterMap.keys():

if k==clusterCount:continue

else: # 計(jì)算新的距離

nk=clusterMap[k]

alpha_i=(ni+nk)/(ni+nj+nk)

alpha_j=(nj+nk)/(ni+nj+nk)

beta= -nk/(ni+nj+nk)

newDistance = alpha_i * clusterDistance[getName(i,k)]

newDistance += alpha_j * clusterDistance[getName(j,k)]

newDistance += beta * clusterDistance[getName(i,j)]

# 把新的距離加入距離集合

clusterDistance[getName(clusterCount,k,'.')]=newDistance

defgetName(i,j):

t=[i,j]

t.sort()

return t[0]+'-'+t[1]

當(dāng)然了,這段代碼只是一個(gè)示意,可以改進(jìn)的地方還很多。

轉(zhuǎn)載本文請(qǐng)聯(lián)系原作者獲取授權(quán),同時(shí)請(qǐng)注明本文來(lái)自宋景和科學(xué)網(wǎng)博客。

鏈接地址:http://blog.sciencenet.cn/blog-2827057-921772.html

總結(jié)

以上是生活随笔為你收集整理的凝聚式层次聚类 java_凝聚法层次聚类之ward linkage method的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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