PageRank算法原理及代码
生活随笔
收集整理的這篇文章主要介紹了
PageRank算法原理及代码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文內容出自帥器學習的課程內容,講得原理清晰,概念深入,鏈接:?PANKRANK算法視頻
另有一篇知乎文章,PAGERANK講得系統透徹,鏈接在此:關鍵詞提取和摘要算法TextRank詳解與實戰
PAGERANK算法是一種網頁排名算法,其基本思路有兩條:
- 鏈接數量。一個網頁被越多的其他網頁鏈接,說明這個網頁很重要。
- 鏈接質量。一個網頁被一個越高權值的網頁鏈接,也能表明這個網頁越重要。
1、課程導論
?
| ? | 由A出鏈到其他節點,即由A可以發射到B? C | ? | ? | ? |
| ? | ? | ? | ? | |
| ? | ? | ? | ? | |
| ? | ? | ? | ? | |
| ? | ? | ? | ? | |
| ? | ? | ? | ? | |
| ? | ? | ? | ? | |
| ? | ? | ? | ? | |
| A | B | C | D | |
| A | 0 | 0 | 0 | 1 |
| B | 1 | 0 | 0 | 0 |
| C | 1 | 1 | 1 | 0 |
| D | 0 | 1 | 1 | 0 |
?
?
經過反復研究,這個最終公式是有問題的,應該改為
?
2、代碼實踐
俗話說實踐出真知,聽課聽懂了,結果實踐的時候折騰了一天才弄明白,因為計算pagerank目前已經有成熟的算法,我根據networkx和pygraph現成的算法去驗證自己寫的是否有問題。
問題,目前有4個網頁A B C D
入鏈和出鏈關系如下圖,那么這4個網頁的pagerank是多少呢?
2.1 自寫算法
import numpy as np p = 0.85 #引入瀏覽當前網頁的概率為p,假設p=0.8a = np.array([[1,0,0,0],[0,0,0,1],[0,0,0,1],[0,1,0,0]],dtype = float) #dtype指定為float length=a.shape[1] #網頁數量 #構造轉移矩陣 b = np.transpose(a) #b為a的轉置矩陣 m = np.zeros((a.shape),dtype = float) for i in range(a.shape[0]):for j in range(a.shape[1]):#如果一個節點沒有任何出鏈,Dead Endsif b[j].sum()==0:b[j]=b[j]+np.array([1/length]*length)m[i][j] = a[i][j] / (b[j].sum()) #完成初始化分配#pr值得初始化 v = np.zeros((m.shape[0],1),dtype = float) #構造一個存放pr值得矩陣 for i in range(m.shape[0]):v[i] = float(1)/m.shape[0]count=0 ee=np.array([[1/length]*length]).reshape(length,-1) # 循環100次計算pageRank值 for i in range(100):# 解決spider traps問題,spider traps會導致網站權重向一個節點偏移,將轉移矩陣加上打開其他網頁的概率1-pv = p*np.dot(m,v) + (1-p)*ee count+=1print("第{}次迭代".format(count)) #pageRank值 print(v)2.2?networkx算法
import networkx as nx import matplotlib.pyplot as plt # 創建有向圖 G = nx.DiGraph() # 有向圖之間邊的關系 edges = [("A", "A"), ("B", "D"), ("D", "B"), ("D", "C")] for edge in edges:G.add_edge(edge[0], edge[1])nx.draw(G,with_labels=True) plt.show() pagerank_list = nx.pagerank(G, alpha=0.85) print("pagerank值是:\n", pagerank_list)?2.3?pygraph算法
from pygraph.classes.digraph import digraph dg = digraph()dg.add_nodes(["A", "B", "C", "D"])dg.add_edge(("A", "A")) dg.add_edge(("B", "D")) dg.add_edge(("D", "B")) dg.add_edge(("D", "C"))damping_factor = 0.85 # 阻尼系數,即α max_iterations = 100 # 最大迭代次數 min_delta = 0.00001 # 確定迭代是否結束的參數,即? graph = dg for node in graph.nodes():if len(graph.neighbors(node)) == 0:for node2 in graph.nodes():print("node:",node,"node2:",node2)digraph.add_edge(graph, (node, node2))print(graph)print("-"*5)print("="*30)nodes = graph.nodes() graph_size = len(nodes)page_rank = dict.fromkeys(nodes, 1.0 / graph_size) # 給每個節點賦予初始的PR值 damping_value = (1.0 - damping_factor) / graph_size # 公式中的(1?α)/N部分flag = False for i in range(max_iterations):change = 0for node in nodes:rank = 0for incident_page in graph.incidents(node): # 遍歷所有“入射”的頁面rank += damping_factor * (page_rank[incident_page] / len(graph.neighbors(incident_page)))rank += damping_valuechange += abs(page_rank[node] - rank) # 絕對值page_rank[node] = rankif change < min_delta:flag = Truebreak if flag:print("finished in %s iterations!" % node) else:print("finished out of 100 iterations!") print(page_rank)3、對比
自寫算法結果: [[0.47534884][0.15906977][0.15906977][0.20651163]] nx算法結果: {'A': 0.47534154833093023, 'B': 0.15907194271825495, 'C': 0.15907194271825495, 'D': 0.20651456623255982} pygraph結果: {'A': 0.47529602196443255, 'B': 0.1590697675524163, 'C': 0.1590697675524163, 'D': 0.20651162802444234}自此,我們的理論和實踐初級入門就可以了!
4、應用
pagerank既可以用在網頁質量的排名,也可以應用到網狀節點類的各種問題,比如社交網絡、各城市資本流向,以及改進后的TextRank,本文應用從希拉里用私人郵箱處理公務成為丑聞 事件為切入點,理解利用pagerank計算節點度量性。
# -*- coding: utf-8 -*- # 用 PageRank 挖掘希拉里郵件中的重要任務關系 import pandas as pd import networkx as nx import numpy as np from collections import defaultdict import matplotlib.pyplot as plt import os os.chdir("D:/pagerank/data/") # 數據加載 emails = pd.read_csv("Emails.csv") # 讀取別名文件 file = pd.read_csv("Aliases.csv")aliases = {} for index, row in file.iterrows():aliases[row['Alias']] = row['PersonId'] # 讀取人名文件 file = pd.read_csv("Persons.csv")persons = {} for index, row in file.iterrows():persons[row['Id']] = row['Name'] # 針對別名進行轉換 def unify_name(name):# 姓名統一小寫name = str(name).lower()# 去掉, 和 @后面的內容name = name.replace(",","").split("@")[0]# 別名轉換if name in aliases.keys():return persons[aliases[name]]return name # 畫網絡圖 def show_graph(graph, layout='spring_layout'):# 使用 Spring Layout 布局,類似中心放射狀if layout == 'circular_layout':positions=nx.circular_layout(graph)else:positions=nx.spring_layout(graph)# 設置網絡圖中的節點大小,大小與 pagerank 值相關,因為 pagerank 值很小所以需要 *20000nodesize = [x['pagerank']*20000 for v,x in graph.nodes(data=True)]# 設置網絡圖中的邊長度edgesize = [np.sqrt(e[2]['weight']) for e in graph.edges(data=True)]# 繪制節點nx.draw_networkx_nodes(graph, positions, node_size=nodesize, alpha=0.4)# 繪制邊nx.draw_networkx_edges(graph, positions, edge_size=edgesize, alpha=0.2)# 繪制節點的 labelnx.draw_networkx_labels(graph, positions, font_size=10)# 輸出希拉里郵件中的所有人物關系圖plt.show() # 將寄件人和收件人的姓名進行規范化 emails.MetadataFrom = emails.MetadataFrom.apply(unify_name) emails.MetadataTo = emails.MetadataTo.apply(unify_name) # 設置遍的權重等于發郵件的次數 edges_weights_temp = defaultdict(list) #defaultdict當字典里的Key不存在時,返回默認值[] for row in zip(emails.MetadataFrom, emails.MetadataTo, emails.RawText):temp = (row[0], row[1])if temp not in edges_weights_temp:edges_weights_temp[temp] = 1else:edges_weights_temp[temp] = edges_weights_temp[temp] + 1 # 轉化格式 (from, to), weight => from, to, weight edges_weights = [(key[0], key[1], val) for key, val in edges_weights_temp.items()] # 創建一個有向圖 graph = nx.DiGraph() # 設置有向圖中的路徑及權重 (from, to, weight) add_weighted_edges_fromu、v、w 分別代表起點、終點和權重。 graph.add_weighted_edges_from(edges_weights) # 計算每個節點(人)的 PR 值,并作為節點的 pagerank 屬性 pagerank = nx.pagerank(graph) # 將 pagerank 數值作為節點的屬性 nx.set_node_attributes(graph, name = 'pagerank', values=pagerank) # 畫網絡圖 show_graph(graph)# 將完整的圖譜進行精簡 # 設置 PR 值的閾值,篩選大于閾值的重要核心節點 pagerank_threshold = 0.005 # 復制一份計算好的網絡圖 small_graph = graph.copy() # 剪掉 PR 值小于 pagerank_threshold 的節點 for n, p_rank in graph.nodes(data=True):if p_rank['pagerank'] < pagerank_threshold:small_graph.remove_node(n) # 畫網絡圖,采用circular_layout布局讓篩選出來的點組成一個圓 show_graph(small_graph, 'circular_layout')?
?
參考鏈接
PageRank算法與TextRank算法詳解:點此鏈接
希拉里原始數據:點此鏈接
TextRank算法的基本原理及textrank4zh使用實例:點此鏈接
總結
以上是生活随笔為你收集整理的PageRank算法原理及代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 钓鱼网站php,偶遇钓鱼网站的一次代码审
- 下一篇: 大数据剖析:思科、IBM、甲骨文、Ube