专栏首页机器学习与生成对抗网络用Python实现科研自动化

用Python实现科研自动化

这个学期如期开课了,虽然是在家里。这学期我导开了一门《高等教育管理专题研究》,一口气给了11个专题。为了对这11个专题的文献分布情况有一个粗略的印象,我觉得都得找相关的文献来看看,但是11个专题都要重新检索一遍,重复性工作让人头秃……于是,我写了个python脚本,自动生成各个主题的关键词和引文分布情况的报告,效果如下图。

看到点击“运行”不到3秒钟就自动生成了6000字左右“像模像样”的报告,不禁流下激动的泪水。

要是有一天能写个程序能将我的想法整理成论文就好了[狗头]。为了留存这个美好的幻想,我把报告生成的思路记录下来,权当为以后积累点技术基础。编程思路包括:提取PDF内容、CSSCI文献题录数据的格式处理、关键词词频计算、引文数据统计、关键词共被引网络生成、word的自动编写与插入(包括样式、表格等)

一、报告结构的拟定

写报告的思路比较固定,我个人的体会是:叙述要求、描述数据和展示结果。那么每个一级标题下,先附上老师的要求,然后描述数据在哪里下载的,最后将结果数据的图表展示出来。按照这个思路走下来了,将每个部分的模板编写为如下这样。

确定了报告框架之后,下面的事情便变得简单,把内容填上去,在写个循环语句,报告就完成了,下面说的都是如何填空的事情。

二、PDF内容提取

我导给了一个PDF,需要把PDF的一级标题和二级标题的内容提取出来,填充themeName和themeKeyword部分。

在python中,提取PDF内容的包有pdfminer、tabula、pdfplumber等(引自:Python:解析PDF文本及表格——pdfminer、tabula、pdfplumber 的用法及对比[1]),都大同小异。经过对比选择了pdfplumber,没安装的话需要先安装一下。

pip install pdfplumber

主要代码如下。

pdfPath = 'Auto_data/course_text/2019-2020春季学期《高等教育管理专题研究》拟研究专题.pdf'
pdf = pdfplumber.open(pdfPath)
for p in pdf.pages:
    test = p.extract_text().split('\n')

通过上述代码就可以提取PDF的所有内容。但是想要正确提取内容还有其他的工作,使用正则表达式根据标题的特点提取一级和二级标题内容、编程将全角标点变成半角标点、去掉标题中的中文和英文标点等、将一级标题和二级标题内容建立对应关系等。非主干代码占了所有代码量的80%以上,真特么的符合“二八法则”。

三、文献题录数据下载与提取

在一个主题词下载之前,先确定该主题的文献检索方式。把下图的检索方式使用代码进行整理,便可以得到searchWord和searchWay。

themeKeyword = '、'.join(themes_keypoints[ii])
searchWord, searchWay = search_type(ii, searchWord_group)

def wordM(word):
    word = "“" + word + "”"
    return word

def search_type(i, searchWord_group):
    word_group = searchWord_group[i]
    slen = len(word_group)
    if (slen > 1):
        endLen = slen - 1
        searchWay = ',检索方式为:'+ word_group[endLen]
        searchWord = '、'.join(word_group[:endLen])
    else:
        searchWord = word_group[0]
        searchWay = ''
    return searchWord, searchWay

随后,在CSSCI官网,下载文献题录数据。

下载下来的数据是这样的。

对了,原来以为有数据规模会很大(并不大),所以使用如下代码生成了一个Windows批处理文件,可以达到一键生成文件夹目录的效果。

file_name = 'Auto_data/lite_data/themes_list.bat'
with open(file_name, "w") as f:
    index = 0
    for i in range(len(themes_group)):
        index = int(index) + 1
        if index < 10: # 记得加0,不然不按顺序
            index = '0' + str(index)
        else:
            index = str(index)
        contant = 'md '+ index + '_' + themes_group[i] + ' '
        f.writelines(contant)
        f.writelines('\n')

在下载得到数据后,需要对数据信息进行提取,提取的信息包括:标题、第一作者、关键词、发表时间、参考文献。标识符如下。

matching_columns = ['【来源篇名】','【第一作者】','【关 键 词】','【年代卷期】','【参考文献】']
separator = '-----------------------------------------------------------------------'

使用正则表达式匹配相关信息,使用.replace函数去掉标识符,再进行其他操作,将信息放入字典中,便完成了信息提取工作。核心代码如下:

for i in range(len(matching_columns)):
    m = matching_columns[i]
    isMatching = re.match(m, curData) #把标题、作者等信息放入字典中
    if isMatching:
        if (i == 0):
            data_dict['article'] = curData.replace(m,'')
        elif (i == 1):
            data_dict['author'] = curData.replace(m,'')
        elif (i == 2):
            data_dict['keyword'] = curData.replace(m,'')
        elif (i == 3):
            data_dict['year'] = curData.replace(m,'').split(',')[0]
        elif (i == 4):
            isReference = 1
isSeparator = re.match(separator, curData)

在完成信息提取之后,生成了这一个主题的题录信息字典data_dict,通过len(data_dict)可以知道这一个主题一共有多少条文献题录数据。

searchNum = len(data_dict)

四、关键词与引文数据统计

关键词的词频计算使用的是类似Excel的数据透视表的方法写成的,这一点在《如何用python表白》一文中已经讲到,计算函数如下。其中,words_count.head(10)是输出到word中的排名前10的关键词,len(set(all_words))是关键词的数量,对应word中的词频分布表和关键词个数keywordNum。

def all_words(df):
    all_words = []
    for w in df['keyword']:
        w_group = w.split('/')
        all_words.extend(w_group)
    print('关键词次数:',len(all_words))
    print('关键词个数:',len(set(all_words))) #使用set方法
    print('\n')

    df_word = pd.DataFrame({'word': all_words})
    words_count = df_word.groupby(by=['word'])['word'].count()
    words_count = words_count.to_frame()
    words_count.columns = ['count']
    words_count = words_count.sort_values(by='count', ascending=False)
    print(words_count.head(10))
    return all_words, words_count, len(set(all_words))

引文数据的提取编程思路类似, references_count.head(10)是输出到word中的被引量排名前10的参考文献。

def all_references(df):
    all_references = []
    for r in df['reference']:
        r_group = r.split('/')
        all_references.extend(r_group)
    print('\n')
    print('引用文献次数:',len(all_references))
    print('引用文献篇数:',len(set(all_references))) #使用set方法

    df_references = pd.DataFrame({'reference': all_references})
    references_count = df_references.groupby(by=['reference'])['reference'].count()
    references_count = references_count.to_frame()
    references_count.columns = ['count']
    references_count = references_count.sort_values(by='count', ascending=False)

    for index in list(references_count.index):
        if not isRef(index):
            references_count.drop(index)

    print(references_count.head(10))
    return references_count

五、关键词共现网络的生成

由于需要分析,关键词共现网络以截图的方式放入报告中,有一些结果还是很好的,可以说很好看了,比如下面这张,很容易给像我这样的博士研究生以思考的启发,比如可以这么说:“创新创业教育的生长,根基在于创新创业活动的开展,课程体系是连接两者的关键因素。此外,创新创业教育还涉及教学改革、教学组织模式、高校人才培养、教学策略的运用等多方面的内容……”

其他的也有好看的,比如“产教融合”的图,中心词、核心词和外围词都十分完整,十分便于分析。

六、word的自动编写

当我们所有的内容都准备好之后,就可以考虑word的自动生成了。我使用的模块是python-docx,没安装的话需要事先安装一下。

pip install python-docx

安装完成后,导入自己已经调好样式的空白word页面。

document = Document('Auto_data/result/input.docx')

先将我们的内容以字符串的形式存储在几个变量中。

first_para = '专题下的思考方向包括:'+ themeKeyword + '。'
second_para = '使用CSSCI进行检索,检索词为:'+ str(searchWord) + str(searchWay) + '。共下载文献题录数据' + str(searchNum) + '条,所有文献一共涉及关键词' + str(keywordNum) + '个,词频分布如下。'
third_para = '关键词共现网络如下。'
fourth_para = '被引用次数排名前10的文献如下。'

使用document.add_paragraph方法就可以将我们的内容以段落的形式插入word中,style可以选择样式,例如'Heading 2'是指二级标题样式,'Normal'是指正文样式。

t1 = document.add_paragraph(themeName, style = 'Heading 2')
p1 = document.add_paragraph(first_para, style = 'Normal')
p2 = document.add_paragraph(second_para, style = 'Normal')

表格的插入比较麻烦。先使用document.add_table生成题头。然后使用.add_row().cells方法增加行,使用for循环进行对表格单元格进行赋值,完成表格的生成。

table1 = document.add_table(rows=1, cols=4, style='网格型1')
hdr_cells = table1.rows[0].cells
hdr_cells[0].text = '关键词'
hdr_cells[1].text = '词频'
hdr_cells[2].text = '关键词'
hdr_cells[3].text = '词频'
table_size = int(maxKeyword/2)
for i in range(table_size):
    another_i = i + table_size
    row_cells = table1.add_row().cells
    row_cells[0].text = t1_data.index[i]
    row_cells[1].text = str(t1_data['count'][i])
    row_cells[2].text = t1_data.index[another_i]
    row_cells[3].text = str(t1_data['count'][another_i])

之后,使用for循环,将11个专题的内容都放入word中,使用document.save保存word,这样,我们6000字的报告就生成啦!

document.save('Auto_data/result/11个专题下的文献计量分析.docx')

写在后面

在思考编程过程的时候,觉得这并不是什么难事,下载数据、提取信息、生成word就完事了。

但是……想法一时爽,编程编断手,虽然报告的生成仅仅需要不到3秒钟,但是累计编程时间超过9个小时,中间涉及正则表达式、字符的unicode编码等新知识点,以及许多大大小小的bug,太占用专业学习的时间。这种报告只是信息的简单叠加,并不具备自主分析的效果,论文还是得自己写[微笑]。能实现一个想法总还是一件开心的事情,程序最大的特点就是复用性,以后就当做写文献综述前的预处理流程吧。大家如果对报告或者源码感兴趣,欢迎在后台留言与我交流哇!

References

[1] Python:解析PDF文本及表格——pdfminer、tabula、pdfplumber 的用法及对比: https://www.cnblogs.com/gl1573/p/10064438.html

本文分享自微信公众号 - 机器学习与生成对抗网络(AI_bryant8)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-02-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ECCV 2020 的对抗相关论文(对抗生成、对抗攻击)

    本文汇总了ECCV 2020上部分对抗相关论文,后续公众号会随缘对一些paper做解读。感兴趣的同学,可先自行根据标题,搜索对应链接(有些paper可能未公布)...

    公众号机器学习与生成对抗网络
  • 使用GAN生成序列数据

    【导读】序列数据十分常见,但由于隐私,法规限制了对有用数据的访问,这极大地减慢了对研发至关重要的有用数据的访问。因此产生了对具有高度代表性但又完全私有的合成序...

    公众号机器学习与生成对抗网络
  • 伯克利《生成对抗网络》综述

    https://sites.google.com/view/berkeley-cs294-158-sp20/

    公众号机器学习与生成对抗网络
  • Confluence 6 可以自定义的元素

    有一些下面的 UI 元素被用在特定的主题中,配色方案的修改可能不会对这些元素有效。

    HoneyMoose
  • 一封情书

    亲爱的小芳姑娘:   你好呀!茫茫人海中,我们因路由器而邂逅,因网线而相识,因无线而相知。自从第一眼看见你,你就犹如一鲁棒的系统而深深地吸引了我:你如C脱胎于...

    范蠡
  • JS(javascript)入门

    起因是在用python的Django做一个页面,需要对原先的文章进行修改,怎么在文本框中填充原先的数据?由于文本框使用了富文本编辑器,发现不只是简单的在inpu...

    小末快跑
  • 简述闪电网络历史:一个与比特币同样伟大想法的历程

    区块链大本营
  • TensorFlow 是如何解读深度学习中的“嵌入”

    一个单词集合,这些属于离散的非数值型对象,数值计算的基本要求是数值型,所以需要将他们映射为实数向量。

    double
  • 深度学习之DNN与前向传播算法

    关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第二 【Python】:排名第三 【算法】:排名第四 前言 深度神经网络(Deep Neu...

    昱良
  • LeetCode <bt>79&212 Word Search I&II

    Given a 2D board and a word, find if the word exists in the grid.

    大学里的混子

扫码关注云+社区

领取腾讯云代金券