In [1]:
## 导入包及定义函数
import re
import numpy as np
import scipy.sparse as sparse
from sklearn import preprocessing
def net_to_csr(row, col, i):
Mat = sparse.coo_matrix((np.ones(len(row)), (row, col)), shape=(i, i)).tocsr()
return Mat
def mat_normalize(Mat):
Mat = preprocessing.normalize(Mat, norm='l1').T
return Mat
def calculate_pagerank(netMat, escape=0.85, rho=1e-5, max_iter=1000, details=0):
i = netMat.shape[1]
x = np.ones(i)
p = escape
a = (1 - p)
for j in range(0, max_iter):
x_n = p * netMat.dot(x) + a
err = np.sum(np.abs(x - x_n))
if details:
print("iter:{} res-error:{}".format(j, err))
print(x_n.shape)
if err < rho:
break
x = x_n
return x_n
def topprint(dic,num=20):
i=0
for i in range(0,num):
print(dic[i])
数据预处理¶
我们首先应该将数据格式化,以便于后续的处理。为了达到速度与灵活性的统一,我们使用字典来存储metadata,用列表和元组来存储引用关系。
In [2]:
## 从acl-metadata中获取元数据。
with open('acl-metadata.txt',encoding='iso-8859-16') as f:
paperid = list()
authors = list()
title = list()
venue = list()
year = list()
n = 0
arrow=re.compile('(.*) = {(.*)}')
for line in f:
match=arrow.search(line)
if match:
label=match.group(1)
item=match.group(2)
if label=='id':
n=n+1
paperid.append(item)
elif label=='author':
authors.append(item)
elif label=='title':
title.append(item)
elif label=='venue':
venue.append(item)
else:
year.append(item)
metadata=dict()
for i in range(0,n):
metadata[paperid[i]]={'author':authors[i],'title':title[i],'venue':venue[i],'year':year[i]}
# 从acl.txt中获取引用的数据
with open('acl.txt') as g:
citedata=list()
arrow=re.compile('(.*) ==> (.*)')
for line in g:
match=arrow.search(line)
if match:
citedata.append((match.group(1),match.group(2)))
## 之后我们所有的数据都以从acl-metadata.txt和acl.txt中获取的metadata和citedata为准。
# metadata是一个字典,key是文章的ID,value是一个字典,具有{'author':author,'title':title,'venue':venue,'year':year}的形式
# citedata是一个列表,每个元素是一个二元元组,形如(paper_id_A,paper_id_B)
计算paper的PageRank¶
利用已知的数据构造Paper的PageRank,可以按照如下的顺序:
- 首先,初始化一个Paper的邻接矩阵。(邻接矩阵代表一个有向多边图)
- 之后,逐个读取文章的引用关系,A ==> B。在a,b中增加一条边。
- 添加完所有边后,利用这个矩阵计算PageRank。
我们计算后输出pagerank最高的20篇论文。
In [8]:
## 计算Paper的pagerank
# 初始化邻接矩阵
papers=dict()
j=0
for paper in metadata:
if paper not in papers:
papers[paper]=j
j=j+1
paper_mat= sparse.dok_matrix((j, j))
# 添加边
for cite in citedata:
paper_mat[papers[cite[0]],papers[cite[1]]]+=1
paper_mat = mat_normalize(paper_mat.tocsr())
p_r = calculate_pagerank(paper_mat, escape=0.85, rho=1e-5, max_iter=1000, details=0)
# 排序
paper_rank = dict()
i = 0
for paper in papers:
paper_rank[metadata[paper]['title']] = p_r[i]
i = i + 1
paper_rank = sorted(paper_rank.items(), key=lambda d: d[1], reverse=True)
topprint(paper_rank)
计算Venue的PageRank¶
利用已知的数据构造Venue的PageRank,可以按照如下的顺序:
- 首先,初始化一个Venue的邻接矩阵。(邻接矩阵代表一个有向多边图)
- 之后,逐个读取文章的引用关系,A ==> B。并查找文章A,B所在的Venue a,b。在a,b中增加一条边。
- 添加完所有边后,利用这个矩阵计算PageRank。
In [9]:
## 计算Venue的pagerank
# 初始化邻接矩阵
venues=dict()
j=0
for paper in metadata:
venue_name=metadata[paper]['venue']
if venue_name not in venues:
venues[venue_name]=j
j=j+1
venue_mat=np.zeros([len(venues),len(venues)])
# 添加边
for cite in citedata:
venue_mat[venues[metadata[cite[0]]['venue']],venues[metadata[cite[1]]['venue']]]+=1
# 矩阵迭代
venue_mat = mat_normalize(venue_mat)
v_r = calculate_pagerank(venue_mat, escape=0.85, rho=1e-5, max_iter=1000, details=0)
# 排序
venues_rank = dict()
i = 0
for venue in venues:
venues_rank[venue] = v_r[i]
i = i + 1
venues_rank = sorted(venues_rank.items(), key=lambda d: d[1], reverse=True)
topprint(venues_rank)
计算Author的PageRank¶
利用已知的数据构造Author的PageRank,可以按照如下的顺序:
- 首先,初始化一个Author的邻接矩阵。(邻接矩阵代表一个有向多边图)
- 之后,逐个读取文章的引用关系,A ==> B。并查找文章A,B a,b。在a,b中增加一条边。
- 添加完所有边后,利用这个矩阵计算PageRank。
In [12]:
## 计算Author的pagerank
# 初始化邻接矩阵
authors=dict()
j=0
for paper in metadata:
author=metadata[paper]['author']
if author not in authors:
authors[author]=j
j=j+1
author_mat= sparse.dok_matrix((j, j))
# 添加边
for cite in citedata:
author_mat[authors[metadata[cite[0]]['author']],authors[metadata[cite[1]]['author']]]+=1
# 矩阵迭代
author_mat = mat_normalize(author_mat.tocsr())
a_r = calculate_pagerank(author_mat, escape=0.85, rho=1e-5, max_iter=1000, details=0)
# 排序
author_rank = dict()
i = 0
for author in authors:
author_rank[author] = a_r[i]
i = i + 1
author_rank = sorted(author_rank.items(), key=lambda d: d[1], reverse=True)
topprint(author_rank)