科技政策文本分词后在Jupyter Notebook中用TextRank做关键词提取

2021-8-20 10:58| 发布者: Fuller| 查看: 3595| 评论: 2

摘要: 1,背景说明在上一篇《Jupyter Notebook使用Python做TextRank关键词提取测试》中,我们手工构造出来词数组做实验,实验了TextRank关键词提取算法,最后输出显示提取到的前10个关键词和权重。但是,手工构造数组只能 ...

1,背景说明

在上一篇《Jupyter Notebook使用Python做TextRank关键词提取测试》中,我们手工构造出来词数组做实验,实验了TextRank关键词提取算法,最后输出显示提取到的前10个关键词和权重。但是,手工构造数组只能用于实验,要用于实际场景,需要一种自动化的手段把文章变成词数组,这个分词过程有很多软件可以选用,本文介绍将GooSeeker文本分词和TextRank结合在一起使用。另外,分析结果只是显示出来也不好使用,本notebook将把分析结果作为新插入的一列存放在excel中。那么整个过程就顺畅了:

1. 如果有很多篇或者很多段文本需要处理,那么存入excel,一行一条数据

2. 导入GooSeeker文本分析软件,导出也是excel

3. 用本Notebook介绍的方法处理导出的excel,处理结果作为新加的列,得到的还是excel文件

概括一下,今天这个Jupyter Notebook,把GooSeeker网络爬虫软件收集的科技政策文本内容导入GooSeeker文本分词和情感分析工具做分词,然后导出分词效果表,针对分词效果表使用TextRank算法做进一步的关键词提取。主要是为了演练textRank编程,其实GooSeeker文本分词和情感分析工具有自己的关键词提取功能,可以对比一下分析的效果。

1.1,什么是TextRank

参看上一篇《Jupyter Notebook使用Python做TextRank关键词提取测试》,在此不再赘述。

1.2,本模板适应的场景

本模板根据GooSeeker分词和文本分析软件生成的分词效果表,对数据进行基本处理后,做进一步TextRank计算处理。

1.3,使用方法

基本操作顺序是:

1. 在GooSeeker分词和文本分析软件上进行任务创建并导入包含原始内容的excel,并导出分词效果表

2. 将导出的分词效果表放在本notebook的data/raw文件夹中

3. 从头到尾执行本notebook的单元

注意:每个notebook项目目录都预先规划好了,具体参看Jupyter Notebook项目目录规划参考。如果要做多个分析项目,把整个模板目录专门拷贝一份给每个分析项目。

2,数据源

数据源是GooSeeker分词和文本分析软件生成的分词效果表。 原始数据是使用GooSeeker采集得到的科技政策文本。供参考和实验。

将要分析的文本内容以Excel格式导入GooSeeker分词软件,几分钟后就能得到词频词性表和分词效果表。如果还做了关键词筛选,还可以生成共词矩阵和社交关系图。另外情感分析也可自动执行,也可以配置自己的情感词库和文本分类关键词。下图显示的是从集搜客分词和文本分析软件导出的分词效果表数据,下面我们会读取这个excel并且把"分词数据"这一列"做处理和转换。

3,修改历史

2021-08-19:第一版发布

4,版权说明

本notebook是GooSeeker大数据分析团队开发的。本notebook中代码可自由共享使用,包括转发、复制、修改、用于其他项目中。 

5,准备程序环境

5.1,引入numpy库

Numpy是一个常用的Python科学技术库,通过它可以快速对数组进行操作,包括形状操作、排序、选择、输入输出、离散傅立叶变换、基本线性代数,基本统计运算和随机模拟等。许多Python库和科学计算的软件包都使用Numpy数组作为操作对象,或者将传入的Python数组转化为Numpy数组,因此在Python中操作数据离不开Numpy。

Numpy的核心是ndarray对象,由Python的n维数组封装而来,但通过C语言预编译相关的数组操作,因此比原生Python具有更高的执行效率,但仍然使用Python语言编码,这样就同时具有简洁的代码和高效的运行速度。ndarry与数组有些区别值得注意,numpy数组中的元素都具有相同的类型,并且在创建时就确定了固定的大小,这与Python数组对象可以动态增长不同。

# coding:utf-8    

import numpy as np 


5.2, 引入math库

math库是python提供的内置数学类函数库,math库不支持复数类型,仅支持整数和浮点数运算。math库一共提供了4个数字常数和44个函数。44个函数共分为4类,包括16个数值表示函数,8个幂对数函数,16个三角对数函数和4个高等特殊函数。

import math


5.3,引入collections库下的Counter

Counter(计数器)是对字典的补充,用于追踪值的出现次数。 Counter是一个继承了字典的类(Counter(dict))

from collections import Counter


5.4,定义阻尼系数和最大迭代数

阻尼系数:其意义是,在任意时刻,用户到达某页面后并继续向后浏览的概率;该数值是根据上网者使用浏览器书签的平均频率估算而得

pr_config = {'alpha': 0.85, 'max_iter': 100}


5.5,定义滑动窗口的词语数

同时出现在滑动窗口里的词语,就认为他们直接存在共现关系

windows = 3


5.6,定义把词转换成矩阵的函数word_adj_matrix

def word_adj_matrix(words_pro, windows, word_num, word_index):

    """

    Adjacency Matrix

    :param windows:

    :return:

    """

    def _word_combine(words, window):

        """

        Keyword arguments:

        :param window:

        """

        if window < 2: window = 2

        for x in range(1, window):

            if x >= len(words):

                break

            words2 = words[x:]

            res = zip(words, words2)

            for r in res:

                yield r

    matrix = np.zeros((word_num, word_num))

    for words in words_pro:

        for w1, w2 in _word_combine(words, windows):

            if w1 in word_index and w2 in word_index:

                index1 = word_index.get(w1)

                index2 = word_index.get(w2)

                matrix[index1][index2] = 1.0

                matrix[index2][index1] = 1.0

    return matrix


5.7,定义函数_build_adjacency_matrix

功能是返回邻接矩阵

def _build_adjacency_matrix():

    adj_matrix = word_adj_matrix(words_pro,windows,word_num,word_index)

    return adj_matrix


5.8,定义函数words_info用于提取文本中的词信息

def words_info(words_list):

    """

    :param words_list:

    :return:

    """

    word_index = dict()

    index_word = dict()

    word_num = 0

    #for index_s, words in enumerate(words_list):

    for index_s, words in enumerate(words_list):

        for index_w, word in enumerate(words):

            word_index[word] = word_num

            index_word[word_num] = word

            word_num += 1

    return word_index, index_word, word_num


5.9,定义按分数高低排序的函数

def get_sorted_items(scores, index_items):

    """

    :param scores:

    :param index_items:

    :return: list[tuple]

    """

    items_scores = dict()

    for index, score in scores.items():

        items_scores[index_items.get(index)] = score

    sorted_items = sorted(items_scores.items(), key=lambda item: item[1], reverse=True)

    return sorted_items


5.10,定义打分函数

def _score_items():

    adj_matrix = _build_adjacency_matrix()

    scores = cal_score(adj_matrix, **pr_config)

    sorted_items = get_sorted_items(scores, index_word)

    return sorted_items

def cal_score(ad_matrix, alpha=0.85, max_iter=100):

    N = len(ad_matrix)

    ad_sum = ad_matrix.sum(axis=0).astype(float)

    ad_sum[ad_sum == 0.0] = 0.001

    ad_matrix = ad_matrix / ad_sum

    pr = np.full([N, 1], 1 / N)

    for _ in range(max_iter):

        pr = np.dot(ad_matrix, pr) * alpha + (1 - alpha)

    pr = pr / pr.sum()

    scores = dict(zip(range(len(pr)), [i[0] for i in pr]))

    return scores

6,计算TextRank

6.1,设定要分析的文件名变量

因为GooSeeker分词软件会分门别类导出好几张表,为了让程序更通用,比如,针对多个分析任务套用同一个notebook模板的时候,我们将每张表都给一个变量,后面的代码还会探测这次分析任务导出了哪几张表,因为并不是每次分析任务导出所有的表。

使用以下变量对应GooSeeker分词结果表:

file_word_freq:词频表

file_seg_effect: 分词效果表

file_word_choice_matrix: 选词矩阵表

file_word_choice_match: 选词匹配表

file_word_choice_result: 选词结果表

file_co_word_matrix: 共词矩阵表

下面的代码将对上述词频表名变量赋值

import pandas as pd

import os

%xmode Verbose

import warnings

warnings.filterwarnings("ignore", category=DeprecationWarning)

# 存原始数据的目录

raw_data_dir = os.path.join(os.getcwd(), '..\\..\\data\\raw')

# 存处理后的数据的目录

processed_data_dir = os.path.join(os.getcwd(), '..\\..\\data\\processed')

filename_temp = pd.Series(['分词效果'])

file_seg_effect = ''


6.2,检测data\raw目录下是否有分词效果表

# 0:'词频', 1:'分词效果', 2:'选词矩阵', 3:'选词匹配', 4:'选词结果', 5:'共词矩阵'

print(raw_data_dir + '\r\n')

for item_filename in os.listdir(raw_data_dir):

    if filename_temp[0] in item_filename:

        file_seg_effect = item_filename

        continue

if file_seg_effect:

    print("分词效果excel表:", "data\\raw\\", file_seg_effect)

else:

    print("分词效果excel表:不存在")


输出结果:

C:\Users\work\workspace_219\notebook\科技政策文本分词后在Jupyter Notebook中做TextRank关键词提取\notebook\eda\..\..\data\raw

分词效果excel表: data\raw\ 分词效果_202108191801041740.xlsx


6.3,读取分词效果表

以下的演示以GooSeeker分词和文本分析软件生成的分词效果excel表为例,需要把分词效果表放到本notebook的data/raw文件夹下

df = pd.read_excel(os.path.join(raw_data_dir, file_seg_effect))


6.4,在打开的excel最右边新增1列“TEXT_RANK关键词”

df["TEXT_RANK关键词"] = ''


6.5,查看excel表前10行数据

df.head(10)


输出结果:

已有的“关键词”列是GooSeeker分词工具提取的关键词,新增的“TEXT_RANK关键词”列目前的值是空的


6.6,把表格的“分词数据”这一列取出来

把“分词数据”这一列取出来,添加到corpus,作为已经分词的语料库

corpus = []

for item in df["分词数据"]:

    temp_corpus = item.split(' ')

    for word in item.split(' '):

        if len(word) < 2 or word.isnumeric():

            temp_corpus.remove(word)

    corpus.append(temp_corpus)

6.7,设置每篇政策文本提取10个关键词

如果需要更多或更少的关键词,请更改下面这条赋值语句

topN = 10


6.8,提取textrank关键词并更新到数据表格

下面的代码执行了这些步骤

1. 调用前面定义的提取TEXTRANK关键词的函数提取textrank关键词

2. 更新数据表格的“TEXT_RANK关键词”

3. 输出显示

for i in range(len(df["分词数据"])):

    words_pro = []

    temp_corpus = df.loc[i,"分词数据"].split(' ')

    for word in df.loc[i,"分词数据"].split(' '):

        if len(word) < 2 or word.isnumeric():

            temp_corpus.remove(word)

    words_pro.append(temp_corpus)

    word_index, index_word, word_num = words_info(words_pro)

    adj_matrix = _build_adjacency_matrix()

    scores = cal_score(adj_matrix, **pr_config)

    sorted_items = get_sorted_items(scores, index_word)

    sorted_words = _score_items()

    keywords = ""

    for item in sorted_words[:topN]:

        keywords = keywords + item[0] + ' '

    df.loc[i,"TEXT_RANK关键词"] = keywords

    print("\n第",i,"条政策文本的关键词")

    print(sorted_words[:topN])

输出结果:

第 0 条政策文本的关键词

[('企业', 0.030537220641375543), ('孵化器', 0.029326523521867653), ('孵化', 0.01888716094275578), ('服务', 0.01435383212873991), ('规定', 0.0128220280660225), ('符合', 0.011751041509823435), ('通知', 0.01056628781400521), ('国务院', 0.010427083198358666), ('以及', 0.009467811570966789), ('技术', 0.008629746983426041)]

第 1 条政策文本的关键词

[('科普', 0.0517770619145013), ('进口', 0.03818635601941905), ('影视作品', 0.033903531035746746), ('海关', 0.023863118806901965), ('自用', 0.020802865875535852), ('附件', 0.019725799764758807), ('单位', 0.018621252020844213), ('税号', 0.01825668802766264), ('财政厅', 0.016250690512045647), ('免征', 0.01613167180872872)]

第 2 条政策文本的关键词

[('高新技术', 0.04499971276627806), ('扣除', 0.03934010083007902), ('企业', 0.03778574867126375), ('通知', 0.03377342039414448), ('超过', 0.029755586476563418), ('纳税', 0.029395545191444574), ('准予', 0.02605426954492502), ('部分', 0.026043864180514093), ('直辖市', 0.022623238751469373), ('计划单列市', 0.02169452641468901)]

第 3 条政策文本的关键词

[('退税', 0.025903585119184166), ('设备', 0.023051246457128118), ('研发', 0.02155339421972629), ('机构', 0.020493358120976097), ('增值税', 0.01936835223541849), ('办法', 0.015031912064786034), ('专用发票', 0.014194233159511377), ('申报', 0.012346737946633398), ('税务机关', 0.012142239154225533), ('办理', 0.01152996634990225)]

第 4 条政策文本的关键词

[('项目', 0.019804317870416473), ('管理', 0.013361217531807697), ('单位', 0.009731264380739025), ('科研人员', 0.009099099053884015), ('预算', 0.008053874148304748), ('实施', 0.007920682151137356), ('相关', 0.007876005641957434), ('按照', 0.00769109605057812), ('要求', 0.007631211521982601), ('有关', 0.0064658345175094886)]

第 5 条政策文本的关键词

[('研发', 0.029539521612577842), ('委托', 0.02396639128428067), ('企业', 0.022199205247966647), ('费用', 0.02074751815697064), ('科技', 0.01782749880163866), ('境外', 0.012950649924443626), ('国家税务总局', 0.012905130716038245), ('委托方', 0.012530079152198089), ('按照', 0.010758348913311896), ('规定', 0.010645527324543507)]

第 6 条政策文本的关键词

[('科技', 0.041619794961853446), ('中小企业', 0.03335898740007286), ('科技型', 0.029518936263016122), ('研发', 0.02560507683632247), ('扣除', 0.024970211962771903), ('财政部', 0.020158980599629877), ('按照', 0.020117009254759868), ('费用', 0.019775223287313157), ('无形资产', 0.017773567563198367), ('信息', 0.01720381781696859)]

第 7 条政策文本的关键词

[('企业', 0.023609278335108806), ('投资', 0.02269769842067623), ('规定', 0.014400986196642453), ('通知', 0.012252994023255555), ('创业投资', 0.01114140506168942), ('科技型', 0.010001043378892613), ('抵扣', 0.009929459694811606), ('包括', 0.009769201531600206), ('按照', 0.008917394749798382), ('初创', 0.008774691548179994)]

第 8 条政策文本的关键词

[('科技', 0.037469199928811606), ('孵化', 0.020228109996280347), ('空间', 0.0183626002237261), ('通知', 0.01763754445435012), ('国家级', 0.016919443179314833), ('对象', 0.015516984408979173), ('认定', 0.01537624699029698), ('房产', 0.013693962257964487), ('省级', 0.013484750409654004), ('信息', 0.012986521208314544)]

第 9 条政策文本的关键词

[('创新', 0.042813253356874185), ('进口', 0.031036329164496647), ('关于', 0.027678899828996364), ('国务院', 0.027611312526538978), ('附件', 0.02504022321031246), ('科技', 0.024501313310444844), ('国家税务总局', 0.02305462845374898), ('关税', 0.02275679256994801), ('海关总署', 0.022176153621586907), ('清单', 0.021653255896433073)]

第 10 条政策文本的关键词

[('进口', 0.020515830609200897), ('通知', 0.015115504345771512), ('科学', 0.0138279311941438), ('科技', 0.013447825650870576), ('核定', 0.01300494704323723), ('会同', 0.011402687365001154), ('国家', 0.0107713279449894), ('研究', 0.01053281956434924), ('单位', 0.01045824701950697), ('有关', 0.00990560571522543)]

第 11 条政策文本的关键词

[('研发', 0.019942121074756684), ('费用', 0.019763942605237946), ('企业', 0.016791143617951403), ('扣除', 0.011772253655374699), ('活动', 0.011408997714308386), ('进行', 0.008925124567480942), ('技术', 0.007457158637673534), ('通知', 0.0074198157666777185), ('加计', 0.006773668551528625), ('产品', 0.006734870734799389)]

第 12 条政策文本的关键词

[('研发', 0.01990548848323355), ('费用', 0.019728118815426552), ('企业', 0.01676545775374172), ('扣除', 0.011753891838262637), ('活动', 0.011388164406543552), ('进行', 0.00890933879068054), ('技术', 0.007442194677881555), ('通知', 0.0074102106560500055), ('加计', 0.006763494796596411), ('产品', 0.0067214587749980705)]


6.9,显示已经填充了“TEXTRANK关键词”字段值后的表格的前10行

可以对比下“关键词”和“TEXTRANK关键词”这2列的数据,这是用不同算法提取的关键词,可能有差异。

df.head(10)


7,下载notebook

下载notebook源代码请进:用TextRank算法从科技政策文本中提取关键词


鲜花

握手

雷人

路过

鸡蛋
发表评论

最新评论

评论 Fuller 2022-7-27 11:24
13153337949: 怎么看汇总的关键词,就是所有数据中哪个关键词权重最高
导出词频词性表,可以看词频
评论 13153337949 2022-7-27 11:15
怎么看汇总的关键词,就是所有数据中哪个关键词权重最高

查看全部评论(2)

GMT+8, 2024-10-11 14:43