美文网首页python
用Python实现科研自动化

用Python实现科研自动化

作者: 兴富同学 | 来源:发表于2020-02-20 22:04 被阅读0次

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

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

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

    一、报告结构的拟定

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

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

    二、PDF内容提取

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

    在python中,提取PDF内容的包有pdfminer、tabula、pdfplumber等(引自:Python:解析PDF文本及表格——pdfminer、tabula、pdfplumber 的用法及对比),都大同小异。经过对比选择了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,太占用专业学习的时间。这种报告只是信息的简单叠加,并不具备自主分析的效果,论文还是得自己写[微笑]。能实现一个想法总还是一件开心的事情,程序最大的特点就是复用性,以后就当做写文献综述前的预处理流程吧。大家如果对报告或者源码感兴趣,欢迎在后台留言与我交流哇!

    相关文章

      网友评论

        本文标题:用Python实现科研自动化

        本文链接:https://www.haomeiwen.com/subject/sbxfqhtx.html