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算法从科技政策文本中提取关键词 |