学术前沿趋势分析Task1:论文数据统计

论文数据统计

  • 1. 研究目的
  • 2. 数据
    • (1) arXiv数据集
    • (2) 网站爬虫
  • 3. 思路和代码
    • (1)获得2019年往后的论文
      • a. 读取arXiv数据集
      • b. 筛选2019年往后的论文
      • c. 拆分categories*(教程以外的东西)
    • (2)爬取所有类别
    • (3)合并前两步的结果
    • (4)数据分析
      • a. 饼图
      • b. 查看细分子类信息

DataWhale数据分析打卡营
开源内容

1. 研究目的

统计2019年及以后全年计算机各个方向论文的数量

2. 数据

(1) arXiv数据集

Kaggle上的一个数据集,可以理解为计算机领域论文信息库。
是一个有很多行的表,每一行代表一篇论文,记录每一篇论文的作者、标签、发表年份等信息。

学术前沿趋势分析Task1:论文数据统计_第1张图片

(2) 网站爬虫

https://arxiv.org/category_taxonomy
ArXiv数据集中一篇论文会有多个标签,标签一般是某领域下的细分方向,比如NLP之于人工智能。
因此通过网页爬虫,可以获得领域下所有的细分方向信息,这样在已知文章标签的情况下,就能对应为之匹配一个大方向了。

学术前沿趋势分析Task1:论文数据统计_第2张图片
学术前沿趋势分析Task1:论文数据统计_第3张图片

3. 思路和代码

代码来自Datawhale开源内容,只做了重新编排,非原创

(1)获得2019年往后的论文

a. 读取arXiv数据集

import json
import pandas as pd

def readArxivFile(path, columns=['id', 'submitter', 'authors', 'title', 'comments', 'journal-ref', 'doi',
       'report-no', 'categories', 'license', 'abstract', 'versions',
       'update_date', 'authors_parsed'], count=None):
    '''
    定义读取文件的函数
        path: 文件路径
        columns: 需要选择的列
        count: 读取行数
    '''
    
    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('arxiv-metadata-oai-snapshot.json', ['id', 'categories', 'update_date'])

学术前沿趋势分析Task1:论文数据统计_第4张图片

b. 筛选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) #重新编号

学术前沿趋势分析Task1:论文数据统计_第5张图片

c. 拆分categories*(教程以外的东西)

看代码的时候发现的小漏洞,目前的代码中有多个标签的文章是不能完成下一步的merge的。
但因为我只停留在阅读代码的阶段,就也没有自己实现了。大意如下

  1. 如果这一行的categories里的内容split之后len>1
  2. 循环切分之后的东西,在表的最后添加行
  3. 修改当前行的categories

学术前沿趋势分析Task1:论文数据统计_第6张图片

(2)爬取所有类别

from bs4 import BeautifulSoup #用于爬取arxiv的数据
import re #用于正则表达式,匹配字符串的模式
import requests #用于网络连接,发送网络请求,使用域名获取对应信息
import pandas as pd #数据处理,数据分析

#爬取所有的类别
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"])

学术前沿趋势分析Task1:论文数据统计_第7张图片

(3)合并前两步的结果

# 合并
_df = data.merge(df_taxonomy, on="categories", how="left").drop_duplicates(["id","group_name"])

# 分类、聚合、排序、重新编号
_df = _df.groupby("group_name").agg({
     "id":"count"}).sort_values(by="id",ascending=False).reset_index()

学术前沿趋势分析Task1:论文数据统计_第8张图片

(4)数据分析

a. 饼图

import matplotlib.pyplot as plt #画图工具
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()

学术前沿趋势分析Task1:论文数据统计_第9张图片

b. 查看细分子类信息

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")

学术前沿趋势分析Task1:论文数据统计_第10张图片

你可能感兴趣的