2021SC@SDUSC
系列文章目录
(十一)PKE代码分析四
目录
前言
之前几篇博客分析了基类相关代码,接下来会从无监督和有监督模型方面继续分析pke代码
pke包含模型如下:
本篇博客先从无监督模型的统计模型开始进行代码分析
unsupervised->statistical
tfidf.py
TF-IDF 关键短语提取模型
(一)原理
TF-IDF(term frequency-inverse document frequency) :一种用于资讯检索于资讯探勘的常用加权技术。是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数呈正比地增加,但同时也会随着它在语料库中出现的频率呈反比地下降。
1.1 TF-IDF原理
主要思想:如果某个词或短语在一篇文章中出现的频率(Term Frequency,TF)高,并且在其他的文章出现得少,即反文档频率(Inverse Documnet Frequency,IDF)低,则认为此词或短语具有很好的类别区分能力,适合用来分类。
具体计算公式:
其中,
:指词i对文档j的重要程度;
:指词i在文档j中出现的次数占比。计算公式如:
其中,指词i在文档j中出现的次数,
指文档j中所有词出现的次数之和;
:指词i的你文档频率,是指总文档数与词i所在文档数目之比,其计算公式如下:
其中,为文档总书目,
表示包含词
的文档数目。
1.2 实例及计算步骤
文档1:程序员从事程序开发、维护的专业人员。一般将程序员分为程序设计人员和程序编码人员,但两者的界限并不非常清楚,特别是在中国。软件从业人员分为初级程序员、高级程序员、系统程序员和项目经理四大类。
文档2:现在网络流行上把那程序员称为“程序猿”,女程序员称为“程序媛”。目前从事IT技术行业的大多数为男性,女性多数从事其他(如:会计、行政、人力资源等)种类的工作,在IT技术里女程序员是很受欢迎的,因此人们爱称女程序员为“程序媛”。
以上述两个文档,介绍TF-IDF的计算思路:
step1 :对文档进行分词,将词语以空格分隔存储在一起,并对每一句话存储为一行;
step2:统计文档中词语出现的次数,可以以dict存储(如:{key:value}:{'程序员':5}),及文档的词语总数目;
step3:对指定词语i统计其出现在文档中的数目,可以以dict存储(如:程序员出现在文档1和文档2中,记为{'程序员':2});
step4:计算,根据
的公式进行计算;
step5:计算,根据公式计算。
1.3 TF-IDF优缺点
优点:TF-IDF的思想对于具有代表性的词语(词语出现在一类文档中,该词语具备代表性)能够很好地表示;
缺点:TF-IDF对于一些在文本中出现频率高但同样具有代表性的词语不能很好表示。例如:
1)鲜花多少钱?2)百合花多少钱?3)水仙花多少钱?4)苹果多少钱?5)橘子多少钱?
如果按照TF-IDF算法,对于5个文档,鲜花、百合花、水仙花、苹果、橘子这些主体词会成为关键词,但从语句的总体来看,它们又都属于询问价格的类型,所以“多少钱”应该成为关键词。
改进:基于TF-IDF的计算法提出的改进方法是,将多个短文本整理为一个文本,这样既可以增加TF值,又可以增加IDF值。
(二)使用示例
在类的注释中有使用示例:
首先导入string和pke包
import string
import pke
# 1. 创建一个 TfIdf 提取器。
extractor = pke.unsupervised.TfIdf()
# 2. 加载文档内容
extractor.load_document(input='path/to/input',
language='en',
normalization=None)
# 3. 选择{1-3}-grams 不包含标点符号作为候选。
extractor.candidate_selection(n=3,
stoplist=list(string.punctuation))
# 4. 使用 `tf` x `idf` 加权候选
df = pke.load_document_frequency_file(input_file='path/to/df.tsv.gz')
extractor.candidate_weighting(df=df)
# 5. 将得分最高的 10 个候选词作为关键词
keyphrases = extractor.get_n_best(n=10)
(三)函数
包含一个类
class TfIdf(LoadFile):
类中包含2个函数
1.def candidate_selection(self, n=3, stoplist=None, **kwargs):
选择 1-3 grams作为关键词候选。
参数:
n (int):n-gram 的长度,默认为 3。
stoplist (list):过滤候选的stoplist,默认为 `None`。 不允许使用来自`string.punctuation` 的标点符号。
# 从 1-3 grams 选择ngrams
self.ngram_selection(n=n)
#如果未提供stoplist,则初始化空列表
if stoplist is None:
stoplist = list(string.punctuation)
# 过滤包含标点符号的候选词
self.candidate_filtering(stoplist=stoplist)
2.def candidate_weighting(self, df=None):
使用文档频率的候选权重函数。
参数: df (dict): 文档频率,文档数量应使用“--NB_DOC--”指定。
# 如果未提供,则初始化默认文档频率计数
if df is None:
logging.warning('LoadFile._df_counts is hard coded to {}'.format(
self._df_counts))
df = load_document_frequency_file(self._df_counts, delimiter='\t')
# 将文档数量初始化为 --NB_DOC-- + 1(当前)
N = 1 + df.get('--NB_DOC--', 0)
下面的for循环遍历候选,先获取候选文档频率,再计算idf分数,最后将 idf 分数添加到权重容器
for k, v in self.candidates.items():
candidate_df = 1 + df.get(k, 0)
idf = math.log(N / candidate_df, 2)
self.weights[k] = len(v.surface_forms) * idf
总结
本文分析了unsupervised->statistical->tfidf.py