--- tags: Data Mining 2022 Fall --- # Data Mining Project 3 Link Analysis Report<br>Fall 2022 @ NCKU > Source code & test data are available from my GitHub <br>https://github.com/cpt1020/Data-Mining-Project3 ## PART 1. Find a Way to Increase Hub, Authority, and PageRank of Node 1 in the First 3 Graphs ### <u>1.1 Graph 1</u> 由於Authority的計算是將Parent的Hub加總,而Hub的計算方式是將Children的Authority加總,而PageRank跟連進來的In-Degree有關。所以為了增加Node 1的Authority、Hub、以及PageRank,我採用的方法是將Node 1都連到每一個Node,且每個Node也都會連到Node 1 (如Figure 2),結果如Table 1和Table 2所示。 <p align=center><center> <img src="https://i.imgur.com/yPKB3CZ.png" width="800" alt></center> </p> <p><center> Figure 2. 左圖為 Graph 1,右圖為新加 Edge (橘色 Edge)後的圖</center> </p> <p><center> Table 1. Graph 1 的 Authority、Hub、以及 PageRank</center> </p> <div align="center"> | | Node 1 |Node 2 | Node 3|Node 4|Node 5| Node 6| | :-: | :-: | :-: | :-: | :-: | :-: | :-: | | $Authority$| 0| 0.2|0.2|0.2|0.2|0.2| |$Hub$|0.2|0.2|0.2|0.2|0.2|0| |$PageRank$|0.025272|0.059760|0.106825|0.171058|0.258725|0.378361| </div> <p><center> Table 2. 更改後的 Graph 1的 Authority、Hub、以及 PageRank </center> </p> | | Node 1 |Node 2 | Node 3|Node 4|Node 5| Node 6| | :-: | :-: | :-: | :-: | :-: | :-: | :-: | |$Authority$|<font color=#FF6600>0.269592</font>|0.099509|0.157725|0.157725|0.157725|0.157725| |$Hub$ |<font color=#FF6600>0.269592</font>|0.157725|0.157725|0.157725|0.157725|0.099509| |$PageRank$ |<font color=#FF6600>0.367730</font>|0.082858|0.120144|0.136923|0.144473|0.147871| 結果與討論: - 從 Table 2 可看到,Node 1 的 Authority、Hub、以及 PageRank 都有上升。 - Authority 會增加是因為 Node 1 的 Parent 數量增加了,得到的 Parent 的 Hub 的加總也因此增加。 - Hub 會增加也是因為 Children 增加,所以 Children 的 Authority 的加總也增加了。 - 而 Node 1 的 In-Degree 最高,導致 PageRank 的傳遞大部分最後都會流到 Node 1,所以 Node 1 的 PageRank 最高。 ### <u>1.2 Graph 2</u> 我用同樣的方法處理 Graph 2,讓 Node 1 連到全部的 Node,且全部的 Node 也都連 到 Node 1 (如 Figure 3),結果如 Table 3 和 Table 4 所示。 <p align=center><center> <img src="https://i.imgur.com/StI35DO.png" width="800" alt></center> </p> <p><center> Figure 3. 左圖為 Graph 2,右圖為新加 Edge (橘色 Edge)後的圖</center> </p> <p><center> Table 3. Graph 2 的 Authority、Hub、以及 PageRank</center> </p> <div align="center"> | | Node 1 |Node 2 | Node 3|Node 4|Node 5| | :-: | :-: | :-: | :-: | :-: | :-: | | $Authority$| 0.2| 0.2|0.2|0.2|0.2| |$Hub$|0.2|0.2|0.2|0.2|0.2| |$PageRank$|0.2|0.2|0.2|0.2|0.2| </div> <p><center> Table 4. 更改後的 Graph 2 的 Authority、Hub、以及 PageRank </center> </p> <center> | | Node 1 |Node 2 | Node 3|Node 4|Node 5| | :-: | :-: | :-: | :-: | :-: | :-: | |$Authority$|<font color=#FF6600>0.288974</font>|0.117446|0.197860|0.197860|0.197860| |$Hub$ |<font color=#FF6600>0.288974</font>|0.197860|0.197860|0.197860|0.117446| |$PageRank$ |<font color=#FF6600>0.381397</font>|0.105814|0.153431|0.174858|0.184500| </center> 結果與討論: - 從 Table 3 和 Table 4 可以看到,用這個方法同樣也可以讓 Node 1 的 Authority、 Hub、以及 PageRank 上升,且是全部的 Node 中最高的。 ### <u>1.3 Graph 3</u> Graph 3 也用前面的方法處理,如 Figure 4,結果則如 Table 5 和 Table 6 所示。 <p align=center><center> <img src="https://i.imgur.com/idDKoxb.png" width="600" alt></center> </p> <p><center> Figure 4. 左圖為 Graph 3,右圖為新加 Edge (橘色 Edge)後的圖</center> </p> <p><center> Table 5. Graph 3 的 Authority、Hub、以及 PageRank</center> </p> | | Node 1 |Node 2 | Node 3|Node 4| | :-: | :-: | :-: | :-: | :-: | | $Authority$|0.190983|0.309017|0.309017|0.190983| |$Hub$|0.190983|0.309017|0.309017|0.190983| |$PageRank$|0.172414|0.327586|0.327586|0.172414| <p><center> Table 6. 更改後的 Graph 3的 Authority、Hub、以及 PageRank </center> </p> | | Node 1 |Node 2 | Node 3|Node 4| | :-: | :-: | :-: | :-: | :-: | |$Authority$|<font color=#FF6600>0.280776</font>|0.219224|0.280776|0.219224| |$Hub$ |<font color=#FF6600>0.280776</font>|0.219224|0.280776|0.219224| |$PageRank$ |<font color=#FF6600>0.296875</font>|0.203125|0.296875|0.203125| 結果與討論: - 從 Table 5 和 Table 6 的結果可以看到,這個方法同樣可以提升 Node 1 的 Authority、 Hub、和 PageRank。 - 此外,也可以看到由於 Node 1 和 Node 3 的 In-Degree 和 Out-Degree 都相同,所 以這兩個 Node 的 Authority、Hub、以及 PageRank 都相同。Node 2 和 Node 4 也 是如此。 ## PART 2. Algorithm Description ### <u>2.1 HITS</u> HITS演算法主要是藉由不停更新每個網頁的Authority和Hub,最後會達到收斂,這演算法也就結束。計算Authority,必須要知道有多少跟Query有關的網頁連到我目前的這個網頁;Hub則是我目前的網頁,有連到多少跟這個Query有關的網頁。實際的Authority和Hub計算方式如下: $$ Authority(v) = \sum_{w\ \in\ parent(v)} Hub(w) $$ $$ Hub(v) = \sum_{w\ \in \ children(v)} Authority(w) $$ 從公式可以看到,某一個Vertex v的Authority,是來自於他的Parent的Hub的加總;Hub則是Vertex v連出去的Children的Authority的加總。 <u>以下是我的程式碼說明</u>: 假設已經將Graph的Adjacency Matrix建立起來,並儲存在`adj_matrix`這個變數,而`vertex_size`則是紀錄總共有多少Vertex。 首先,將每個Vertex的Authority和Hub都初始化成1: ```python! # 初始化hub和authority,初始值都設為1 hub = [1 for x in range(vertex_size)] authority = [1 for x in range(vertex_size)] ``` 再來則是進入while迴圈,不停更新每個Vertex的Authority和Hub,直到達到設定的終止條件,詳細說明如程式碼中的註解: ```python! iteration = 1 while True: # 將前一個iteration計算得到的hub和authority先copy一份 prev_hub = hub.copy() prev_authority = authority.copy() # 產生adj_matrix的transpose transpose = [[adj_matrix[j][i] for j in range(len(adj_matrix))] for i in range(len(adj_matrix[0]))] # 用前一個iteration的hub來計算authority authority = np.dot(transpose, prev_hub) authority = authority.astype(float) # 用前一個iteration的authority來計算hub hub = np.dot(adj_matrix, prev_authority) hub = hub.astype(float) # 記得要做Normalization,這樣才會收斂 authority = one_norm(authority, vertex_size) hub = one_norm(hub, vertex_size) # 計算前一輪跟後一輪的差值 diff = 0 for i in range(vertex_size): diff += abs(authority[i] - prev_authority[i]) diff += abs(hub[i] - prev_hub[i]) # 判斷是否達到iteration上限,或前一輪與後一輪差值是否達到設定的收斂門檻epsilon # 若達到上限或門檻,則演算法結束 if diff < epsilon or iteration > max_iteration: break else: iteration += 1 ``` ### <u>2.2 PageRank</u> PageRank公式: $$ PageRank(V_i) = \frac{d}{n} + (1-d) \times \sum_{l_{j,i}\in E} \frac {PageRank(P_j)}{Outdegree(P_j)} $$ $$ \displaylines{ d:\ damping \ factor\\ n:\ number\ of\ vertex} $$ PageRank演算法,根據公式,就是將每個Vertex的Parent的PageRank除以該Parent的Children數量(也就是該Parent的Out-degree),將每個Parent的加總起來,即為該Vertex的PageRank。另外,為了避免Rank Sink Problem (詳細內容後面會說明),多加了Damping Factor,讓每一個Vertex,他是有一定的機率是隨機到達該Vertex,也有一定的機率是從該Vertex的Parent到達該Vertex。 <u>以下是我的程式碼說明</u>: 首先,將每個Vertex的PageRank都初始化成1/(vertex_size): ```python! # 先初始化每個vertex的PageRank為(1/vertex_size) page_rank = [(1/vertex_size) for x in range(vertex_size)] ``` 將每個Vertex的Out-degree記錄起來,方便後面使用: ```python! # 記錄每個vertex的out-degree outdegree_list = [] for i in range(vertex_size): sum = 0 for j in range(vertex_size): sum += adj_matrix[i][j] outdegree_list.append(sum) ``` 將每個Vertex的Parent記錄起來,方便後面使用: ```python! # 記錄每個node的parent有誰 parent_list = [] for i in range(vertex_size): # 開始尋找node i的parent有誰 parent = [] for j in range(vertex_size): if adj_matrix[j][i] == 1: # 若有node i的parent,就把它存進parent parent.append(j) if len(parent) == 0: # 若該node沒有parent,則存[-1] parent_list.append([-1]) else: parent_list.append(parent) ``` 進入while迴圈,每一個Iteration都會將每一個Vertex的每個PageRank都更新一次,詳細說明如程式碼中的註解: ```python! iteration = 1 while True: # 先將前一個iteration的PageRank copy一份 prev_page_rank = page_rank.copy() for i in range(vertex_size): # 先來更新第i個node的page rank new_page_rank_sum = 0 # 尋找第i個node的parent for j in parent_list[i]: if j != -1: # 若i的parent j不等於-1,就代表node i有parent # 將parent前一個iteration的PageRank除以他的outdegree # 並加入new_page_rank_sum new_page_rank_sum += (prev_page_rank[j]/outdegree_list[j]) # 帶入公式更新node i的PageRank page_rank[i] = ((damping_factor/vertex_size) + (1-damping_factor) * new_page_rank_sum) # 每回合都要將PageRank做正規化 page_rank = one_norm(page_rank, vertex_size) # 僅依照max iterattion決定是否break if iteration >= max_iteration: break else: iteration += 1 ``` ### <u>2.3 SimRank</u> SimRank公式: $$ S(a,\ b)= \frac{C}{\mid{I(a)}\mid\mid{I(b)}\mid}\sum_{i=1}^{\mid{I(a)}\mid} \sum_{j=1}^{\mid{I(b)}\mid} S(I_i(a),\ I_j(b)) $$ $$ \displaylines{ S(a,\ b): similarity\ of\ node\ a\ and\ node\ b \\ C: decay\ factor \\ {I(a)}: parent\ of\ node\ a } $$ SimRank主要是計算兩個Vertex,a和b,他們之間的相似度 S(a,b)。S(a,b)的計算方式是將a和b的Parent,兩兩將其Parent的相似度加總起來,除以a和b的Parent數量的相乘,再乘上Decay Factor C。 <p align=center><center> <img src="https://i.imgur.com/CR4HoCw.png" width="400" alt></center> </p> <p><center> Figure5. SimRank說明範例</center> </p> 以Figure 5做說明,假設要計算$S(3,5)$: - 3的Parent有兩個,分別是1和2 - 5的Parent有兩個,分別也是1和2 - 接下來要兩兩將其Parent的相似度加總起來: 所以要將$S(1,1)$、$S(1,2)$、$S(2,1)$、以及$S(2,2)$加總起來 - 由於自己跟自己的相似度是1,所以$S(1,1)=S(2,2)=1$ - 由於目前在第一個Iteration,所以$S(1,2)=S(2,1)=0$ - 所以$S(3,5)$經由第一個Iteration計算得到的結果就是: $$ S(3, 5)=decay\ factor \times \frac{1+1+0+0}{2\times2}=decay\ factor\times\frac{2}{4} $$ 再以$S(4,5)$為例: - 4的Parent有3 - 5的Parent有1和2 - 將4和5的Parent的相似度加總起來: 由於是第一個Iteration,所以 $S(3,1)+S(3,2)=0+0=0$ - 所以$S(4,5)$經由第一個Iteration計算得到的結果就是: $$ S(4, 5)=decay\ factor \times \frac{0}{1\times2}=0 $$ 第一個Iteration將每個Vertex跟每個Vertex的Similarity都算完後,就再進入第二個Iteration做計算,直到達到設定的max_iteration,或收斂為止。 <u>以下是我的程式碼說明</u>: 先宣告一個大小為vertex_size × vertex_size的矩陣Sim來記錄Similarity,並將每一格都初始化成0: ```python! # 先初始化sim sim = [[0 for x in range(vertex_size)] for y in range(vertex_size)] ``` 由於每個Vertex對自己的Similarity是1,因此先將Sim的對角線都初始化成1: ```python! # 將sim的對角線初始化成1 (∵ Sim(i,i)=1) for i in range(vertex_size): sim[i][i] = 1 ``` 將每個Vertex有多少In-Neighbor、以及有哪些In-Neighbor記錄下來,方便後面使用: ```python! # 記錄每個點的in-neighbor數量 in_neighbors_num = [] for i in range(vertex_size): sum = 0 for j in range(vertex_size): sum += adj_matrix[j][i] in_neighbors_num.append(sum) # 記錄每個點的in-neighbor有誰 in_neighbor = [] for i in range(vertex_size): parent = [] for j in range(vertex_size): if adj_matrix[j][i] == 1: parent.append(j) in_neighbor.append(parent) ``` 接下來進入while迴圈執行SimRank,詳細說明如程式碼中的註解: ```python3! iteration = 1 while True: # 先將當前的Sim copy一份儲存在last_sim last_sim = [] for list in sim: copy = list.copy() last_sim.append(copy) for i in range(vertex_size): for j in range(vertex_size): if i != j: sim_sum = 0 if in_neighbors_num[i] != 0 and in_neighbors_num[j] != 0: # 若i有parent,j也有parent for k in in_neighbor[i]: # i的parent k for l in in_neighbor[j]: # j的parent l # 將上一輪計算得到的Sim(k,l)加總起來 sim_sum += last_sim[k][l] # 帶入公式更新Sim(i,j) sim[i][j] = (decay_factor / (in_neighbors_num[i] * in_neighbors_num[j])) * sim_sum else: # 對角線的值都是1(∵ Sim(i,i)=1) sim[i][j] = 1 # 依據max iteration決定是否break if iteration >= max_iteration: break else: iteration += 1 ``` ## PART 3. Result Analysis and Discussion 以下Graph 1-4的結果皆為在參數max_iteration 30 (每個演算法都總共執行30個Iterations)、Decay Factor 0.7、Damping Factor 0.1所執行的結果。 ### <u>3.1 Graph 1</u> <p align=center><center> <img src="https://i.imgur.com/DCIH259.png" width="400" alt></center> </p> <p><center> Figure 6. Graph 1示意圖</center> </p> <p><center> Table 7. Graph 1執行HITS和PageRank的結果</center> </p> | | Node 1 |Node 2 | Node 3|Node 4|Node 5| Node 6| | :-: | :-: | :-: | :-: | :-: | :-: | :-: | | $Authority$| 0| 0.2|0.2|0.2|0.2|0.2| |$Hub$|0.2|0.2|0.2|0.2|0.2|0| |$PageRank$|0.025272|0.059760|0.106825|0.171058|0.258725|0.378361| <p><center> Table 8. Graph 1執行SimRank的結果</center> </p> | | Node 1 |Node 2 | Node 3|Node 4|Node 5| Node 6| | :-: | :-: | :-: | :-: | :-: | :-: | :-: | |Node 1|1|0|0|0|0|0| |Node 2|0|1|0|0|0|0| |Node 3|0|0|1|0|0|0| |Node 4|0|0|0|1|0|0| |Node 5|0|0|0|0|1|0| |Node 6|0|0|0|0|0|1| HIT - 由於 Authority 的計算方式是將 Parent 的 Hub 加總,由於 Node 1 沒有 Parent, 所以 Node 1 的 Authority 就是 0。 - 同理,由於 Hub 的計算方式是將 Children 的 Authority 加總,由於 Node 6 沒有 Children,所以 Node 6 的 Hub 是 0。 - 除了 Node 1 和 6,其他 Node 的 In-Degree 和 Out-Degree 都是 1,所以其他 Node 的 Authority 和 Hub 都是 1/5 = 0.2。 PageRank - 由於 Graph 1 的 Edge 全部串在一起剛好是一個從 Node 1 連到 Node 6 的 Edge, 所以 PageRank 的傳遞會從 Node 1 傳遞到 Node 6,最後累積在 Node 6。所以可 以看到從 Node 1 到 Node 6,PageRank 呈現遞增的結果。 SimRank - 由於 Graph 1 的 Node 彼此間都沒有共同的 Parent,不同 Node 之間的 Similarity 不管怎麼計算都會是 0,所以最終的結果是個 Identity Matrix。 ### <u>3.2 Graph 2</u> <p align=center><center> <img src="https://i.imgur.com/b33TM26.png" width="400" alt></center> </p> <p><center> Figure 7. Graph 2示意圖</center> </p> <p><center> Table 9. Graph 2執行HITS和PageRank的結果</center> </p> | | Node 1 |Node 2 | Node 3|Node 4|Node 5| | :-: | :-: | :-: | :-: | :-: | :-: | |$Authority$|0.2|0.2|0.2|0.2|0.2| |$Hub$ |0.2|0.2|0.2|0.2|0.2| |$PageRank$ |0.2|0.2|0.2|0.2|0.2| <p><center> Table 10. Graph 1執行SimRank的結果</center> </p> | | Node 1 |Node 2 | Node 3|Node 4|Node 5| | :-: | :-: | :-: | :-: | :-: | :-: | |Node 1|1|0|0|0|0| |Node 2|0|1|0|0|0| |Node 3|0|0|1|0|0| |Node 4|0|0|0|1|0| |Node 5|0|0|0|0|1| HITS - 由於 Graph 2 是一個環狀,且每個 Node 的 In-Degree 和 Out-Degree 都是 1,所 以可以看到每個 Node 的 Authority 和 Hub 都是 1/Node 總數。 PageRank - 由於 Graph 2 是一個環狀,PageRank 不會像 Graph 1 最後都累積在某一個 Node, 而是會平均分散在每個 Node,所以每個 Node 的 PageRank 也是 1/Node 總數。 SimRank - 由於 Graph 2 的這 5 個 Node,彼此都沒有共同的 Parent,所以不同的 Node 的 Similarity 都是 0,僅有 Sim(i, i)是 1。 ### <u>3.3 Graph 3</u> <p align=center><center> <img src="https://i.imgur.com/L3Y7zKr.png" width="300" alt></center> </p> <p><center> Figure 8. Graph 3示意圖</center> </p> <p><center> Table 11. Graph 3執行HITS和PageRank的結果</center> </p> | | Node 1 |Node 2 | Node 3|Node 4| | :-: | :-: | :-: | :-: | :-: | |$Authority$|0.190983|0.309017|0.309017|0.190983| |$Hub$ |0.190983|0.309017|0.309017|0.190983| |$PageRank$ |0.172414|0.327586|0.327586|0.172414| <p><center> Table 12. Graph 3執行SimRank的結果</center> </p> | | Node 1 |Node 2 | Node 3|Node 4| | :-: | :-: | :-: | :-: | :-: | |Node 1|1|0|0.538462|0| |Node 2|0|1|0|0.538462| |Node 3|0.538462|0|1|0| |Node 4|0|0.538462|0|1| HITS - 可以看到由於 Node 2 和 3 的 In-Degree 和 Out-Degree 都是 2,Node 1 和 4 的 In- Degree 和 Out-Degree 都是 1,所以 Node 2 和 3 的 Hub 和 Authority 都相同,且 都大於 Node 1 和 4。 PageRank - 由於 Node 2 和 3 的 In-Degree 都是 2,大於 Node 1 和 4 的 In-Degree,所以 PageRank 在傳遞的過程中,會逐漸累積在 Node 2 和 3,所以這兩個 Node 的 PageRank 大於 Node 1 和 4。 SimRank - 由於 Node 1 和 3 有共同的 Parent,Node 2,所以 $𝑆𝑖𝑚(1,3)$ 和$𝑆𝑖𝑚(3,1)$出現了非0的結果,且 $𝑆𝑖𝑚(1,3) = 𝑆𝑖𝑚(3,1)$ 。 - 同理,由於 Node 2 和 Node 4 有共同的 Parent,Node 3,所以 $𝑆𝑖𝑚(2,4)$ 和$𝑆𝑖𝑚(4,2)$ 相等且非 0。 - 最後,由於 Node 2 和 3 的 In-Degree 和 Out-Degree 相等,且 Node 1 和 4 的 In-Degree和Out-Degree相等,所以$𝑆𝑖𝑚(1,3)= 𝑆𝑖𝑚(3,1)= 𝑆𝑖𝑚(2,4)=𝑆𝑖𝑚(4,2)$。 ### <u>3.4 Graph 4</u> <p align=center><center> <img src="https://i.imgur.com/MjKHAGy.png" width="400" alt></center> </p> <p><center> Figure 9. Graph 4示意圖</center> </p> <p><center> Table 13. Graph 4執行HITS和PageRank的結果</center> </p> | | Node 1 |Node 2 | Node 3|Node 4|Node 5|Node 6|Node 7| | :-: | :-: | :-: | :-: | :-: | :-: | :-: |:-:| |$Authority$|0.139484|0.177912|0.200823|0.140178|0.201425|0.056089|0.084088| |$Hub$ |0.275453|0.047762|0.108683|0.198660|0.183735|0.116735|0.068972| |$PageRank$ |0.288012|0.161041|0.139420|0.107246|0.182749|0.055404|0.066128| <p><center> Table 14. Graph 4執行SimRank的結果</center> </p> | | Node 1 |Node 2 | Node 3|Node 4|Node 5|Node 6|Node 7| | :-: | :-: | :-: | :-: | :-: | :-: | :-: |:-:| |Node 1|1|0.243|0.232|0.239|0.221|0.303|0.175| |Node 2|0.243|1|0.294|0.256|0.295|0.17|0.343| |Node 3|0.232|0.294|1|0.34|0.275|0.339|0.341| |Node 4|0.239|0.256|0.34|1|0.23|0.427|0.427| |Node 5|0.221|0.295|0.275|0.23|1|0.159|0.3| |Node 6|0.303|0.17|0.339|0.427|0.159|1|0.155| |Node 7|0.175|0.343|0.341|0.427|0.3|0.155|1| <p><center> Table 15. 每個 Node 的 Parent、Children、以及排序資訊</center> </p> |Node|Parent|Children|Authority Ranking|Hub Ranking|PageRank Ranking| |:-:|:-:|:-:|:-:|:-:|:-:| |1|2, 3, 5, 6|2, 3, 4, 5, 7|5|1|1| |2|1, 3, 4|1|3|7|3| |3|1, 4, 5|1, 2|2|5|4| |4|1, 5|2, 3, 5|4|2|5| |5|1, 4, 6, 7|1, 3, 4, 6|1|3|2| |6|5|1, 5|7|4|7| |7|1|5|6|6|6| HITS - 可以看到 Node 1 雖然 Parent 數量很高,但推薦 Node 1 的是 Node 2、3、5、6, 但這幾個都不算是很好的推薦者(Hub 都不高),所以 Authority 排名沒有很好;但 因為 Node 1 幾乎推薦了每一個 Node,所以他的 Hub 排名很高。 - 從 Figure 10 也可以看到,Node 1 和 5 在第一個 Iteration 因為 Parent 數量高,所 以 Authority 最高,但在第二個 Iteration,Node 1 的 Authority 馬上就掉下來。 - Node 5 則因為推薦他的 Node 的 Hub 排名都滿好的,有 Hub 排名的第一、第二、 和第四名,所以他的 Authority 才會排很前面。 - Node 2 因為只有推薦 Node 1,但 Node 1 的 Authority 排名第五,沒有很好,所以才導致 Node 2 變成 Hub 最後一名。 - 從 Figure 10 和 Figure 11 可以看到,Authority 和 Hub 在每一個 Iteration 都是上 下震盪,之後才趨於平穩。會有這現象是因為這一回合的 Authority 是由上一個 Iteration 的 Parent 的 Hub 而來;而這一回合的 Hub 是由上一個 Iteration 的 Children 的 Authority 而來。但這一回合的 Authority/Hub 又會影響到下一回合的 Children/Parent 的 Hub/Authority。所以其實是有兩條路徑在影響這些數字,所 以才會看到每一個 Iteration 會這樣上上下下的現象。 PageRank - 可以看到 PageRank 的排名跟每個 Node 的 Parent 數量有一定相關性,因為 Parent 越多,就代表有越多的 PageRank 會傳遞到這個 Node。 SimRank - 相似度最高的是 𝑆𝑖𝑚(4,6) 和 𝑆𝑖𝑚(4,7),0.427,他們共同的 Parent 分別是 1 或 5。 - 第二高的則是 𝑆𝑖𝑚(3,6),0.339,其共同 Parent 是 5。 - 第三高的則是 𝑆𝑖𝑚(2,7),0.343,其共同 Parent 是 1。 - 第四高的則是 𝑆𝑖𝑚(3,7),0.341,其共同 Parent 是 1。 - 從這幾點可以觀察到,若某個 Node 的 Parent,是另一個 Node 的 Parent 的子集, 那他們的 Similarity 就會很高。此外,若某兩個 Node 的 Parent 的差集數量越小, 那他們的 Similarity 也會越大。 - 若某兩個 Node 的 Parent 的交集是空集合,那他們的 Similarity 就會很低,譬如說 𝑆𝑖𝑚(6,7) = 0.155 和 𝑆𝑖𝑚(6,2) = 0.17。雖然 Node 6 和 Node 2 的 Parent 都沒有交 集,但 Node 2 的 Parent 的 Parent 就有 Node 5,也就是 Node 6 的 Parent,所以 𝑆𝑖𝑚(6,2) 大於 𝑆𝑖𝑚(6,7)。 <p align=center><center> <img src="https://i.imgur.com/UtXsyvo.png" width="600" alt></center> </p> <p><center> Figure 10. Graph 4 每個 Node 的 Authority 變化</center> </p> <p align=center><center> <img src="https://i.imgur.com/4pIMvNZ.png" width="600" alt></center> </p> <p><center> Figure 11. Graph 4 每個 Node 的 Hub 變化</center> </p> ### <u>3.5 Damping Factor</u> 為了要解決 Rank Sink Problem,也就是假如某個 Node 沒有 Parent 而他永遠就都沒 有 Rank;或者是某個 Node 沒有 Children,導致該 Node 無法將 Rank 傳給其他人,因此 用 Damping Factor 來解決這問題。譬如說 Damping Factor 0.1,就代表有 0.1 的機會是 隨機跳到該 Node,0.9 的機會是由該 Node 的 Parent 跳到該 Node。 #### $Experiment\ I$ 測試資料: 由於 Graph 1 的 Node 1 沒有 Parent,Node 7 沒有 Children,因此以 Graph 1 做測試。 實驗條件&步驟: - 測試有 Damping Factor 0.1 以及無 Damping Factor,參數 max_iteration 1000000,收斂門檻 epsilon 1e-10,並以 `numpy.allclose(前一輪 page_rank, 目前 page_rank, atol = epsilon)`來確認是否達到收斂。 - 對 Graph 1 執行 PageRank,並記錄達到收斂的 Iteration。 結果與討論: <p><center> Table 16. 對 Graph 1 執行有或無 Damping Factor 的 PageRank</center> </p> | |Node 1|Node 2|Node 3|Node 4|Node 5|Node 6|Converge Iteration| |:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| |Damping 0.1|0.025272|0.059760|0.106825|0.171058|0.258725|0.378361|7| |No Damping|0|0|0|0|0|0|7| - 從 Table 16 可以看到,沒有使用 Damping Factor 的話,由於 Graph 1 的 Node 1 無 Parent,Node 6 無 Children,導致全部的 Node 的 PageRank 都是 0。 這是因為 Node 1 沒有 Parent,所以 Node 1 不可能得到 PageRank,再加上 Graph 1 的 Edge 全部是一整條單一方向,所以其他的 Node 若要得到 PageRank 只能仰賴 Node 1 傳送的 PageRank,但因 Node 1 沒有 Parent,所以全部 Node 的 PageRank 都是 0。 - 使用 Damping Factor 0.1 之後,每個 Node 都有 0.1 的機會是隨機進入該 Node 的,所以 Node 1 的機率不再是 0。 另外,由於 Node 6 沒有 Children,導致 PageRank 在傳送的過程,大部分都累積 到 Node 6,所以可以看到 PageRank 從 Node 1 到 Node 6 呈現遞增的現象。 #### $Experiment\ II$ 目的: 欲觀察若無 Damping Factor,則對於含有無 Children 的 Node 的 Graph 執行PageRank 會有什麼結果。 測試資料: 將 Graph 1 做修改,如 Figure 12 所示(橘色的 Edge 是新加入的 Edge)。 <p align=center><center> <img src="https://i.imgur.com/jq8RaN2.png" width="400" alt></center> </p> <p><center> Figure 12. 經修改後含有無 Children 的 Node 的 Graph 1</center> </p> 實驗條件&步驟: - 測試有 Damping Factor 0.1 以及無 Damping Factor,參數 max_iteration 1000000,收斂門檻 epsilon 1e-10,並以 `numpy.allclose(前一輪 page_rank, 目前 page_rank, atol = epsilon)`來確認是否達到收斂。 - 對測試資料執行 PageRank,並記錄達到收斂的 Iteration。 <p><center> Table 17. 含有無 Children 的 Node 執行 PageRank 的結果</center> </p> | |Node 1|Node 2|Node 3|Node 4|Node 5|Node 6|Converge Iteration| |:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| |Damping 0.1|0.124|0.163|0.124|0.163|0.197|0.229|29| |No Damping Factor| |epsilon 1e-10|0.083|0.167|0.083|0.167|0.167|0.333|63| |epsilon 1e-20|0.083|0.167|0.083|0.167|0.167|0.333|129| |epsilon 1e-50|0.083|0.167|0.083|0.167|0.167|0.333|329| |epsilon 1e-100|0.083|0.167|0.083|0.167|0.167|0.333|661| - 在有 Damping factor 的情況下,可以看到 PageRank 都是從 Node 1 到 Node 6 呈 現遞增的狀況,PageRank 會累積在編號比較後面的 Node。 - 但若未使用 Damping Factor,且 Graph 中存在無 Children 的 Node 則會得到比較 特別的狀況。從 Table 17 可以看到,只要將收斂的門檻 epsilon 不停調低,達到收 斂的 Iteration 就會不停增加,且不管是設定哪個收斂的門檻,PageRank 的結果都 一樣。這在前面的實驗、或者是有使用 Damping Factor 的狀況都沒有發生過。 - 這狀況是因為若存在無 Children 的 Node,則 Adjacency Matrix 的某一列就都會是 0,這樣就會無解,所以才會看到這個情況。 #### $Experiment\ III$ 目的: 欲觀察若無 Damping Factor,則對存在無 Parent 的 Node 的 Graph 執行 PageRank會有什麼結果。 測試資料: 將 Graph 1 做修改,如 Figure 12 所示(橘色的 Edge 是新加入的 Edge)。 實驗條件&步驟: - 測試有 Damping Factor 0.1 以及無 Damping Factor,參數 max_iteration 1000000,收斂門檻 epsilon 1e-10,並以 `numpy.allclose(前一輪 page_rank, 目前 page_rank, atol = epsilon)`來確認是否達到收斂。 - 對測試資料執行 PageRank,並記錄達到收斂的 Iteration。 <p align=center><center> <img src="https://i.imgur.com/SGMfzYC.png" width="400" alt></center> </p> <p><center> Figure 13. 經修改後含有無 Parent 的 Node 的 Graph 1</center> </p> 結果與討論: <p><center> Table 18. 含有無 Parent 的 Node 執行 PageRank 的結果</center> </p> | |Node 1|Node 2|Node 3|Node 4|Node 5|Node 6|Converge Iteration| |:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| |Damping 0.1|0.017|0.032|0.045|0.057|0.438|0.411|5| |No Damping|0|0|0|0|0.5|0.5|5| - 可以看到在有 Damping Factor 的狀況下,PageRank 都是從 Node 1 到 Node 6 呈 現遞增的狀況,PageRank 會累積在編號比較後面的 Node。 - 在沒有使用 Damping Factor 的狀況下,可以看到 PageRank 集中在最後的兩個 Node。 <p><center> Table 19. 無 Damping Factor 每一輪的執行結果</center> </p> | |Node 1|Node 2|Node 3|Node 4|Node 5|Node 6| |:-:|:-:|:-:|:-:|:-:|:-:|:-:| |Iteration 1|0|0.167|0.167|0.167|0.333|0.167| |Iteration 2|0|0|0.167|0.167|0.333|0.333| |Iteration 3|0|0|0|0.167|0.5|0.333| |Iteration 4|0|0|0|0|0.5|0.5| |Iteration 5|0|0|0|0|0.5|0.5| - 若將無 Damping Factor 在每一個 Iteration 的 PageRank 的變化拿出來看,則可看 到如 Table 19 的變化。 可以看到無 Parent 的 Node,即 Node 1,在第一個 Iteration 其 PageRank 就是 0。所以對於無 Parent 的 Node,若沒有使用 Damping Factor,其 PageRank 就會 是 0。 再來,由於 Figure 13 的特性,PageRank 會從 Node 2 傳到 Node 3、再傳到 Node 4、最後傳到 Node 5 和 Node 6,因為無法再傳出去,所以就在 Node 5 和 6 之間傳遞。 #### $Experiment\ IV$ 目的: 欲測試不同的 Damping Factor,對於多少 Iteration 才會達到收斂是否會有影響。 測試資料: Graph 1-6,以及 ibm-5000。 實驗條件&步驟: - 測試不同 Damping Factor 0.1、0.2、0.3、0.4、0.5、0.6、0.7、0.8、0.9。 - 參數 max_iteration 1000000,收斂門檻 epsilon 1e-10,並以 `numpy.allclose(前 一輪 page_rank, 目前 page_rank, atol = epsilon)`來確認是否達到收斂。 - 對測試資料執行 PageRank,並記錄達到收斂的 Iteration。 結果與討論: - 從 Figure 14 可以看到,基本上隨著 Damping Factor 增加,達到收斂的 Iteration 就會越少。 - 比較特別的是 Graph 2 的結果,不管用哪個 Damping Factor,都是在第一個 Iteration 就達到收斂,這是因為 Graph 2 是一個環狀,所以 PageRank 不管怎麼 傳,每一輪的 PageRank 都會跟前一輪的一樣,所以在第一輪就會達到收斂。 - 從 PageRank 的公式可以知道,當 Damping Factor 越大,就代表「隨機」達到該 Node 的機率就越大、從 Parent 而來的機率就越小、Parent 的影響力也越小,所 以會更快達到收斂。 另外,Table 20 和 Table 21 是 Graph 3 和 Graph 4 分別在 Damping Factor 0.1 和 0.9 達到收斂時的 PageRank。 - 可以看到,當 Damping Factor 越大,每個 Node 的 PageRank 就越平均,差異越 小,這也是因為隨機到達每個 Node 的機會比較大,從 Parent 而來的機會比較小, 所以 Parent 傳遞的 PageRank 的影響力就越小,反而「隨機」這個因素比 Parent 還有影響力,所以最終的 PageRank 會更趨近於 1/(Node 總數)。 <p><center> Table 20. Graph 3 在 Damping Factor 0.1 和 0.9 達到收斂時的 PageRank</center> </p> |Graph 3| Node 1 |Node 2 | Node 3|Node 4| | :-: | :-: | :-: | :-: | :-: | |Damping 0.1|0.172|0.328|0.328|0.172| |Damping 0.9|0.238|0.262|0.262|0.238| <p><center> Table 21. Graph 4 在 Damping Factor 0.1 和 0.9 達到收斂時的 PageRank</center> </p> |Graph 4|Node 1|Node 2|Node 3|Node 4|Node 5|Node 6|Node 7| |:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| |Damping 0.1|0.288|0.161|0.139|0.107|0.183|0.055|0.066| |Damping 0.9|0.16|0.143|0.14|0.136|0.156|0.132|0.132| <p align=center><center> <img src="https://i.imgur.com/dji2Qya.png" width="800" alt></center> </p> <p><center> Figure 14. 不同 Damping Factor 達到收斂的 Iteration</center> </p> ### <u>3.6 Decay Factor</u> #### $Experiment\ V$ 目的: 由 SimRank 的公式可以看到,若 Decay Factor 越小,Similarity 就越小,所以我認為若 Decay Factor 越小,就會越快達到收斂,因為前一輪跟後一輪的差距會比較快變小。 為了證實這個想法,執行以下實驗。 測試資料: Graph 1-6,以及 ibm-5000。 實驗條件&步驟: - 對測試資料執行 SimRank,Decay Factor 0.1、0.2、0.3、0.4、0.5、0.6、0.7、0.8、 0.9。 - max_iteration 100000,收斂門檻 epsilon 1e-10,並以 `numpy.allclose(前一輪 sim_rank, 目前 sim_rank, atol = epsilon)`來確認是否達到收斂,並紀錄不同 Decay Factor 達到收斂的 Iteration,結果如 Figure 15 所示。 結果與討論: <p align=center><center> <img src="https://i.imgur.com/mhNP5II.png" width="800" alt></center> </p> <p><center> Figure 15. 不同 Decay factor 對於達到收斂 iteration 的影響</center> </p> - 可以看到 Graph 3-6,達到收斂的 Iteration 都會隨著 Decay Factor 的增加而增加, 跟原本的猜測一樣。 - 但在 Graph 1, 2、以及 ibm-5000,卻是分別在第 1 個 Iteration 和第 4 個 Iteration 就達到收斂,且不隨著 Decay Factor 的增加而有所變動。 我覺得是因為這幾個 Graph 的 SimRank 都是稀疏矩陣,尤其像 Graph 1 和 2 的 SimRank 是 Identity Matrix,而 ibm-5000 的 SimRank 除了對角線,大部分也都 是 0,僅有少部分非 0。 所以可以看到,對於相似度越低的 Graph (Node 幾乎都沒有共同 Parent),Decay Factor 對這種 Graph 的影響不大、也不太影響他們達到收斂的 Iteration。 接下來,我想看不同 Decay Factor 對於達到收斂的 SimRank 會有什麼影響,因此我 將前述實驗 Graph 3 在 Decay Factor 0.1 和 0.9 最終收斂的 SimRank 列出來,如 Table 22 和 Table 23 所示。 <p><center> Table 22. Graph 3 在 Decay Factor 0.1 達到收斂時的 SimRank</center> </p> | | Node 1 |Node 2 | Node 3|Node 4| | :-: | :-: | :-: | :-: | :-: | |Node 1|1|0|0.052632|0| |Node 2|0|1|0|0.052632| |Node 3|0.052632|0|1|0| |Node 4|0|0.052632|0|1| <p><center> Table 23. Graph 3 在 Decay Factor 0.9 達到收斂時的 SimRank</center> </p> | | Node 1 |Node 2 | Node 3|Node 4| | :-: | :-: | :-: | :-: | :-: | |Node 1|1|0|0.818177|0| |Node 2|0|1|0|0.818177| |Node 3|0.818177|0|1|0| |Node 4|0|0.818177|0|1| - 從 Table 22 和 Table 23 可以看到,達到收斂的 SimRank 的數字會隨著 Decay Factor 的增加而增加。這個結果也並不意外,因為從公式就可以看到 Decay Factor 的大小也會影響到 Similarity 的大小。 - 至於 Graph 1 和 2 的 SimRank,則是不論 Decay Factor 為何,都是 Identity Matrix 。 ## PART 4. Effectiveness Analysis ### <u>4.1 Execution Time of the 3 Algorithms</u> 測試資料: Graph 1-6,以及 ibm-5000 由於這三個演算法的執行時間會跟測試資料的 Node 數量以及 Edge 數量有關,因此 Table 24 列出這 7 個測試資料的 Edge 和 Node 數量。 <p><center> Table 24. 測試 Data 的 Node 與 Edge 數量</center> </p> | | Node數量 |Edge 數量 | | :-: | :-: | :-: | |Graph 1|6 |5 | |Graph 2|5 |5 | |Graph 3|4 |6 | |Graph 4|7 |18 | |Graph 5|469|1102| |Graph 6| 1228|5220| |ibm-5000|836|4798| 實驗條件&步驟: 對這 7 個資料執行 HITS、PageRank、SimRank 演算法,參數 max_iteration 30 (三 個演算法都各跑 30 Iteration)、Damping Factor 0.1、Decay Factor 0.7,結果如 Table 25、Figure 16、以及 Figure 17 所示。 結果與討論: <p><center> Table 25. 三個演算法的執行時間(單位:秒) </center> </p> | | $HITS$ |$PageRank$ | $SimRank$| | :-: | :-: | :-: | :-:| |Graph 1|0.00153|0.00015|0.00064| |Graph 2|0.00122|0.00012|0.00058| |Graph 3|0.00121|0.00011|0.00057| |Graph 4|0.00234|0.00022|0.00224| |Graph 5|1.70784|0.06332|9.5617| |Graph 6|11.7193|0.39496|141.19387| |ibm-5000|5.72715|0.18675|75.91552| - 可以看到,這三個演算法基本上都隨著 Node 或 Edge 數量的增加,執行時間也會 因此增加。 - 三個演算法當中,以 PageRank 所需的時間最少,因為 PageRank 的程式碼,處理 的資料都儲存在一維矩陣。 此外,執行 PageRank 會用到的一些資訊我都有事先記錄下來,而並非在每個 for loop 裡面才去尋找,像是每個 Node 有哪些 Parent,以及每個 Parent 有多少 Children 等資訊。 <p align=center><center> <img src=" https://i.imgur.com/ee9iNT5.png " width="500" alt></center> </p> <p><center> Figure 16. Graph 1-4 執行三個演算法的時間</center> </p> <p align=center><center> <img src=" https://i.imgur.com/9dGhS1A.png " width="500" alt></center> </p> <p><center> Figure 17. Graph 5、6、以及 ibm-5000 執行三個演算法的時間</center> </p> - 從 Figure 16 可以看到,當 Node 數量少時,HITS 所需的執行時間比 SimRank 還 多;但在 Figure 17 可以看到,當 Node 數量變多時,SimRank 所需的時間就會急 劇增加。 本來以為我 SimRank 用了 4 層 for loop 去執行,應該會花最多時間。測試 HITS 程式碼後,發現是在計算 Authority 和 Hub 的地方花最多時間,這個地方我是使用 `numpy.dot()`來計算。 所以可以看到當 Node 和 Edge 數量少的時候,`numpy.dot()` 所需的時間會比 SimRank 的 4 層 for loop 還多;但當 Node 和 Edge 數量增加時,SimRank 的 4 層 for loop 就會造成時間急劇增加。 #### $Experiment\ VI$ 目的: 為了測試若不用 `numpy.dot()` 計算 Authority 和 Hub 是否能改善執行時間,我修改我的 HITS 程式碼,並測試新的 HITS 程式碼的執行時間。 測試資料: Graph 1-6、以及 ibm-5000。 實驗條件&步驟: 對 7 個測試資料執行新的 HITS 程式碼,每個測試資料都跑 30 個 Iteration,並記錄 執行時間。 <u>新的 HITS 程式碼說明如下</u>: 首先,將每個 Vertex 的 Authority 和 Hub 都初始化成 1: ```python! # 初始化 hub 和 authority hub = [1 for x in range(vertex_size)] authority = [1 for x in range(vertex_size)] ``` 接下來則是紀錄每個 Node 的 Parent 和 Children,以方便後面使用: ```python # 先將每個 node 的 parent/children 的資訊記錄下來 parent_list = [] children_list = [] for i in range(vertex_size): parent = [] children = [] for j in range(vertex_size): if adj_matrix[j][i] == 1: parent.append(j) if adj_matrix[i][j] == 1: children.append(j) if len(parent) == 0: parent_list.append([-1]) else: parent_list.append(parent) if len(children) == 0: children_list.append([-1]) else: children_list.append(children) ``` 再來則是進入 while 迴圈,不停更新每個 Node 的 Authority 和 Hub,直到達到設定的終 止條件,詳細說明如程式碼中的註解: ```python! iteration = 1 while True: # 先 copy 一份當前的 hub 和 authority prev_authority = authority.copy() prev_hub = hub.copy() for i in range(vertex_size): # 計算authority if parent_list[i][0] != -1: # 若 node i 有 parent new_auth = 0 for j in parent_list[i]: # 把 node i 的每個 parent j 前一輪的 hub 值加總起來 new_auth += prev_hub[j] # 更新authority authority[i] = new_auth else: # 若 node i 沒有 parent,就直接 0 authority[i] = 0 # 計算hub if children_list[i][0] != -1: # 若 node i 有 parent new_hub = 0 for j in children_list[i]: # 把 node i 的每個 parent j 前一輪的 authority 值加總起來 new_hub += prev_authority[j] # 更新hub hub[i] = new_hub else: # 若 node i 沒有 parent,就直接 0 hub[i] = 0 # 記得要做Normalization,這樣才會收斂 authority = one_norm(authority, vertex_size) hub = one_norm(hub, vertex_size) # 依據 max iteration 決定是否 break if iteration >= max_iteration: break else: iteration += 1 ``` 結果與討論: <p><center> Table 26. 新的 HITS 演算法執行時間(單位:秒) </center> </p> | | $HITS\ (Old)$ |$HITS\ (New)$ | $PageRank$ | $SimRank$| | :-: | :-: | :-: | :-:| :-:| |Graph 1|0.00153|<font color=#FF6600>0.00029</font>|0.00015|0.00064| |Graph 2|0.00122|<font color=#FF6600>0.00027</font>|0.00012|0.00058| |Graph 3|0.00121|<font color=#FF6600>0.00023</font>|0.00011|0.00057| |Graph 4|0.00234|<font color=#FF6600>0.0004</font>|0.00022|0.00224| |Graph 5|1.70784|<font color=#FF6600>0.08094</font>|0.06332|9.5617| |Graph 6|11.7193|<font color=#FF6600>0.98606</font>|0.39496|141.19387| |ibm-5000|5.72715|<font color=#FF6600>0.19853</font>|0.18675|75.91552| <p align=center><center> <img src=" https://i.imgur.com/7A3Fnic.png " width="500" alt></center> </p> <p><center> Figure 18. 新的 HITS 程式碼執行 Graph 1-4 的執行時間</center> </p> <p align=center><center> <img src=" https://i.imgur.com/wiIer57.png " width="500" alt></center> </p> <p><center> Figure 19. 新的 HITS 程式碼執行 Graph 5-6 和 ibm-5000 的執行時間</center> </p> - 從 Figure 18 和 Table 26 可以看到,新的 HITS 所需的執行時間大幅減少許多,所需時間和 PageRank 差不多,只比 PageRank 多一些。 - 從這個例子可以看到,雖然使用 Package 的功能會方便許多,但有可能會因為其實作方式而增加執行時間,而因此有可能導致誤判演算法實際的效能。 ### <u>4.2 The Effect of Edge Number on Execution Time</u> #### $Experiment\ VII$ 目的: 欲測試不同 Edge 數量對執行時間的影響。 測試資料: 用以下 5 個指令生出 5 份 ibm 資料。 ```cmd ./gen lit -ntrans 0.5 -tlen 10 -nitems 0.002 -npats 5 -conf 0.2 -patlen 20 ./gen lit -ntrans 0.5 -tlen 10 -nitems 0.004 -npats 5 -conf 0.2 -patlen 20 ./gen lit -ntrans 0.5 -tlen 10 -nitems 0.01 -npats 5 -conf 0.2 -patlen 20 ./gen lit -ntrans 0.5 -tlen 10 -nitems 0.02 -npats 5 -conf 0.2 -patlen 20 ./gen lit -ntrans 0.5 -tlen 10 -nitems 0.1 -npats 5 -conf 0.2 -patlen 20 ``` <p><center> Table 27. 不同 nitems 參數產生的 Node 與 Edge 數量</center> </p> | | Node數量 |Edge 數量 | | :-: | :-: | :-: | |`nitems 0.002`|354 |692 | |`nitems 0.004`|354 |1382 | |`nitems 0.01` |346|2417 | |`nitems 0.02` |345|3137 | |`nitems 0.1` |349|4333| 實驗條件&步驟: 對這 7 個資料執行 HITS、PageRank、SimRank 演算法,參數 max_iteration 30 (三個演算法都各跑 30 Iteration)、Damping Factor 0.1、Decay Factor 0.7,結果如 Figure 20 所示。 結果與討論: <p align=center><center> <img src=" https://i.imgur.com/dLT1sZc.png " width="500" alt></center> </p> <p><center> Figure 20. 不同 Edge 數量對演算法執行時間的影響</center> </p> <!-- ![](https://i.imgur.com/dLT1sZc.png) --> - 可以看到 HITS 和 PageRank 不太會隨著 Edge 數量的增加而增加執行時間,因為他們要處理的資料都是儲存在一維陣列,而一維陣列的大小取決於 Node 數量,所以這兩個演算法的執行時間主要受 Node 數量影響。 - SimRank 則會隨著 Edge 數量增加而大幅增加執行時間,因為我用了 4 層 for loop 去執行,所以 SimRank 的執行時間對 Edge 數量很敏感。 ### <u>4.3 The Effect of Node Number on Execution Time</u> #### $Experiment\ VIII$ 目的: 為了驗證我前面的猜測,想測試不同的 Node 數量對 HITS 和 PageRank 執行時間的影響。 測試資料: 用以下 5 個指令生出 5 份 ibm 資料。 ```cmd ./gen lit -ntrans 0.5 -tlen 10 -nitems 0.01 -npats 5 -conf 0.2 -patlen 20 ./gen lit -ntrans 1 -tlen 10 -nitems 0.01 -npats 5 -conf 0.2 -patlen 20 ./gen lit -ntrans 1.5 -tlen 10 -nitems 0.01 -npats 5 -conf 0.2 -patlen 20 ./gen lit -ntrans 2 -tlen 10 -nitems 0.01 -npats 5 -conf 0.2 -patlen 20 ./gen lit -ntrans 2.5 -tlen 10 -nitems 0.01 -npats 5 -conf 0.2 -patlen 20 ``` 由於增加 Node 數量,Edge 數量勢必也會增加。為了減少 Edge 數量增加所造成的變異,僅能盡量控制 Node 和 Edge 維持在固定的比例,由 Table 28 可見 Edge 對 Node 的比例幾乎都是在 7。 <p><center> Table 28. 不同 ntrans 參數產生的 Node 和 Edge 數量</center> </p> | | Node數量 |Edge 數量 | Edge/Node | | :-: | :-: | :-: | :-: | |`ntrans 0.5`|346 |2417 |6.99| |`ntrans 1` |694 |4870 |7.02| |`ntrans 1.5`|1005|7052 |7.02| |`ntrans 2` |1352|9499 |7.03| |`ntrans 2.5`|1703|11998|7.05| 實驗條件&步驟: - 對這五筆測試資料執行 HITS、PageRank、以及 SimRank 演算法。 - 參數 Damping Factor 0.1、Decay Factor 0.7、max_iteration 30 (三個演算法都各跑 30 Iteration)。 結果與討論: - 從 Figure 21 可以看到,三個演算法都會隨著 Node 數量增加而增加執行時間。 - 其中以 SimRank 所增加的時間最多,其次是 HITS,上升幅度最小的則是 PageRank。 <p align=center><center> <img src="https://i.imgur.com/jrUgXU9.png" width="800" alt></center> </p> <p><center> Figure 21. 不同 Node 數量對演算法執行時間的影響</center> </p> ## PART 5. Conclusions ### $HITS$ HITS 藉由計算 Authority 和 Hub 來評估每個 Node,並不會只因為 Parent 或 Children 數量多而就會有高的 Authority 和 Hub,Parent 和 Children 的品質也會影響到 Authority 和 Hub。 此外,在做這份作業時發生一件小插曲,也因此有個意外的發現。我跟同學在核對彼 此 HITS 輸出的結果,但 Graph 6 都有對不上的地方,我同學跑 30 個 Iteration 得到的結果,我的程式碼要跑大概 60 個 Iteration 才能得到相似的結果。看了同學的程式碼之後才 發現,我同學每一個 Iteration 在計算 Authority/Hub 時,都是用該 Iteration 剛計算完的 Hub/Authority 來計算,並不是用上一個 Iteration 的 Hub/Authority 來計算。也因此我才知道用這種方式計算的話,達到收斂的速度大概會是我的作法的兩倍(我達到收斂的 Iteration,我同學的只需要一半的 Iteration 就可達到收斂)。 ### $PageRank$ PageRank 則是藉由 Parent 的分數以及 Parent 的 Children 數量來做評分。基本上, PageRank 的分數大致上會與 Parent 數量呈一定相關性,因為 Parent 越多,就會有越多 PageRank 傳遞到該 Node。 若沒有使用 Damping Factor,則若 Graph 中存在沒有 Parent 的 Node,則該 Node 的 PageRank 就會是 0;倘若 Graph 存在沒有 Children 的 Node,則會有無解的狀況發生。 Damping Factor 越大,達到收斂的 Iteration 就會越少,這是因為「隨機」到達該 Node 的影響力大於從「Parent」到達該 Node 的影響力。此外,Damping Factor 越大, 達到收斂時每個 Node 的 PageRank 就會越接近 1/(Node 總數)。 ### $SimRank$ SimRank 是藉由評估 Node 跟 Node 的 Parent 來評估這兩個 Node 的相似度。若某個 Node 的 Parent 是另一個 Node 的 Parent 的子集,則這兩個 Node 的 SimRank 就會比較高。此外,若兩個 Node 的 Parent 差集數量越小,則他們的 SimRank 也會較高。由此可知,若 Parent 的交集是空集合,那 SimRank 就會較低,不過在迭代的過程中,還會將 Parent 的 Parent 等關係較遠的 Parent 納入評估。 Decay Factor 越高,達到收斂的 Iteration 就會越多。但倘若達到收斂的 SimRank 是 稀疏矩陣,或單位矩陣,則 Decay Factor 的大小對於達到收斂的 Iteration 的影響力則不大,因為這種狀況通常很快就會達到收斂。 ### Execution Time 在演算法的執行時間方面,三個演算法基本上都會隨著 Node 數量增加而增加執行時 間,其中以 SimRank 的執行時間增加的幅度最為劇烈。在 Node 數量固定的情況下, HITS 和 PageRank 不太會因為 Edge 數量增加而顯著增加執行時間,但 SimRank 則會隨 著 Edge 數量增加而顯著增加執行時間。三個演算法當中,PageRank 所需的執行時間是最少的。 最後,在實作演算法時,雖然使用 package 的 function 會很方便,但有可能會因為 package 的 function 的實作方式而增加所需的執行時間,而因此誤判演算法的效能。