论文趋势分析(python+excel+tableau)
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import json
from bs4 import BeautifulSoup #用于爬取arxiv的数据
import re #用于正则表达式,匹配字符串的模式
import requests #用于网络连接,发送网络请求,使用域名获取对应信息
1数据读取
1.1读取原始数据
- 数据集来源:数据集链接;
- 数据集的格式如下:
id
:arXiv ID,可用于访问论文;submitter
:论文提交者;authors
:论文作者;title
:论文标题;comments
:论文页数和图表等其他信息;journal-ref
:论文发表的期刊的信息;doi
:数字对象标识符,https://www.doi.org;report-no
:报告编号;categories
:论文在 arXiv 系统的所属类别或标签;license
:文章的许可证;abstract
:论文摘要;versions
:论文版本;authors_parsed
:作者的信息。
# 读取json数据
def readArxivFile(path, columns=['id', 'submitter', 'authors', 'title', 'comments', 'journal-ref', 'doi','report-no', 'categories', 'license', 'abstract', 'versions','update_date', 'authors_parsed'], count=None):
data = []
with open(path, 'r') as f:
for idx, line in enumerate(f):
if idx == count:
break
d = json.loads(line)
d = {col : d[col] for col in columns}
data.append(d)
data = pd.DataFrame(data)
return data
data = readArxivFile('D:\code\Github\data\AcademicTrendsAnalysis/arxiv-metadata-oai-snapshot.json', ['id', 'submitter', 'authors', 'title', 'comments', 'journal-ref', 'categories', 'abstract', 'versions','update_date', 'authors_parsed'])
1.2抽取5%的数据作为样本进行分析
- 注释掉此段代码,就可以对全部数据进行分析,限于本人的机子性能有限,所以只取5%的数据进行分析
data = data.sample(frac =0.05,replace = False,random_state = 1 )
# 清理内存垃圾
import gc
gc.collect()
76
# 存储转换后的数据
data.to_csv('D:\code\Github\data\AcademicTrendsAnalysis\data.csv',index = False)
data.head(3)
id | submitter | authors | title | comments | journal-ref | categories | abstract | versions | update_date | authors_parsed | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1506.04017 | Serena Ng | Jean-Jacques Forneron and Serena Ng | A Likelihood-Free Reverse Sampler of the Poste... | NaN | NaN | stat.ME | This paper considers properties of an optimi... | [{'version': 'v1', 'created': 'Fri, 12 Jun 201... | 2015-12-02 | [['Forneron', 'Jean-Jacques', ''], ['Ng', 'Ser... |
1 | gr-qc/9211024 | NaN | R. Mansouri and M.Mohazzab (BROWN) | Tunneling in Anisotropic Cosmological Models | 13 pages, phyzzx | Class.Quant.Grav.10:1353-1359,1993 | gr-qc | Tunneling rate is investigated in homogenous... | [{'version': 'v1', 'created': 'Thu, 19 Nov 199... | 2010-04-06 | [['Mansouri', 'R.', '', 'BROWN'], ['Mohazzab',... |
2 | 2011.02152 | Rotem Liss | Rotem Liss, Tal Mor | From Practice to Theory: The "Bright Illuminat... | 17 pages | NaN | quant-ph cs.CR | The "Bright Illumination" attack [Lydersen e... | [{'version': 'v1', 'created': 'Wed, 4 Nov 2020... | 2020-11-05 | [['Liss', 'Rotem', ''], ['Mor', 'Tal', '']] |
1.3 爬取论文类别信息
- group_name 论文大类
- archive_name 论文子类(除了物理学领域,其他种类都没有子类)
- archive_id 论文子类的缩写
- category_name 论文细类的名称
- categories 论文细类的缩写
#爬取所有的类别
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
})
df_taxonomy.head()
# 存储论文类别信息
df_taxonomy.to_csv('D:\code\Github\data\AcademicTrendsAnalysis\categories.csv',index = False)
data = pd.read_csv('D:\code\Github\data\AcademicTrendsAnalysis\data.csv')
df_taxonomy = pd.read_csv('D:\code\Github\data\AcademicTrendsAnalysis\categories.csv')
df_taxonomy.head(3)
group_name | archive_name | archive_id | category_name | categories | category_description | |
---|---|---|---|---|---|---|
0 | Computer Science | Computer Science | Computer Science | Artificial Intelligence | cs.AI | Covers all areas of AI except Vision, Robotics... |
1 | Computer Science | Computer Science | Computer Science | Hardware Architecture | cs.AR | Covers systems organization and hardware archi... |
2 | Computer Science | Computer Science | Computer Science | Computational Complexity | cs.CC | Covers models of computation, complexity class... |
1.4处理多种类论文
- 有的论文同时属于多个种类,在统计时,只按照其最重要的类别(第一个类别)
data.categories.iloc[:5]
0 stat.ME
1 gr-qc
2 quant-ph cs.CR
3 cond-mat.mtrl-sci
4 math.FA math.AP math.CA math.DG
Name: categories, dtype: object
看到类别数据以空格分割
data['category'] = data.categories.str.split(' ',expand=True)[0]
print(data['category'].nunique())
172
1.5表连接
data = data.merge(df_taxonomy,how='left',left_on='category',right_on='categories')
data.shape
(89846, 18)
1.6提取论文的发表年份和月份
data['month'] = pd.to_datetime(data.update_date).dt.month
data['year'] = pd.to_datetime(data.update_date).dt.year
1.7提取论文的页数,图数
# 将评论转换成pd.string类型
data.comments = data.comments.astype('string')
pat = '(\d+) pages'
data['pages'] = data.comments.str.extract(pat=pat)
pat = '(\d+) figures'
data['figure'] = data.comments.str.extract(pat)
# 将文本转换为数字
data.pages = data.pages.fillna('0').astype(int)
# 避免0值参与计算的影响,将0值转换为空值,聚合计算时会自动忽略
data.loc[data.pages == 0] = np.nan
# 将文本转换为数字
data.figure = data.figure.fillna('0').astype(int)
# 避免0值参与计算的影响,将0值转换为空值,聚合计算时会自动忽略
data.figure.loc[data.figure == 0] = np.nan
1.8提取论文的作者数量
- 将文本型的列表转换为python列表
import ast
data.authors_parsed = data.authors_parsed.apply(ast.literal_eval)
- 统计作者数量
data['author_num'] = data.authors_parsed.apply(len)
1.9删除重复的论文
- 一篇论文可能多次提交,因此有多个版本,只保留第一个版本
data = data.drop_duplicates(['id','category'],keep = 'first')
data.to_csv('D:\code\Github\data\AcademicTrendsAnalysis\data_processed.csv',index=False)
2论文趋势分析-python
2.1论文大类总体分析
2.1.1各大类论文总数
- 物理,数学,计算机科学是数量最多的三大门类
- 统计学,计量生物学等门类的数量较少
group1 = data.groupby('group_name')['id'].agg('count').sort_values(ascending = False).to_frame()
group1 = group1.reset_index()
group1.columns = ['group_name','count']
sns.barplot(x = 'count',y = 'group_name',data = group1)
<matplotlib.axes._subplots.AxesSubplot at 0x1ca624ed730>
![图片名称](https://img-blog.csdnimg.cn/20210130211155849.png)
2.1.2各类论文数量随年份的变化
- 可以看到计算机科学的论文数量随着时间,增长越来越快,数学次之
- 物理学领域的论文数量变化较大,但总体也呈现上升趋势
- 其他领域的论文数量则增幅很小
group2 = data.groupby(['group_name','year'])['id'].agg('count').to_frame()
group2 = group2.reset_index()
group2.columns = ['group_name','year','count']
sns.relplot(data=group2,x='year',y = 'count',hue='group_name',kind='line')
<seaborn.axisgrid.FacetGrid at 0x1ca63d96130>
![图片名称](https://img-blog.csdnimg.cn/20210130211317788.png)
sns.catplot(data = group2,x = 'year',y ='count',col='group_name'
,col_wrap=2,height=6,aspect=1.2,kind='bar')
<seaborn.axisgrid.FacetGrid at 0x1ca62d0baf0>
![图片名称](https://img-blog.csdnimg.cn/20210130211412996.png)
2.1.3论文总数量随时间的变化
group3 = data.groupby('year')['id'].agg('count').sort_values(ascending = False).to_frame().reset_index()
group3.columns = ['year','count']
plt.figure(figsize = (10,8))
sns.barplot(data=group3,x='year',y='count')
<matplotlib.axes._subplots.AxesSubplot at 0x1ca65815940>
![图片名称](https://img-blog.csdnimg.cn/20210130211524990.png)
2.1.4不同大类论文页数的不同
- 可以看到计算机科学的平均论文页数并不算高
- 经济学,数学,统计学的论文页数较多
group4 = data.groupby('group_name')['pages'].agg('mean').sort_values(ascending = False).to_frame().reset_index()
group4.columns = ['group_name','pages']
sns.barplot(data=group4,x='pages',y='group_name')
<matplotlib.axes._subplots.AxesSubplot at 0x1ca6c4183a0>
![图片名称](https://img-blog.csdnimg.cn/20210130211602590.png)
2.1.5不同大类合作作者数量的不同
- 物理学领域论文平均每篇的作者数量最多,为5人
- 数学领域论文平均每篇的作者数量最少,只有不到2人
group4 = data.groupby('group_name')['author_num'].agg('mean').sort_values(ascending = False).to_frame().reset_index()
group4.columns = ['group_name','author_num']
sns.barplot(data=group4,x='author_num',y='group_name')
<matplotlib.axes._subplots.AxesSubplot at 0x1ca6ba9faf0>
![图片名称](https://img-blog.csdnimg.cn/20210130211732313.png)
2.2计算机领域论文趋势分析
2.2.1各领域论文的总数量
- 计算机视觉,机器学习果然是计算机科学论文最多的领域
group5 = data.loc[data.group_name == 'Computer Science'].groupby('category_name')['id'].agg('count').sort_values(ascending = False).to_frame().reset_index()
group5.columns = ['category_name','count']
plt.figure(figsize=(12,10))
sns.barplot(data=group5,x='count',y='category_name')
<matplotlib.axes._subplots.AxesSubplot at 0x1ca7165a1f0>
![图片名称](https://img-blog.csdnimg.cn/20210130211831216.png)
2.2.2各领域论文数量随时间的变换
- 可以看到除了机器学习,机器视觉,自然语言处理增长较快之外,其他领域的论文数量增长都比较慢
- 信息理论,密码学与安全,机器人是除了ML,CV,NLP之外发表论文数量比较多的领域
- ML和CV还是计算机科学领域最火的方向
group6 = data.loc[data.group_name == 'Computer Science'].groupby(['category_name','year'])['id'].agg('count').sort_values(ascending = False).to_frame().reset_index()
group6.columns = ['category_name','year','count']
sns.relplot(data=group6,x='year',y = 'count',hue='category_name',kind='line',height = 10,style = 'category_name',palette='husl')
<seaborn.axisgrid.FacetGrid at 0x1ca6c6c5070>
![图片名称](https://img-blog.csdnimg.cn/2021013021192712.png)
- Y轴相同刻度,查看相对数量
sns.catplot(data = group6,x = 'year',y ='count',col='category_name'
,col_wrap=4,height=5,aspect=1.2,kind='bar')
<seaborn.axisgrid.FacetGrid at 0x1ca6c2eb7f0>
![图片名称](https://img-blog.csdnimg.cn/20210130212012610.png)
- Y轴不同刻度,查看变化趋势
sns.catplot(data = group6,x = 'year',y ='count',col='category_name'
,col_wrap=4,height=5,aspect=1.2,kind='bar',sharey=False)
<seaborn.axisgrid.FacetGrid at 0x1ca6c474130>
![图片名称](https://img-blog.csdnimg.cn/20210130212108549.png)
2.2.3论文页数
- 人工智能,编程语言,数值分析领域的论文页数最长
- CV和NLP的平均页数未进入前20
group7 = data.loc[data.group_name == 'Computer Science'].groupby('category_name')['pages'].agg('mean').sort_values(ascending = False).to_frame().reset_index().head(20)
group7.columns = ['category_name','mean_pages']
plt.figure(figsize=(6,8))
sns.barplot(data=group7,x='mean_pages',y='category_name')
<matplotlib.axes._subplots.AxesSubplot at 0x1ca76e637f0>
![图片名称](https://img-blog.csdnimg.cn/20210130212150233.png)
2.2.4计算机视觉领域的合作作者数量最多
group8 = data.loc[data.group_name == 'Computer Science'].groupby('category_name')['author_num'].agg('mean').sort_values(ascending = False).to_frame().reset_index().head(20)
group8.columns = ['category_name','mean_author_num']
plt.figure(figsize=(6,8))
sns.barplot(data=group8,x='mean_author_num',y='category_name')
<matplotlib.axes._subplots.AxesSubplot at 0x1ca772646d0>
![图片名称](https://img-blog.csdnimg.cn/20210130212237937.png)
3使用Excel分析
3.1创建数据透视表
- 将存储的csv文件另存为excel文件,并随便创建打开一个excel文件
- 点击数据选项卡-获取外部数据-现有连接
- 点击浏览,选择上面保存的
data_processed.xlsx
文件 - 更改属性,输入sql语句:
select * from [D:\code\Github\data\AcademicTrendsAnalysis\data_processed.xlsx].[data_processed$]A left join [D:\code\Github\data\AcademicTrendsAnalysis\categories.xlsx].[categories$]B on A.category = B.categories
![图片名称](https://img-blog.csdnimg.cn/20210130212739928.jpg)
3.2不同大类的论文数量随时间的变化趋势
- 在数据透视表中选择
![图片名称](https://img-blog.csdnimg.cn/20210130212914855.jpg)
![图片名称](https://img-blog.csdnimg.cn/2021013021300784.jpg)
![图片名称](https://img-blog.csdnimg.cn/20210130213037706.jpg)
![图片名称](https://img-blog.csdnimg.cn/2021013021310368.jpg)
4使用tableau进行分析
4.1计算机领域论文数量差异
![图片名称](https://img-blog.csdnimg.cn/20210130213144456.jpg)
4.2计算机领域论文数量变化(top5)
![图片名称](https://img-blog.csdnimg.cn/20210130213210937.jpg)
4.3计算机领域论文页数差异
![图片名称](https://img-blog.csdnimg.cn/20210130213249307.jpg)
总结
总的来说,python,excel,tableau都能完成上述分析可视化任务,但是各有优缺点:
- python:
- 适合做不规则数据的处理
- 适合进行各种算法建模
- 适合进行预测分析
- excel:
- 适合小量规则数据的分析与可视化
- 数据格式较为局限,数据量不易过大
- tableau
- 适合大量数据的分析与可视化
- 操作简单,比python敲代码作图更快捷