采集的文章和关键词不符(本文一步步为你演示如何用Python实现中文关键词提取这一)
优采云 发布时间: 2021-11-09 11:24采集的文章和关键词不符(本文一步步为你演示如何用Python实现中文关键词提取这一)
本文将一步步教你如何用Python从中文文本中提取关键词。如果你需要“粗略看”一篇长文,不妨试一试。
2017-12-07-20-38-22-7-426487.png
需要
我朋友最近对自然语言处理很感兴趣,因为他打算用自动化的方法从长文本中提取关键词来确定主题。
他问我方法,我推荐他阅读我的“如何在 Python 中从海量文本中提取主题?” ”。
看完后,他说很有收获,只是应用场景和自己的需求有些不同。
《如何使用Python从海量文本中提取主题?》本文面对海量文档,利用主题发现功能对文章进行聚类。而且他不需要处理很多文档,也不需要聚类,但是每个需要处理的文档都很长,他希望通过自动化的方法从长文本中提取关键词得到一个粗略的想法。
突然发现之前忘记写文章了,介绍了提取单个文本的方法关键词。
虽然这个功能实现起来并不复杂,但也有一些坑需要避免。
通过这篇文章,我将一步步的为大家展示如何使用Python实现中文关键词提取功能。
环境 Python
第一步是安装 Python 运行时环境。我们使用集成环境Anaconda。
请到此网站下载最新版本的 Anaconda。向下滚动页面以找到下载位置。网站会根据您当前使用的系统自动推荐合适的版本供您下载。我使用的是 macOS,下载文件格式为 pkg。
2017-12-03-22-19-31-2-856072.png
下载页面区域左侧为Python3.6版本,右侧为2.7版本。请选择2.7 版本。
双击下载的pkg文件,按照中文提示一步步安装。
2017-12-03-22-19-31-2-856170.jpeg
样本
我专门为大家准备了一个github项目来存放本文的配套源码和数据。请从该地址下载压缩包文件,然后解压。
解压后的目录名为demo-keyword-extraction-master,示例目录收录以下内容:
2017-12-7_21-24-56_snapshots-01.jpg
除了github项目默认的描述文件README.md外,目录下还有两个文件,分别是数据文件sample.txt和程序源代码文件demo-extract-keyword.ipynb。
口吃分词
我们使用的关键词 提取工具是stutter 分割。
之前在《如何用Python做中文分词?》在文章中,我们使用了这个工具来分割中文句子。这次我们使用了它的另一个功能,即关键词提取。
请进入终端,使用cd命令进入解压后的文件夹demo-keyword-extraction-master,输入如下命令:
pip install jieba
好了,软件包工具也准备好了。下面我们执行
jupyter notebook
进入 Jupyter 笔记本环境。
图像.png
至此,环境准备就绪,下面来介绍一下本文使用的中文文本数据。
数据
一开始,我很担心找不到现成的中文文本。
在互联网上可以找到大量的中文文本。
但是如果是用来演示的,不知道会不会有版权问题。如果你的任何作品被用于分析,人们可能会问,“你从哪里得到这个电子版?”
如果我一次又一次地提起诉讼,我将无法抗拒。
后来发现我只是自找麻烦——找别人的文字怎么办?用我自己的不是更好吗?
一年多来,我写了90多篇文章文章,总字数超过27万字。
图像.png
我特意找了一个非技术的,避免提取关键词所有Python命令。
我选择了去年的“网约车司机的两三件事”。
图像.png
这个文章讲述了更多有趣的故事。
我从网页中提取文本并将其存储在 sample.txt 中。
注意这里是容易踩坑的地方。在暑假的一次研讨会上,有几个学生因为从互联网上提取中文文本的问题而被卡了很长时间。
这是因为与英文不同,汉字有编码问题。不同的系统有不同的默认编码,不同版本的 Python 接受不同的编码。您从 Internet 下载的文本文件可能与您系统的编码不一致。
图像.png
在任何情况下,这些因素都可能导致您打开的文本中到处都是难以理解的乱码。
因此,使用中文文本数据的正确方式是在 Jupyter Notebook 中新建一个文本文件。
图像.png
然后,将出现以下空白文件。
图像.png
使用任何可以正常显示的编辑器打开从别处下载的文本,然后复制整个内容并将其粘贴到这个空白文本文件中,以避免编码混乱。
避开这个坑可以为你省去很多不必要的麻烦。
好了,知道这个技巧后,你就可以愉快的提取关键词了。
实施
回到Jupyter Notebook的主界面,点击demo-extract-keyword.ipynb,就可以看到源码了。
图像.png
是的,你没看错。两种不同的方式(TF-idf和TextRank)只需要这四个短句就可以完成对关键词的提取。
在这一部分,我们首先解释执行步骤。不同关键词提取方式的原理会在后面介绍。
首先,我们从口吃分词分析工具箱中导入所有的关键词提取函数。
from jieba.analyse import *
在对应的语句上,按 Shift+Enter 组合键执行语句并得到结果。
然后,让 Python 打开我们的示例文本文件并将其所有内容读入 data 变量。
with open('sample.txt') as f:
data = f.read()
使用TF-idf方法提取关键词和权重,依次展示。如果不指定,默认显示数量为20关键词。
for keyword, weight in extract_tags(data, withWeight=True):
print('%s %s' % (keyword, weight))
在显示内容之前,会有一些提示,不管了。
Building prefix dict from the default dictionary ...
Loading model from cache /var/folders/8s/k8yr4zy52q1dh107gjx280mw0000gn/T/jieba.cache
Loading model cost 0.547 seconds.
Prefix dict has been built succesfully.
然后名单出来了:
优步 0.280875594782
司机 0.119951947597
乘客 0.105486129485
师傅 0.0958888107815
张师傅 0.0838162334963
目的地 0.0753618512886
网约车 0.0702188986954
姐姐 0.0683412127766
自己 0.0672533110661
上车 0.0623276916308
活儿 0.0600134354214
天津 0.0569158056792
10 0.0526641740216
开优步 0.0526641740216
事儿 0.048554456767
李师傅 0.0485035501943
天津人 0.0482653686026
绕路 0.0478244723097
*敏*感*词* 0.0448480260748
时候 0.0440840298591
看了一下,觉得关键词的提取还是比较靠谱的。当然,数字10也混进去了,还好是无害的。
如果需要修改关键词的个数,需要指定topK参数。比如你想输出10个关键词,可以这样执行:
for keyword, weight in extract_tags(data, topK=10, withWeight=True):
print('%s %s' % (keyword, weight))
让我们尝试另一种关键词提取方法-TextRank。
for keyword, weight in textrank(data, withWeight=True):
print('%s %s' % (keyword, weight))
关键词 提取结果如下:
优步 1.0
司机 0.749405996648
乘客 0.594284506457
姐姐 0.485458741991
天津 0.451113490366
目的地 0.429410027466
时候 0.418083863303
作者 0.416903838153
没有 0.357764515052
活儿 0.291371566494
上车 0.277010013884
绕路 0.274608592084
转载 0.271932903186
出来 0.242580745393
出租 0.238639889991
事儿 0.228700322713
单数 0.213450680366
*敏*感*词* 0.212049665481
拉门 0.205816713637
跟着 0.20513470986
注意这个提取的结果和TF-idf的结果是不一样的。至少,那个非常突然的“10”已经消失了。
但是,这是否意味着TextRank方法一定比TF-idf好?
本题留作反思题,希望您在仔细阅读以下原则后能独立回答。
如果你只需要应用这个方法解决实际问题,那么请跳过原理部分,直接进入讨论。
原则
下面简单解释一下上一篇文章中出现的两种不同的关键词提取方法的基本原理——TF-idf和TextRank。
为了不让大家觉得无聊,这里就不用数学公式了。后面我会给出相关资料的链接。有兴趣的小伙伴可以跟着图片去了解和阅读学习。
先说TF-idf。
它的全称是词频-逆文档频率。中间有一个连字符,左右两边是各自的一部分,结合在一起决定一个词的重要性。
第一部分是词频(Term Frequency),即一个词出现的频率。
我们常说“重要的事情说三遍”。
同样的,某个词出现的次数越多,这意味着这个词的重要性可能会非常高。
但是,这只是一种可能,并不是绝对的。
例如,现代汉语中的许多虚词——“的、地、得”,以及古代汉语中的许多结尾词“之、胡、哲、叶、羲”。这些词可能在文中多次出现,但显然不是关键词。
这就是为什么我们在判断关键词时需要第二部分(idf)的配合。
逆文档频率(inverse document frequency)首先计算一个词在每个文档中出现的频率。假设总共有10篇文档,其中某个词A在10篇文章文章中最先出现,另一个词B只出现在3篇文章中。哪个词更重要?
给你一分钟思考,然后继续阅读。
是时候公布答案了。
答案是 B 更关键。
A 可以是功能词,也可以是所有文档共享的主题词。而B只出现在3个文档中,所以很可能是一个关键词。
逆文档频率就是取这个文档频率的倒数。这样,第一部分和第二部分越高越好。两者都高,很有可能是关键词。
TF-idf 讲完了,再来说说 TextRank。
与 TF-idf 相比,TextRank 更为复杂。它不是简单地进行加减乘除运算,而是基于图形的计算。
下图是来自原创文档的示例图片。
图像.png
TextRank首先提取词汇形成节点;然后根据词汇的关联建立联系。
根据连接节点的数量,为每个节点分配一个初始权重值。
然后迭代。
根据连接到一个词的所有词的权重,重新计算该词的权重,然后将重新计算的权重传递出去。在这种变化达到平衡状态之前,权重值不再变化。这在意识形态上与 Google 的 PageRank 算法一致。
图像.png
根据最终的权重值,取其中排名靠前的词汇作为关键词的提取结果。
如果您对原创文献感兴趣,请参考以下链接:
讨论
总而言之,本文讨论了如何使用 Python 提取中文文本。具体来说,我们分别使用了TF-idf和TextRank方法,两者提取关键词的结果可能不同。
你做过中文关键词提取吗?使用什么工具?效果如何?还有比这篇文章更有效的方法吗?欢迎留言,与大家分享您的经验和想法,我们一起交流讨论。