如果让我们自己去做搜索的话,我们能够想到的是文章和搜索词的相关性,以此来判断这个文章是否是我们想要的,最开始的搜索有的是这样做的,还有的是按照网站的种类做个大的索引表,但是可以索引的关键字有限 。
互联网上的网页估计有千百亿规模了(猜测),那么显然不是所有包含搜索关键字的网页都同等重要 。有的在标题中包含关键字,有的在文档中包含关键字;有的是权威机构网站,有的是个人博客,显然在给用户返回网页的时候,比较重要的网页的应该排在前面,不重要的网页信息排在后面 。那又来一个问题,如何确定一个网页的重要性那 。
网页是通过链接来组织的,那么我们可以把整个互联网看成一张大的图,每个节点为一个个网页,网页之间的链接看成边 。网页是否重要,要看是否有多个网页链接到它 。被越多网页链接的网页越重要,当然链接这个网页的多个链接的重要性又是不相同的 。
假设我们搜索得到很多网页,其中一个网页Y的排名应该来自所有指向这个网页X1,X2,X3的权重之和:
Y网页的权重 = X1+X2+X3...+Xn而X1,X2,...Xn的权重分别是多少,如何度量,这又需要通过链接到它的网页的权重来计算,这样循环往复,就无解了 。据说是Google的布林破解了这个怪圈,就是开始的时候给每个网页设置相同的初始值,那么经过多轮计算后,这个算法可以保证网页排名多次之后回收敛到排名的真实值 。
我理解下,大概是这样子的:
第一轮的时候,我们假设所有网页的权重都是1,那么A这个网页的权重为1+1+1为3, 第二轮计算的时候,与A相连的网页权重变成了2,那么最终A这个网页的权重就变成了2+2+2=6,这样多次计算后,被更多权重高的网页链接的网页,排名靠前,其他的靠后 。
这整个过程有点类似于民主选举,选举过程中每个人的票的权重又是不一样的,这和现实也很类似 。那么PageRank算法除了计算网页排名还有什么用那,数据实战45讲里面,有个例子比较有意思,计算泄露出来希拉里邮件列表中的人物影响力的情况,通过python的networkx库可以方便地计算PageRank的值 。
下面的网络图的:
【pagerank算法实现 PageRank算法与实践】
简单的计算PageRank的代码:
import networkx as nx# 创建有向图G = nx.DiGraph() # 有向图之间边的关系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)结果:
整个数据集合分为三个文件:Aliases.csv,Emails.csv和Persons.csv,其中Emails文件为邮件内容,包括重要的发送者和接收者信息 。Persons文件统计邮件中所有人的姓名和对应ID 。下面代码是数据实战中的代码直接拿过来了,其实过程也是比较简单,只是这个思路比较重要 。
# -*- coding: utf-8 -*-# 用 PageRank 挖掘希拉里邮件中的重要任务关系import pandas as pdimport networkx as nximport numpy as npfrom collections import defaultdictimport matplotlib.pyplot as plt# 数据加载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']# 针对别名进行转换 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 值很小所以需要 *20000 nodesize = [x['pagerank']*20000 for v,x in graph.nodes(data=http://www.zrodata.com/True)] # 设置网络图中的边长度 edgesize = [np.sqrt(e[2]['weight']) for e in graph.edges(data=http://www.zrodata.com/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) # 绘制节点的 label nx.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)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# 转化格式 (from, to), weight => from, to, weightedges_weights = [(key[0], key[1], val) for key, val in edges_weights_temp.items()]# 创建一个有向图graph = nx.DiGraph()# 设置有向图中的路径及权重 (from, to, weight)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=http://www.zrodata.com/True): if p_rank['pagerank'] < pagerank_threshold: small_graph.remove_node(n)# 画网络图,采用circular_layout布局让筛选出来的点组成一个圆show_graph(small_graph, 'circular_layout')
推荐阅读
- 开私服的方法(如何开私服?教你轻松实现游戏梦想 怎么开私服)
- 视频号如何推流直播 微信自带的能实现推流直播的具体步骤
- 2018年58岁女子实现财务自由,和结婚34年丈夫各住一房,称:别碰我
- 5个方法实现安卓苹果之间快速传输图片 苹果跟安卓怎么互传照片联系人
- 国产光刻机真实现状 纳米国产光刻机多少钱一台
- 夏至三庚入伏怎么算的 夏至三庚入伏的算法
- 电视回看怎么操作?教你如何简单实用地实现回看功能! 电视回看怎么操作
- 实现小米手机的远程控制的操作方法 小米手机远程协助功能在哪里
- 如何促进企业良性发展 如何实现企业的良性发展
- 算法的三种基本结构的特点是什么 算法的三种基本结构是什么快