【数据分析】学术前沿分析(1)——论文数据统计
赛题说明
任务
任务1 :论⽂数量量统计(数据统计任务):统计2019年全年,计算机各个⽅方向论⽂数量;
任务2 :论⽂作者统计(数据统计任务):统计所有论⽂作者出现评率Top10的姓名;
任务3 :论⽂代码统计(数据统计任务):统计所有论⽂类别下包含源代码论文的比例;
任务4 :论⽂分类(数据建模任务):利用已有数据建模,对新论文进行类别分类;
任务5 :作者关联(数据建模任务):对论文作者关系进⾏建模,统计最常出现的作者关系;
可视性任务
任务1:统计分析每个类别论⽂在不同时期的热⻔关键词,分析arXiv论⽂常见关键词的发展趋势,
并进⾏统计可视化;
任务2:统计分析每个类别论⽂综述句子的长度、情感和定冠词,并进⾏可视化;
任务3:统计分析论⽂作者的关联度,通过关联挖掘进行分析;
数据说明
arXiv 重要的学术公开网站,也是搜索、浏览和下载学术论⽂的重要工具。 arXiv论⽂涵盖的范围⾮常广,涉及物理学的庞⼤分支和计算机科学的众多⼦学科,如数学、统计学、电气⼯程、定量生物学和经济学等等。
本次赛题将使用arXiv在公开的17万篇论⽂数据集,希望各位选手通过数据分析能够挖掘出最近学术的发展趋势和学术关键词。
数据集来源: https://www.kaggle.com/Cornell-University/arxiv
数据集介绍
id : arXiv ID,可⽤用于访问论⽂;
submitter :论⽂提交者;
authors :论⽂作者;
title :论⽂标题;
comments :论⽂页数和图表等其他信息;
journal-ref :论⽂发表的期刊的信息;
doi :数字对象标识符, https://www.doi.org;
report-no :报告编号;
categories :论⽂在 arXiv 系统的所属类别或标签;
license :⽂章的许可证;
abstract :论⽂摘要;
versions :论⽂版本;
authors_parsed :作者的信息。
代码
导入库
import seaborn as sns #⽤用于画图
from bs4 import BeautifulSoup #⽤用于爬取arxiv的数据
import re #⽤用于正则表达式,匹配字符串串的模式
import requests #⽤用于⽹网络连接,发送网络请求,使⽤用域名获取对应信息
import json #读取数据,我们的数据为json格式的
import pandas as pd #数据处理理,数据分析
import matplotlib.pyplot as plt #画图⼯工具
读入数据
data = [] #初始化
#使⽤用with语句句优势: 1.自动关闭⽂文件句句柄; 2.自动显示(处理理)⽂文件读取数据异常
with open("arxiv-metadata-oai-2019.json", 'r') as f:
for line in f:
data.append(json.loads(line))
data = pd.DataFrame(data) #将list变为dataframe格式,方便使用pandas进行分析
data.shape #显示数据⼤大⼩小
查看前五行数据
data.head()
数据描述
'''
count:⼀一列数据的元素个数;
unique:⼀一列数据中元素的种类;
top:⼀一列数据中出现频率最⾼的元素;
freq:⼀一列数据中出现频率最⾼的元素的个数;
'''
data["categories"].describe()
查看独立种类
# 所有的种类(独立的)
unique_categories = set([i for l in [x.split(' ') for x in data["categories"]]for i in l])
#len(unique_categories)
unique_categories
得到2019年之后的数据
data["year"] = pd.to_datetime(data["update_date"]).dt.year #将update_date从例例如2019-02-20的str变为datetime格式,并提取处year
del data["update_date"] #删除 update_date特征,其使命已完成
data = data[data["year"] >= 2019] #找出 year 中2019年年以后的数据,并将其他数据删除
# data.groupby(['categories','year']) #以 categories 进行排序,如果同⼀一个categories相同则使⽤用 year 特征进行排序
data.reset_index(drop=True, inplace=True) #重新编号
data #查看结果
挑选出计算机领域的所有论文
#爬取所有的类别
website_url = requests.get('https://arxiv.org/category_taxonomy').text #获取网页的文本数据
soup = BeautifulSoup(website_url,'lxml') #爬取数据,这里使用lxml的解析器,加速
root = soup.find('div',{'id':'category_taxonomy_list'}) #找出 BeautifulSoup 对应的标签入口
tags = root.find_all(["h2","h3","h4","p"], recursive=True) #读取 tags
#初始化 str 和 list 变量量
level_1_name = ""
level_2_name = ""
level_2_code = ""
level_1_names = []
level_2_codes = []
level_2_names = []
level_3_codes = []
level_3_names = []
level_3_notes = []
#进⾏
for t in tags:
if t.name == "h2":
level_1_name = t.text
level_2_code = t.text
level_2_name = t.text
elif t.name == "h3":
raw = t.text
level_2_code = re.sub(r"(.*)\((.*)\)",r"\2",raw) #正则表达式:模式字符串:(.*)\((.*)\);被替换字符串"\2";被处理字符串: raw
level_2_name = re.sub(r"(.*)\((.*)\)",r"\1",raw)
elif t.name == "h4":
raw = t.text
level_3_code = re.sub(r"(.*) \((.*)\)",r"\1",raw)
level_3_name = re.sub(r"(.*) \((.*)\)",r"\2",raw)
elif t.name == "p":
notes = t.text
level_1_names.append(level_1_name)
level_2_names.append(level_2_name)
level_2_codes.append(level_2_code)
level_3_names.append(level_3_name)
level_3_codes.append(level_3_code)
level_3_notes.append(notes)
#根据以上信息生成dataframe格式的数据
df_taxonomy = pd.DataFrame({
'group_name' : level_1_names,
'archive_name' : level_2_names,
'archive_id' : level_2_codes,
'category_name' : level_3_names,
'categories' : level_3_codes,
'category_description': level_3_notes
})
#按照 "group_name" 进行分组,在组内使用 "archive_name" 进行排序
df_taxonomy.groupby(["group_name","archive_name"])
df_taxonomy
正则式表达筛选
'''
pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为⼀一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
flags : 编译时⽤用的匹配模式,数字形式。
其中pattern、 repl、 string为必选参数
'''
re.sub(r"(.*)\((.*)\)",r"\2",raw)
所有大类论文数量分布
_df = data.merge(df_taxonomy, on="categories",
how="left").drop_duplicates(["id","group_name"]).groupby("group_name").agg({"id":"count"}).sort_values(by="id",ascending=False).reset_index()
_df
饼图可视化
fig = plt.figure(figsize=(15,12))
explode = (0, 0, 0, 0.2, 0.3, 0.3, 0.2, 0.1)
plt.pie(_df["id"], labels=_df["group_name"], autopct='%1.2f%%',
startangle=160, explode=explode)
plt.tight_layout()
plt.show()
2019年后计算机的各个子领域论文数量
group_name="Computer Science"
cats = data.merge(df_taxonomy, on="categories").query("group_name ==@group_name")
cats.groupby(["year","category_name"]).count().reset_index().pivot(index="category_name", columns="year",values="id")
一些问题和总结
为什么需要重新爬取数据
因为已有的数据集不完整,所以再自己爬数据集确认一下,取一个并集。其实是为了严谨~