自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一篇學(xué)會(huì) PageRank 算法與實(shí)踐

開(kāi)發(fā) 前端
PageRank通過(guò)網(wǎng)絡(luò)浩瀚的超鏈接關(guān)系來(lái)確定一個(gè)頁(yè)面的等級(jí)。Google把從A頁(yè)面到B頁(yè)面的鏈接解釋為A頁(yè)面給B頁(yè)面投票,Google根據(jù)投票來(lái)源(甚至來(lái)源的來(lái)源,即鏈接到A頁(yè)面的頁(yè)面)和投票目標(biāo)的等級(jí)來(lái)決定新的等級(jí)。

如果讓我們自己去做搜索的話,我們能夠想到的是文章和搜索詞的相關(guān)性,以此來(lái)判斷這個(gè)文章是否是我們想要的,最開(kāi)始的搜索有的是這樣做的,還有的是按照網(wǎng)站的種類(lèi)做個(gè)大的索引表,但是可以索引的關(guān)鍵字有限。

互聯(lián)網(wǎng)上的網(wǎng)頁(yè)估計(jì)有千百億規(guī)模了(猜測(cè)),那么顯然不是所有包含搜索關(guān)鍵字的網(wǎng)頁(yè)都同等重要。有的在標(biāo)題中包含關(guān)鍵字,有的在文檔中包含關(guān)鍵字;有的是權(quán)威機(jī)構(gòu)網(wǎng)站,有的是個(gè)人博客,顯然在給用戶(hù)返回網(wǎng)頁(yè)的時(shí)候,比較重要的網(wǎng)頁(yè)的應(yīng)該排在前面,不重要的網(wǎng)頁(yè)信息排在后面。那又來(lái)一個(gè)問(wèn)題,如何確定一個(gè)網(wǎng)頁(yè)的重要性那。

網(wǎng)頁(yè)是通過(guò)鏈接來(lái)組織的,那么我們可以把整個(gè)互聯(lián)網(wǎng)看成一張大的圖,每個(gè)節(jié)點(diǎn)為一個(gè)個(gè)網(wǎng)頁(yè),網(wǎng)頁(yè)之間的鏈接看成邊。網(wǎng)頁(yè)是否重要,要看是否有多個(gè)網(wǎng)頁(yè)鏈接到它。被越多網(wǎng)頁(yè)鏈接的網(wǎng)頁(yè)越重要,當(dāng)然鏈接這個(gè)網(wǎng)頁(yè)的多個(gè)鏈接的重要性又是不相同的。

假設(shè)我們搜索得到很多網(wǎng)頁(yè),其中一個(gè)網(wǎng)頁(yè)Y的排名應(yīng)該來(lái)自所有指向這個(gè)網(wǎng)頁(yè)X1,X2,X3的權(quán)重之和:

Y網(wǎng)頁(yè)的權(quán)重 = X1+X2+X3...+Xn

而X1,X2,...Xn的權(quán)重分別是多少,如何度量,這又需要通過(guò)鏈接到它的網(wǎng)頁(yè)的權(quán)重來(lái)計(jì)算,這樣循環(huán)往復(fù),就無(wú)解了。據(jù)說(shuō)是Google的布林破解了這個(gè)怪圈,就是開(kāi)始的時(shí)候給每個(gè)網(wǎng)頁(yè)設(shè)置相同的初始值,那么經(jīng)過(guò)多輪計(jì)算后,這個(gè)算法可以保證網(wǎng)頁(yè)排名多次之后回收斂到排名的真實(shí)值。

我理解下,大概是這樣子的:

第一輪的時(shí)候,我們假設(shè)所有網(wǎng)頁(yè)的權(quán)重都是1,那么A這個(gè)網(wǎng)頁(yè)的權(quán)重為1+1+1為3, 第二輪計(jì)算的時(shí)候,與A相連的網(wǎng)頁(yè)權(quán)重變成了2,那么最終A這個(gè)網(wǎng)頁(yè)的權(quán)重就變成了2+2+2=6,這樣多次計(jì)算后,被更多權(quán)重高的網(wǎng)頁(yè)鏈接的網(wǎng)頁(yè),排名靠前,其他的靠后。

這整個(gè)過(guò)程有點(diǎn)類(lèi)似于民主選舉,選舉過(guò)程中每個(gè)人的票的權(quán)重又是不一樣的,這和現(xiàn)實(shí)也很類(lèi)似。 那么PageRank算法除了計(jì)算網(wǎng)頁(yè)排名還有什么用那,數(shù)據(jù)實(shí)戰(zhàn)45講里面,有個(gè)例子比較有意思,計(jì)算泄露出來(lái)希拉里郵件列表中的人物影響力的情況,通過(guò)python的networkx庫(kù)可以方便地計(jì)算PageRank的值。

下面的網(wǎng)絡(luò)圖的:

簡(jiǎn)單的計(jì)算PageRank的代碼:

import networkx as nx
# 創(chuàng)建有向圖
G = nx.DiGraph()
# 有向圖之間邊的關(guān)系
edges = [("B1", "B"), ("B2", "B"), ("C1", "C"), ("C2", "C"), ("D1", "D"), ("D2", "D"), ("D", "A"), ("C", "A"), ("B", "A")]
for edge in edges:
G.add_edge(edge[0], edge[1])
pagerank_list = nx.pagerank(G, alpha=1)
print("pagerank值是:", pagerank_list)

結(jié)果:

整個(gè)數(shù)據(jù)集合分為三個(gè)文件:Aliases.csv,Emails.csv和Persons.csv,其中Emails文件為郵件內(nèi)容,包括重要的發(fā)送者和接收者信息。 Persons文件統(tǒng)計(jì)郵件中所有人的姓名和對(duì)應(yīng)ID。 下面代碼是數(shù)據(jù)實(shí)戰(zhàn)中的代碼直接拿過(guò)來(lái)了,其實(shí)過(guò)程也是比較簡(jiǎn)單,只是這個(gè)思路比較重要。


# -*- coding: utf-8 -*-
# 用 PageRank 挖掘希拉里郵件中的重要任務(wù)關(guān)系
import pandas as pd
import networkx as nx
import numpy as np
from collections import defaultdict
import matplotlib.pyplot as plt
# 數(shù)據(jù)加載
emails = pd.read_csv("./input/Emails.csv")
# 讀取別名文件
file = pd.read_csv("./input/Aliases.csv")
aliases = {}
for index, row in file.iterrows():
aliases[row['Alias']] = row['PersonId']
# 讀取人名文件
file = pd.read_csv("./input/Persons.csv")
persons = {}
for index, row in file.iterrows():
persons[row['Id']] = row['Name']
# 針對(duì)別名進(jìn)行轉(zhuǎn)換
def unify_name(name):
# 姓名統(tǒng)一小寫(xiě)
name = str(name).lower()
# 去掉, 和 @后面的內(nèi)容
name = name.replace(",","").split("@")[0]
# 別名轉(zhuǎn)換
if name in aliases.keys():
return persons[aliases[name]]
return name
# 畫(huà)網(wǎng)絡(luò)圖
def show_graph(graph, layout='spring_layout'):
# 使用 Spring Layout 布局,類(lèi)似中心放射狀
if layout == 'circular_layout':
positions=nx.circular_layout(graph)
else:
positions=nx.spring_layout(graph)
# 設(shè)置網(wǎng)絡(luò)圖中的節(jié)點(diǎn)大小,大小與 pagerank 值相關(guān),因?yàn)?pagerank 值很小所以需要 *20000
nodesize = [x['pagerank']*20000 for v,x in graph.nodes(data=True)]
# 設(shè)置網(wǎng)絡(luò)圖中的邊長(zhǎng)度
edgesize = [np.sqrt(e[2]['weight']) for e in graph.edges(data=True)]
# 繪制節(jié)點(diǎn)
nx.draw_networkx_nodes(graph, positions, node_size=nodesize, alpha=0.4)
# 繪制邊
nx.draw_networkx_edges(graph, positions, edge_size=edgesize, alpha=0.2)
# 繪制節(jié)點(diǎn)的 label
nx.draw_networkx_labels(graph, positions, font_size=10)
# 輸出希拉里郵件中的所有人物關(guān)系圖
plt.show()
# 將寄件人和收件人的姓名進(jìn)行規(guī)范化
emails.MetadataFrom = emails.MetadataFrom.apply(unify_name)
emails.MetadataTo = emails.MetadataTo.apply(unify_name)
# 設(shè)置遍的權(quán)重等于發(fā)郵件的次數(shù)
edges_weights_temp = defaultdict(list)
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] = 1
else:
edges_weights_temp[temp] = edges_weights_temp[temp] + 1
# 轉(zhuǎn)化格式 (from, to), weight => from, to, weight
edges_weights = [(key[0], key[1], val) for key, val in edges_weights_temp.items()]
# 創(chuàng)建一個(gè)有向圖
graph = nx.DiGraph()
# 設(shè)置有向圖中的路徑及權(quán)重 (from, to, weight)
graph.add_weighted_edges_from(edges_weights)
# 計(jì)算每個(gè)節(jié)點(diǎn)(人)的 PR 值,并作為節(jié)點(diǎn)的 pagerank 屬性
pagerank = nx.pagerank(graph)
# 將 pagerank 數(shù)值作為節(jié)點(diǎn)的屬性
nx.set_node_attributes(graph, name = 'pagerank', values=pagerank)
# 畫(huà)網(wǎng)絡(luò)圖
show_graph(graph)

# 將完整的圖譜進(jìn)行精簡(jiǎn)
# 設(shè)置 PR 值的閾值,篩選大于閾值的重要核心節(jié)點(diǎn)
pagerank_threshold = 0.005
# 復(fù)制一份計(jì)算好的網(wǎng)絡(luò)圖
small_graph = graph.copy()
# 剪掉 PR 值小于 pagerank_threshold 的節(jié)點(diǎn)
for n, p_rank in graph.nodes(data=True):
if p_rank['pagerank'] < pagerank_threshold:
small_graph.remove_node(n)
# 畫(huà)網(wǎng)絡(luò)圖,采用circular_layout布局讓篩選出來(lái)的點(diǎn)組成一個(gè)圓
show_graph(small_graph, 'circular_layout')
責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2021-07-29 07:55:20

React實(shí)踐代碼

2023-03-13 21:38:08

TCP數(shù)據(jù)IP地址

2021-08-26 13:22:46

雪花算法隨機(jī)數(shù)

2021-09-13 09:00:03

istio安裝部署

2021-12-26 18:24:00

NginxTomcat服務(wù)

2022-02-21 08:48:00

Pulsar部署配置

2022-01-02 08:43:46

Python

2022-02-07 11:01:23

ZooKeeper

2023-12-05 07:14:27

AIGo

2023-01-03 08:31:54

Spring讀取器配置

2021-05-11 08:54:59

建造者模式設(shè)計(jì)

2021-07-05 22:11:38

MySQL體系架構(gòu)

2021-07-06 08:59:18

抽象工廠模式

2022-08-26 09:29:01

Kubernetes策略Master

2023-11-28 08:29:31

Rust內(nèi)存布局

2021-07-02 09:45:29

MySQL InnoDB數(shù)據(jù)

2022-08-23 08:00:59

磁盤(pán)性能網(wǎng)絡(luò)

2021-07-02 08:51:29

源碼參數(shù)Thread

2021-07-16 22:43:10

Go并發(fā)Golang

2021-09-28 08:59:30

復(fù)原IP地址
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)