社区发现算法——Louvain 算法
Louvain 算法
原始論文為:《Fast unfolding of communities in large networks》。
所以又被稱為Fast unfolding算法。
Louvain算法是一種基于模塊度的社區(qū)發(fā)現(xiàn)算法。其基本思想是網(wǎng)絡(luò)中節(jié)點(diǎn)嘗試遍歷所有鄰居的社區(qū)標(biāo)簽,并選擇最大化模塊度增量的社區(qū)標(biāo)簽。在最大化模塊度之后,每個社區(qū)看成一個新的節(jié)點(diǎn),重復(fù)直到模塊度不再增大。
首先復(fù)習(xí)下模塊度:
這里引入了權(quán)重方便擴(kuò)展到有權(quán)圖,但其實(shí)對于無權(quán)圖,可以看做所有邊權(quán)重為1,這時候就等于用節(jié)點(diǎn)的度計(jì)算,用度理解一樣。
算法詳述:
模塊度優(yōu)化階段:每個節(jié)點(diǎn)將自己作為自己社區(qū)標(biāo)簽。每個節(jié)點(diǎn)遍歷自己的所有鄰居節(jié)點(diǎn),嘗試將自己的社區(qū)標(biāo)簽更新成鄰居節(jié)點(diǎn)的社區(qū)標(biāo)簽,選擇模塊度增量最大(貪婪思想)的社區(qū)標(biāo)簽,直到所有節(jié)點(diǎn)都不能通過改變社區(qū)標(biāo)簽來增加模塊度。
也就是說,首先將每個節(jié)點(diǎn)指定到唯一的一個社區(qū),然后按順序?qū)⒐?jié)點(diǎn)在這些社區(qū)間進(jìn)行移動。怎么移動呢?假設(shè)有一節(jié)點(diǎn) i ,它有三個鄰居節(jié)點(diǎn) j1, j2, j3,我們分別嘗試將節(jié)點(diǎn) i 移動到 j1, j2, j3 所在的社區(qū),并計(jì)算相應(yīng)的 modularity 變化值ΔQ,哪個變化值最大就將節(jié)點(diǎn) i 移動到相應(yīng)的社區(qū)中去(當(dāng)然,這里我們要求最大的 modularity 變化值要為正,如果變化值均為負(fù),則節(jié)點(diǎn) i 保持不動)。按照這個方法反復(fù)迭代,直到網(wǎng)絡(luò)中任何節(jié)點(diǎn)的移動都不能再改善總的 modularity 值為止。
移動到一個社區(qū)C中所獲得的模塊化Q增益可以很容易地計(jì)算出來:
=12m(ki,in?Σtotkim)\frac{1}{2m}(k_{i,in}-{Σ_{tot}ki\over m})2m1?(ki,in??mΣtot?ki?)
其中ΣinΣ_{in}Σin?是在社區(qū)C內(nèi)的鏈路的權(quán)重總和(權(quán)重為1時就等于度數(shù)),如果是初始情況,即一個節(jié)點(diǎn)作為一個社區(qū)時,它就為這個節(jié)點(diǎn)自己到自己的連接,這時候仍然需要起點(diǎn)加weight,終點(diǎn)加weight(即使這個時候起點(diǎn)和終點(diǎn)為同一節(jié)點(diǎn),對于無環(huán)圖權(quán)為0)
ΣtotΣ_{tot}Σtot?是關(guān)聯(lián)到C中的節(jié)點(diǎn)的鏈路上的權(quán)重的總和
ki是關(guān)聯(lián)到節(jié)點(diǎn)i的鏈路的權(quán)重的總和
ki,in是從節(jié)點(diǎn)i連接到C中的節(jié)點(diǎn)的鏈路的總和
m是網(wǎng)絡(luò)中的所有鏈路的權(quán)重的總和
網(wǎng)絡(luò)凝聚階段:每個社區(qū)合并為一個新的超級節(jié)點(diǎn),超級節(jié)點(diǎn)的邊權(quán)重為原始社區(qū)內(nèi)所有節(jié)點(diǎn)的邊權(quán)重之和,形成一個新的網(wǎng)絡(luò)。
將第一個階段得到的社區(qū)視為新的“節(jié)點(diǎn)”(一個社區(qū)對應(yīng)一個),重新構(gòu)造子圖,兩個新“節(jié)點(diǎn)”之間邊的權(quán)值為相應(yīng)兩個社區(qū)之間各邊的權(quán)值的總和。如這個圖所示,如果第一個階段得到的社區(qū)有以下三個,那么第二個階段的任務(wù)就是將這三個社分別看一個新的節(jié)點(diǎn),然后將任意兩個新節(jié)點(diǎn)之間的所有連線的權(quán)重相加得到的和,作為這兩個新節(jié)點(diǎn)之間的連線的權(quán)重。
上述兩個階段迭代進(jìn)行,直到模塊度不再增大。
??下圖很好的描述了這兩個階段。第一次迭代,經(jīng)過模塊度優(yōu)化階段,總的 modularity 值不再改變,算法將16個節(jié)點(diǎn)劃分成4個社區(qū);在網(wǎng)絡(luò)凝聚階段,4個社區(qū)被凝聚成4個超級節(jié)點(diǎn),并重新更新了邊權(quán)重。之后就進(jìn)入第二次迭代中。
算法通過引入分步迭代的思想(類比EM算法),避免陷入貪婪思想導(dǎo)致的局部最優(yōu)。
算法流程:
1、初始時將每個頂點(diǎn)當(dāng)作一個社區(qū),社區(qū)個數(shù)與頂點(diǎn)個數(shù)相同。
2、依次將每個頂點(diǎn)與之相鄰頂點(diǎn)合并在一起,計(jì)算它們最大的模塊度增益是否大于0,如果大于0,就將該結(jié)點(diǎn)放入模塊度增量最大的相鄰結(jié)點(diǎn)所在社區(qū)。
3、迭代第二步,直至算法穩(wěn)定,即所有頂點(diǎn)所屬社區(qū)不再變化。
4、將各個社區(qū)所有節(jié)點(diǎn)壓縮成為一個結(jié)點(diǎn),社區(qū)內(nèi)點(diǎn)的權(quán)重轉(zhuǎn)化為新結(jié)點(diǎn)環(huán)的權(quán)重,社區(qū)間權(quán)重轉(zhuǎn)化為新結(jié)點(diǎn)邊的權(quán)重。
5、重復(fù)步驟1-3,直至算法穩(wěn)定。
可以看到Louvain 算法與FN算法非常相似,我覺得最大的不同時Louvain 算法在凝聚階段是將整個社區(qū)看做一個新的超節(jié)點(diǎn)來看,而FN算法是以社區(qū)的觀點(diǎn)來凝聚。
算法優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
1、時間復(fù)雜度低,適合大規(guī)模的網(wǎng)絡(luò)。
??2、社區(qū)劃分結(jié)果穩(wěn)定,有具體指標(biāo)能夠評估社區(qū)劃分好壞。
??3、消除了模塊化分辨率的限制。由于模塊度是全局指標(biāo),最大化的時候很難發(fā)現(xiàn)小型的社區(qū),很容易將小型社區(qū)合并。而算法第一次迭代是以單個節(jié)點(diǎn)作為社區(qū)的粒度,規(guī)避了這種問題。
??4、天然自帶層次化的社區(qū)劃分結(jié)果,每一次迭代的社區(qū)劃分結(jié)果都可以保留下來,作為社區(qū)劃分的中間結(jié)果,可供選擇。
缺點(diǎn)
1、社區(qū)過大,不能及時收斂。如果我們將模塊度類比為損失函數(shù)的話,Fast Unfolding在模塊度優(yōu)化階段采用的貪婪思想很容易將整個社區(qū)劃分“過擬合”。因?yàn)镕ast Unfolding是針對點(diǎn)遍歷,很容易將一些外圍的點(diǎn)加入到原本緊湊的社區(qū)中,導(dǎo)致一些錯誤的合并。這種劃分有時候在局部視角是優(yōu)的,但是全局視角下會變成劣的。
??
??Python代碼如下:代碼與數(shù)據(jù)下載
參考結(jié)果如下:
社區(qū) 1 [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 16, 17, 19, 21]
社區(qū) 2 [32, 33, 8, 14, 15, 18, 20, 22, 26, 29, 30]
社區(qū) 3 [23, 24, 25, 27, 28, 31]
0.388560157790927
算法執(zhí)行時間0.002000093460083008
總結(jié)
以上是生活随笔為你收集整理的社区发现算法——Louvain 算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSV出力ボタンラッパー(asp.net
- 下一篇: POJ 3608 Bridge Acro