(项目记录)学者影响力预测(python)

最近准备实习,所以把之前的项目拿出来回顾一下,用csdn做一下记录和梳理,方便以后查看,一起交流讨论。

完整项目代码已经上传github

项目介绍:基于深度学习的学者影响力预测

项目概述:

学术网络影响力评估的主要研究内容是,基于学术网络中作者、文献、期刊、机构等信息,对学术网络中重要的组成因素(如作者、文献等)进行评估。通过研究分析,本项目主要基于学者所发表的文献的相关信息及其在社交网络中的属性等因素来预测学者在学术领域的影响力。

当前的学者影响力评估方法归为两类:基于统计的评价方法(如h-index)和基于学术网络结构的评价方法(如PageRank )。
基于统计的方法考虑的是文章的数量、文章的被引用次数等信息,如作者发表文章的数量( Publication )、作者被引用的次数(Citation)、作者的合作作者数(Co-authors )和h-index等。而基于学术网络结构的方法,则是基于整个学术网络的网络结构(如作者之间的合作网络、作者之间的引用网络)对作者进行评价,如基于作者合作网络的PageRank(PR_AC)算法和基于作者的引用网络的PageRank算法(PR_CO)。
我们首先复原论文Future impact: Predicting scientific success实验,对比R^2值,p-value等评价发现拟合地最好方程是岭回归,对学者h-index增长影响最显著的特征是“论文发量”,“2010年的h-index”。

工作介绍:

数据收集(爬虫)

相当于是一个爬虫的项目实践吧,爬虫基础可见我的另一篇博客爬虫(python)
我负责的内容是从dplp(http://dblp.uni-trier.de/db/journals/neco/)中爬取期刊中所有文章和作者信息,然后从Scopus(https://www.scopus.com/search/form.uri?display=basic)中爬取文章的索引信息,最后构建学术引用网络。

dplp(DataBase systems and Logic Programming)是计算机领域内对研究的成果以作者为核心的一个计算机类英文文献的集成数据库系统。按年代列出了作者的科研成果。包括国际期刊和会议等公开发表的论文。DBLP没有提供对中文文献的收录和检索功能,国内的权威期刊及重要会议的论文缺乏一个类似的集成检索系统。DBLP所收录的期刊和会议论文质量较高,DBLP的文献更新速度很快,很好地反应了国外学术研究的前沿方向。

Scopus是一个新的导航工具,它涵盖了世界上最广泛的科技和医学文献的文摘、参考文献及索引。Scopus收录了来自于许多著名的期刊文献如Elsevier、Kluwer、Institutionof Electrical Engineers、JohnWiley、Springer、Nature、AmericanChemicalSociety等等。尤为重要的是,Scopus还广泛的收录了重要的中文期刊,如:《计算机学报》 等其它众多高品质的期刊。正因为拥有60%的内容来自于美国以外的国家,您就能够获得最全面的世界范围内的前瞻性科学技术医学文献。

Step 1:dplp中爬取期刊中文章和作者信息

可以从https://dblp.uni-trier.de/db/journals/nn/看到期刊Neural Networks的所有内容。
(项目记录)学者影响力预测(python)
打开2019: Volumes 109可以可看到,期刊中包含的文章名和作者等信息。
(项目记录)学者影响力预测(python)

OK,Let’s go!首先,我们先构建url,然后用bs4来解码html,bs4的好处是bs4可以选择任意喜欢的方式,进行解码,我选择的是html5lib,而且解码后的格式是树的格式,方便我们查询标签。
bs4详细介绍见我的另一篇爬虫(二)Beautiful Soup(python

url_journal="http://dblp.uni-trier.de/db/journals/nn/"
response_journal=requests.get(url_journal);
soup_journal=BeautifulSoup(response_journal.content.decode("utf-8"),"html5lib");

然后看到网页的源代码,格式可以说是很工整了,每个都是li开头Tag
(项目记录)学者影响力预测(python)
直接上代码吧,里面注释我应该标注的很明白了。如果一下子看不懂,可以一点一点print出来,看看树形结构,就可以看懂啦。

    for tag in soup_journal.find_all("li"):
        if len(tag.contents) > 0:
            contents=tag.contents;
            if "Volume" in contents[0]:
                if int(str(contents[0].split(":")[0])) > 2009:
                    # print (int(str(contents[0].split(":")[0])))
                    Year=str(contents[0].split(":")[0]);# 把年份保存下来
                    temp=contents[1:];
                    for element in temp:
                        if isinstance(element,bs4.element.NavigableString)==False:
                            for (key,value) in element.attrs.items():
                                # 解析每个volume下的文章
                                url_volume=value;# value表示url
                                print(value)
                                response_volume=requests.get(url_volume);
                                soup_volume=BeautifulSoup(response_volume.content.decode("utf-8"),"html5lib");

                                for tag_volume in soup_volume.find_all("article",attrs={"class": "data"}):
                                    temp_paper=[];
                                    paper_title=[];
                                    paper_author=[];

                                    # 处理每篇文章
                                    for element_volume in tag_volume.contents:
                                        # 判断该元素是不是一个标签
                                        if isinstance(element_volume,bs4.element.Tag):
                                            # 判断该元素是不是一个作者标签
                                            if element_volume.has_attr("itemtype"):
                                                paper_author.append(str(element_volume.string));
                                            elif element_volume.has_attr("class"):
                                                paper_title.append(str(element_volume.string));


                                    # 保存每篇文章的信息
                                    temp_paper.append(str(paper_id));
                                    temp_paper.extend(paper_title);
                                    temp_paper.append(Year);
                                    temp_paper.append(Journal);
                                    temp_paper.extend(paper_author);
                                    # 将信息保存到总的列表中
                                    total_paper.append(temp_paper);
                                    paper_id=paper_id+1;
                else:
                    break;

最后把爬取下来的东西保存到csv表格中,这里csv的包在python3.x和python2.x中有些不同,这里给出一些介绍:

open(file,mode,encoding,errors=“ignore”)
参数1:文件路径
参数2:mode:模式,读取文件的时候使用"r",默认"r" 参数3:encoding:指定读取的编码格式
参数4:errors:对编码错误的处理 默认是严格的,若使用"ignore"则可以忽略编码错误
功能:打开一个文件,并且获取到打开文件的对象。

可参见:csv基础操作csv在python3.xpython2.x的不同分析

import csv
    with open("papers_neural_networks.csv","w",errors="ignore") as ft:
        writer=csv.writer(ft, dialect='unix')#避免输出的时候有空格 unix可以忽略'\r'
        for x in total_paper:
            writer.writerow(x);

爬取结果展示:

(项目记录)学者影响力预测(python)
呦,还不错哦,同样的方法,我还爬取了Evolutionary Computation和Neural Computation期刊,方法都一样,改一下url就OK啦,这些数据供我们构建学术网络用。

Step 2:scopus中爬取文章的id

为了把我们爬到的文章进行统一标注,我们需要爬取EID,EID就是每篇论文的表示(像你的学号一样),方便我们以后构建论文的索引网络。你可以看到url,scopus其实也是靠EID来检索论文的。
(项目记录)学者影响力预测(python)
在scopus上搜索,EID虽然没有显示,但是我们通过源码搜索就可以找到它。
(项目记录)学者影响力预测(python)
我们可以看到网站的url是有规律的,前面和后面一大串很复杂的数字,但是它们是固定的,我们可以直接复制,中间是论文的题目,只不过把空格换成了’+'号,那么,我们就可以构建出我们所需要的目标url

# 构造URL需要用
str1 = "http://www.scopus.com/results/results.uri?numberOfFields=0&src=s&clickedLink=&edit=&editSaveSearch=&origin=searchbasic&authorTab=&affiliationTab=&advancedTab=&scint=1&menu=search&tablin=&searchterm1=";
str2 = "&field1=TITLE&dateType=Publication_Date_Type&yearFrom=Before+1960&yearTo=Present&loadDate=7&documenttype=All&subjects=LFSC&_subjects=on&subjects=HLSC&_subjects=on&subjects=PHSC&_subjects=on&subjects=SOSC&_subjects=on&st1="
str3 = "&st2=&sot=b&sdt=b&sl=66&s=TITLE%28";
str4 = "%29&sid=B1008C74CB35D28A3D2FA576D9FBD993.53bsOu7mi7A1NSY7fPJf1g%3A380&searchId=B1008C74CB35D28A3D2FA576D9FBD993.53bsOu7mi7A1NSY7fPJf1g%3A380&txGid=B1008C74CB35D28A3D2FA576D9FBD993.53bsOu7mi7A1NSY7fPJf1g%3A38&sort=plf-f&originationType=b&rr=&null="

with open("papers_" + name + ".csv", "r") as ft:
   reader = csv.reader(ft);
   for row in reader:
       if row[0] != "ID" and row[0]!="":
           count = count + 1;
           str5 = row[1].replace(" ","+");#将标题以空格为分隔符分裂,分裂成一个list
           print(str5)
           str6 = str1 + str5 + str2 + str5 + str3 + str5 + str4;
           url_paper = str6;  # 构造好的url

然后,解析url

response_paper = requests.get(url_paper);
soup_paper = BeautifulSoup(response_paper.content.decode("utf-8"), "html5lib");

用爬取下来的EID替换之前的ID

for tag_paper in soup_paper.find_all("input", attrs={"name": "selectedEIDs"}):
	tag1 = tag_paper['id']
	pid = str(tag1[11:])  # 得到每篇文章的id
	temp_row = [];
	temp_row.append(pid);
	temp_row.extend(row[1:]);#将原表中除id外的信息都加入
	papers_all.append(temp_row);  # 把每篇文章的信息得到
	print (count, temp_row)

爬取结果展示:

这里为了看起来舒服,就把"2-s2.0-"删除掉了。
(项目记录)学者影响力预测(python)

Step 3:爬取文章所有引用文章

这里使用了爱思唯尔提供的一个api,来搜索引用文章

直接上代码了,

paper_id = [];
	with open("papers_"+name+"_modify.csv","r") as ft:
		reader=csv.reader(ft);
		for row in reader:
			if row[0]!="ID":
				# 存储所有的journal信息
				paper_id.append(row[0]);


	# 对每一篇文章做处理,找到对应的参考文献
	headers = {'Accept':'application/json'};
	str1="http://api.elsevier.com/content/abstract/EID:";
	str2="?apikey=ab6a63d43253501662ea07c589c6c0a8&view=REF";
	paper_total=[];
	first_row=["P_ID","R_ID","Journal","Author"];
	paper_total.append(first_row);

	count=1;
	for eid in paper_id:
		# 打印每篇文章id
		url_paper=str1+eid+str2;
		print(url_paper)
		# time.sleep(10);
		page_response=requests.get(url_paper, headers=headers);
		# print (page_response)
		page=json.loads(page_response.content.decode("utf-8"));
		# print(page.keys())
		# print(page['abstracts-retrieval-response'].keys())
		# 安全检查
		if page==None or 'abstracts-retrieval-response' in page.keys()==False:
			continue;

		if page['abstracts-retrieval-response']==None or 'references' in page['abstracts-retrieval-response']==False:
			continue;

		if page['abstracts-retrieval-response']['references']==None or 'reference' in page['abstracts-retrieval-response']['references'].keys()==False:
			continue;

		# 解析得到结果
		for paper in page['abstracts-retrieval-response']['references']['reference']:
			# print(paper)
			sourcetitle=paper['sourcetitle'];
			if sourcetitle==None: # 没有期刊
				continue;
			temp_author=[];
			if paper['author-list']==None:#没有作者
				continue;
			for element in paper['author-list']['author']:
				if 'ce:given-name' in element.keys():
					temp_author.append(element['ce:given-name']+" "+element['ce:surname']);
				else:
					temp_author.append(element['ce:indexed-name']);
			temp=[];
			temp.append(eid);#存入文章id
			temp.append(paper['scopus-eid']);#存入参考文献id
			temp.append(sourcetitle);#存入参考文献所在期刊
			temp.extend(temp_author);
			paper_total.append(temp);
			# print(temp)

		count=count+1;

OK,就先介绍这么多,后期会上传一些sk-learn平台上做的回归实验的过程和结果。

上一篇:tex, virtex, initex - 文本格式化和排版


下一篇:写paper期间的无病呻吟及吐槽