-
前言
因为最近项目需要,这里基于资料,个人理解与实际应用进行一个整体性的文本关键信息抽取方法总结。大的方向上,我将关键信息抽取分为以下几个点:
关键词提取、主题提取、实体抽取、关系抽取
下面进行详细的实现分析。
一、关键词提取
-
简介
关键词是文本分析中比较传统也比较重要的一项,在繁冗文本中提取到关键词,有助于之后一系列的操作包括主题、推荐、搜索等等。一般进行关键词提取可以分为有监督或者无监督。有监督是对文本中词语进行标注,进而转化成一个二分类问题,对每一个词判别该词语是否是文本的关键词,该方法付出与收效不成正比,通用性也较差,一般不进行使用。
无监督算法不需要人工标注的训练集,一般以基于文本统计特征、基于词图模型的TF-IDF、TextRank所使用最多。
-
TF-IDF
TF-IDF是以词频为衡量指标,重要的词往往在文章中出现的频率也非常高;但另一方面,不是出现次数越多的词就一定重要,因为有些词在各种文章中都频繁出现,那它的重要性肯定不如哪些只在某篇文章中频繁出现的词重要性强。从统计学的角度,就是给予那些不常见的词以较大的权重,而减少常见词的权重。所以逆文档频率IDF被引入。
TF-IDF的计算公式如下:
TF(词频) = 单个词在文本中出现的频次/文本的总词数
IDF(逆文档频率) = log(语料库中的文档总数/(包含该词的文档数 + 1))
TF-IDF = TF * IDF
一般IDF有已经基于大量语料预设好的值。调用也有大量库打包好可供使用,以调用jieba为例:
jieba.analyse.extract_tags(sentence, topK=num, withWeight=False, allowPOS=())
可以看到封装得十分完善,可以选择关键词数目已经允许成为关键词的词性。以下源码:
def extract_tags(self, sentence, topK=20, withWeight=False, allowPOS=(), withFlag=False):
# (1)中文分词
if allowPOS:
allowPOS = frozenset(allowPOS)
words = self.postokenizer.cut(sentence)
else:
words = self.tokenizer.cut(sentence)
# (2)计算词频TF
freq = {
}
for w in words:
if allowPOS:
if w.flag not in allowPOS:
continue
elif not withFlag:
w = w.word
wc = w.word if allowPOS and withFlag else w
if len(wc.strip()) < 2 or wc.lower() in self.stop_words:
continue
freq[w] = freq.get(w, 0.0) + 1.0
total = sum(freq.values())
# (3)计算IDF
for k in freq:
kw = k.word if allowPOS and withFlag else k
freq[k] *= self.idf_freq.get(kw, self.median_idf) / total
# (4)排序得到关键词集合
if withWeight:
tags = sorted(freq.items(), key=itemgetter(1<