说明:本文依据《中文自然语言处理入门实战》完成。目前网上有不少转载的课程,我是从GitChat上购买。
第三课 中文文本中的关键字提取
关键词提取就是从文本里面把跟这篇文章意义最相关的一些词语抽取出来。这个可以追溯到文献检索初期,关键词是为了文献标引工作,从报告、论文中选取出来用以表示全文主题内容信息的单词或术语,在现在的报告和论文中,我们依然可以看到关键词这一项。因此,关键词在文献检索、自动文摘、文本聚类/分类等方面有着重要的应用,它不仅是进行这些工作不可或缺的基础和前提,也是互联网上信息建库的一项重要工作。
关键词抽取方法
- 关键词分配:就是给定一个已有的关键词库,对于新来的文档从该词库里面匹配几个词语作为这篇文档的关键词。
- 关键词提取:针对新文档,通过算法分析,提取文档中一些词语作为该文档的关键词。
目前大多数应用领域的关键词抽取算法都是基于后者实现的,从逻辑上说,后者比前者在实际应用中更准确。
1.基于TF-IDF的关键词提取
TF-IDF 是 Term Frequency - Inverse Document Frequency 的简写。TF-IDF 是一种数值统计,用于反映一个词对于语料中某篇文档的重要性。
TF-IDF 的主要思想就是:如果某个词在一篇文档中出现的频率高,也即 TF 高;并且在语料库中其他文档中很少出现,即 DF 低,也即 IDF 高,则认为这个词具有很好的类别区分能力。
其中TF为词频,表示词汇t在文档d中出现的频率。
n_{i,j}是词t_i在文件d_j中出现的次数。
IDF是逆文档频率(Inverse Document Frequency),表示语料库中包含词 t 的文档的数目的倒数。
|D|是语料库中文件总数,|{j:t_i\in d_j}|包含词t的文件数目,为防止公式中被除数为0,会自动加1。
TF-IDF公式就是将TF和IDF相乘。
jieba已经实现了TF-IDF的抽取功能,使用jieba.analyse引入,参数设置如下
- sentence:待提取的文本语料;
- topK:返回 TF/IDF 权重最大的关键词个数,默认值为 20;
- withWeight:是否需要返回关键词权重值,默认值为 False;
- allowPOS:仅包括指定词性的词,默认值为空,即不筛选。
result_jieba = jieba.analyse.extract_tags(sentence, topK=20, withWeight=True, allowPOS=())
print(result_jieba)
2.基于TextRank的关键词提取
TextRank核心思想是文本中的词看作图中的节点,通过边相互连接,不同的节点会有不同的权重,权重高的节点可以作为关键词。
jieba已经实现了TF-IDF的抽取功能,使用jieba.analyse引入
result_TextRank = jieba.analyse.textrank(sentence, topK=20, withWeight=True, allowPOS=('n', 'v'))
print(result_TextRank)
3.基于LDA主题模型的关键词提取
在之前的机器学习中,LDA是和PCA一样用于降维处理的模型,在这里作为主题词模型进行关键词提取。
这里使用之前处理文献量化时的数据来做抽取。教程中使用的是gensim的LDA模型,我在这里使用的是Sklearn的LDA模型(LatentDirichletAllocation)
#-*- coding: utf-8 -*-
#处理文献摘要
import jieba
import pandas as pd
from dateutil import parser
data = pd.read_excel(r'.\yyjy_data.xls', sheetname=2)
data.head()
def chinese_word_cut(text):
stopwords=stopwordslist(r'C:\Users\01\Desktop\analysis\yyjy_cnki\stopwords.txt')
outstr=''
for word in jieba.cut(text):
if word not in stopwords:
if word != '\t':
outstr += word
outstr += " "
return outstr
def stopwordslist(filepath):
stopwords=[line.strip() for line in open(filepath, 'r', encoding='utf-8').readlines()]
return stopwords
data['Abstract']=data['Abstract'].astype(str)
data['content_cut']=data.Abstract.apply(chinese_word_cut)
data.head()
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
n_features = 1000
max_df用于去掉出现太频繁的
max_df = 0.50 means "忽略terms出现超过50%的文本".
max_df = 25 means "忽略terms出现超过25的文本".
max_df的默认值为1,意思为忽略出现超过100%的文本,即不会有任何意义
min_df用于去掉太不常见的
min_df = 0.01 means "忽略不超过1%的".
min_df = 5 means "忽略不超过5的".
tf_vectorizer = CountVectorizer(
strip_accents='unicode',
max_features=n_features,
stop_words='english',
max_df=0.50,
min_df=100)
tf = tf_vectorizer.fit_transform(data.content_cut)
from sklearn.decomposition import LatentDirichletAllocation
n_topics = 10
lda = LatentDirichletAllocation(
n_topics=n_topics,
max_iter=50,
learning_method='online',
learning_offset=50.,
random_state=0)
lda.fit(tf)
def print_top_words(model, feature_names, n_top_words):
for topic_idx, topic in enumerate(model.components_):
print("Topic #%d:" % topic_idx)
print(" ".join([feature_names[i]
for i in topic.argsort()[:-n_top_words - 1:-1]]))
print()
n_top_words = 30
tf_feature_names = tf_vectorizer.get_feature_names()
print_top_words(lda, tf_feature_names, n_top_words)
4.使用HanLP进行关键词提取
可以使用HanLP来完成关键字提取,内部采用 TextRankKeyword 实现。
result_han = HanLP.extractKeyword(sentence, 20)
print(result_han)
对比这几个主题抽取结果,你会发现,主题抽取和之前的分词紧密相连,如果分词能够更加智能化,那么抽取的主题词应该不会像这个结果这样微粒。我在这里还是建议大家使用LDA模型。
[('人工智能', 0.9750542675762887), ('智能', 0.5167124540885567), ('机器', 0.20540911929525774), ('人类', 0.17414426566082475), ('科学', 0.17250169374402063), ('模拟', 0.15723537382948452), ('技术', 0.14596259315164947), ('计算机', 0.14030483362639176), ('图像识别', 0.12324502580309278), ('流行语', 0.11242211730309279), ('领域', 0.11159372252391753), ('理论', 0.10842142209463919), ('挑战性', 0.10725948546907216), ('计算机科学', 0.10059322603690721), ('胜任', 0.09603824920938145), ('能以', 0.09542563662711341), ('缩写', 0.0918581965484536), ('容器', 0.08756191629402063), ('机器人', 0.08742415105876289), ('包括', 0.08708560101505154)]
[('智能', 1.0), ('人工智能', 0.9494129745270592), ('机器', 0.49663267662671245), ('人类', 0.42644352327508783), ('技术', 0.4081045856122762), ('模拟', 0.37686972900289967), ('包括', 0.3497298194015523), ('科学', 0.3166353404714701), ('理论', 0.30488902877451407), ('计算机', 0.2967448735822335), ('领域', 0.2800715509931106), ('年度', 0.271562368094339), ('需要', 0.26846112321216903), ('心理学', 0.2519058950332978), ('信息', 0.24293798778090905), ('语言', 0.2341066489418511), ('识别', 0.23353569236715208), ('带来', 0.23309672987030272), ('过程', 0.22882750520149098), ('延伸', 0.2248210588102454)]
[人工智能, 智能, 人类, 研究, 不同, 工作, 包括, 领域, 模拟, 理论, 技术, 新的, 门, 机器, 计算机, 科学, 入选, 复杂, AI, 12月]