信息抽取
信息抽取是个宽泛的概念,指的是从非结构化的文本中提取出结构化的信息来的一种技术。信息抽取(information extraction),即从自然语言文本中,抽取出特定的事件或事实信息,帮助我们将海量内容自动分类、提取和重构。信息通常包括实体(entity)、关系(relation)、事件(event)
新词提取
新词
新词指的是词典之外的词语。新词的提取分为:
- 提取大量的文本(生语料)中的词语,无论新旧
- 用词典过滤掉已有的词语,得到新的词语
信息熵
信息熵指的是某条消息所含的信息量。不确定性越大,信息量越大。计算方法如下:
$$
H(x)=-\sum_xp(x)logp(x)
$$
如果对数函数的底数是2,信息上的单位就是比特
具体到新词提取中,给定字符串S作为词语选取,X定义为左边可能出现的字符(左邻字),则成H(X)为S的左信息熵。
互信息
互信息指的是两个离散型随机变量XY之间的相关程度的度量。
$$
\begin{align}
I(X;Y)
& =\sum_{x,y}p(x,y)log \frac{p(x,y)}{p(x)p(y)} \
& = E_{p(x,y)} log\frac{p(x,y)}{p(x)p(y)}
\end{align}
$$
在韦恩图中,
- 并集:联合分布的信息熵$H(X,Y)$
- 差集:条件熵$H(X|Y)$
- 交集:互信息$H(X;Y)$
互信息越大,两个变量的关系越密切。同时发生的可能性也就越大。
提取新词
有了信息熵和互信息,将两个指标低于一定阈值的片段过滤掉,剩下的片段按照频次降序排列,截取最高频次的N个片段,完成词语的提取流程。具体模块在com.hankcs.hanlp.mining.word.NewWordDiscover
,相应的接口为com.hankcs.hanlp.HanLP#extractWords
1 | word_life_list = HanLP.extractWords(IOUtil.newBufferedReader(corpus), 100) # 提取100个关键词 |
接口的参数为
-
reader 从reader中获取文本,逐行读取和处理,内存更省
-
size 需要提取词语的数量
-
NewWordsOnly 是否只提取词典中没有的词语,返回
OOV
-
max_word_len 词语最长长度,默认是4
-
min_freq 词语最低频率
-
min_entropy 词语最低熵。0.5左右,该值越大,越短的词语越容易被提取出来。
-
min_aggregation 词语最低互信息,一般50-200。该值越大,越长的词语越容易被提取出来
关键词提取
提取文章中重要的单词,而不是限于词语的新鲜程度,成为关键词提取
在进行提取的过程中,根据一份还是多份文档,提取算法分为单文档和多文档算法。
- 单文档:词频和TextRank
- 多文档:TF-IDF
词频
文章中作者反复提及到的词语,通过统计文章每种词语的词频并排序,获取关键词。但是比如某些词语,比如“的”反复出现,但是并不是关键词。词频统计的步骤:
- 分词
- 停用词过滤
- 按词频统计前n个
1 | counter = TermFrequencyCounter() |
- 遍历counter默认是按照字典顺序遍历
- top(N)返回的是词频最高的前N个单词及词频,降序排列
- 标点符号等停用分词已经去除了,分词结果以语境为主
- 索引模式:激活内置分词器的索引模式
1 | counter.getSegment().enableIndexMode(true); # 激活索引模式 |
笔记:使用词频统计的缺陷是,高频词语不等价于关键词。比如所有报道“奥运会”的文章中,将“奥运会”作为关键词并不合适,用户希望看到的是每篇文章的特色之处,而不是共性。
TF-IDF
TF-IDF(Term Frequency-Inverse Document Frequency, 词频-倒排文档频次)是信息检索中一个重要的词语重要程度的统计指标,广泛用于搜索引擎中,它属于多文档提取方法。综合考虑词语的稀有程度:
-
正比于它在文中的频次
-
反比于有多少文档包含它:包含该词语的文档越多,越不能体现文档的特色。
-
计算方法有多种,如下一种
$$
\begin{align}TF-IDF(t,d)& = \frac{TF(t,d)}{DF(t)} \ & = TF(t,d)\cdot IDF(t)\end{align}
$$
上面每个参数的解释
t
代表的是term
d
代表的是document
TF(t,d)
代表的是t
在d
中的出现频次DF(t)
代表的是多少篇文档包含t
DF
的倒数成为$IDF$
1 | counter = TfIdfCounter() # 调用方法的类 |
add
函数接受两个参数:文档id
和文档内容documents
方法返回所有的文档id
,供用户遍历getKeywordsOf(id, 3)
的两个参数:文档id
和提取的关键词个数
TextRank
如果没有大型的语料库或者存储IDF的内存,又想改善瓷片统计的效果,使用TextRank方法。TextRank实际上就是谷歌的PageTank文本上的应用
PageRank
是一种用于排序网页的随机算法。基本原理如下
- 互联网看作是有向图,网页视作为节点
- 节点$V_i$到节点$V_j$的超链接视作有向边
- 初始化每个节点的权重$S(V_i)$都是1,通过迭代的方式更新每个节点的权重,更新的表达式为
$$
S(V_i)=(1-d)+d*\sum_{V_j \in In(V_i)}\frac{1}{|Out(V_j)|}S(V_j)
$$
- d是0-1之前的常数因子,用户点击链接跳出当前链接当前网站的概率
- $In(V_i)$表示链接$V_i$的集合
- $Out(V_j)$表示从$v_j$出发链接到的集合
- 外链权重和外链总数成反比,与提供外链的网站权重成正比
笔记:并不是外链越多,PR就越高。外链越多,权重就越低。
PageRank应用到关键词提取中,将单词看做是节点。每个单词的外链是来自前后固定大小的窗口内的所有单词。
1 | keyword_list = HanLP.extractKeyWord(content, 5) |
短语提取
固定多词表达串的识别。常用于搜索引擎的自动推荐,文档的简介生成等。
1 | pharse_list = HanLP.extractPharse(text, 5) # 两个参数是文档的内容和所需短语个数 |
关键句提取
BM25
一般的PageRank
在句子颗粒度上行不通的,因为一篇文章中几乎不会出现两句完全相同的句子。引入了BM25
算法衡量句子的相似度,改进连接的权重计算。
在搜索引擎中,查询串query
是由多个词语构成的。BM25
解决的是衡量多个词语与文档的关联程度。几个定义如下:
- Q为查询语句,由关键字$q_1,…,q_n$组成
- D是被检索的文档
- $k_l$和$d$是两个常量,$avgDL$是所有文档的平均长度
BM25
的定义如下:
$$
\mathrm{BM} 25(D, Q)=\sum_{i=1}^{n} \operatorname{IDF}\left(q_{i}\right) \cdot \frac{\operatorname{TF}\left(q_{i}, D\right) \cdot\left(k_{1}+1\right)}{\operatorname{TF}\left(q_{i}, D\right)+k_{1} \cdot\left(1-b+b \cdot \frac{|D|}{\operatorname{avg} D L}\right)}
$$
上面式子的特点
- 先对查询语句中所有单词的
IDF
加权求和,两个参数和TF可以看做是调整IDF权重的参数 - $k_1$越大,TF对正面文档得分的正面影响就越大;b越大,TF负面文档得分的正面影响就越大
- 在
TF-IDF
中,当IDF
固定时,得分正比于TF,长文档占据优势;BM25
中,TF
对得分的影响还必须考虑文档长度
TF-IDF的表达式再现:
$$
\begin{align}TF-IDF(t,d)& = \frac{TF(t,d)}{DF(t)} \ & = TF(t,d)\cdot IDF(t)\end{align}
$$
TextRank
在上面的BM25
算法中,将句子视作一个查询语句,相邻的句子视作待查询的文档,得到它们之间的相似度。将该相似度看做是PageRank
中链接的权重,得到了TextRank
算法。
$$
\mathrm{WS}\left(V_{i}\right)=(1-d)+d \times \sum_{V_{j} \in \ln \left(V_{i}\right)} \frac{\mathrm{BM} 25\left(V_{i}, V_{j}\right)}{\sum_{V_{k} \in O u\left(V_{j}\right) \mathrm{BM} 25\left(V_{k}, V_{j}\right)}} \mathrm{WS}\left(V_{j}\right)
$$
TextRank
关键句提取模块的实现为TextRankSentence
。核心的Java代码为
1 | for (int _ = 0; _ < max_iter; ++_) |
当两次迭代间权重最大变化量小于阈值min_diff
,或者总的迭代次数达到max_iter
时算法终止。
1 | sentence_list = HanLP.extractSummary(document,3) # 两个参数:文档和所需要的句子数量 |