关键词采集词(一种的相邻词关系、基于图排序的提取)

优采云 发布时间: 2021-11-13 21:03

  关键词采集词(一种的相邻词关系、基于图排序的提取)

  很久以前,我使用TFIDF进行工业关键词提取。TFIDF 只是从词的统计信息入手,没有充分考虑词之间的语义信息。现在本文将介绍一种关键词提取算法TextRank,该算法考虑相邻词的语义关系,基于图排序。

  1. 简介

  TextRank 是由 Mihalcea 和 Tarau 在 EMNLP'04 [1] 中提出的。思路很简单:通过词之间的相邻关系构建一个网络,然后用PageRank迭代计算各个节点的rank值,对rank值进行排序得到关键词。PageRank 最初是用来解决网页排名问题的。网页之间的链接关系是图的边缘。迭代计算公式如下:

  \[PR(V_i) = (1-d) + d * \sum_{j \in In(V_i)} \frac{1}{|Out(V_j)|}PR(V_j)\]

  其中,\(PR(V_i)\)表示节点\(V_i\)的秩值,\(In(V_i)\)表示节点\(V_i\)的前驱节点集合,\(Out (V_j)\)代表节点\(V_j\)的后续节点集合,\(d\)是平滑的阻尼因子。

  网页之间的链接关系可以用图来表示,那么如何将一个句子(可以看作是一个词的序列)构造成一个图呢?TextRank 在某个词与其之前的 N 个词和其后的 N 个词之间具有图相邻关系(类似于 N-gram 语法模型)。具体实现:设置一个长度为N的滑动窗口,该窗口中的所有词都被认为是该词节点的相邻节点;那么TextRank构建的词图就是一个无向图。下图显示了从文档构建的词图(去除了停用词并按词性过滤):

  

  考虑到不同的词对可能有不同的共现(co-occurrence),TextRank使用共现作为无向图边的权重。那么,TextRank的迭代计算公式如下:

  \[WS(V_i) = (1-d) + d * \sum_{j \in In(V_i)} \frac{w_{ji}}{\sum_{V_k \in Out(V_j)} w_{jk} } WS(V_j)\]

  2. 评价

  接下来,将评估TextRank在关键词提取任务上的准确率、召回率和F1-Measure,并与TFIDF进行比较;精度计算公式如下:

  \[精度 = \frac{1}{N} \sum_{i=0}^{N-1} \frac{\left|P_i \cap T_i\right|}{\left|P_i\right|}\]

  其中,\(N\)为文档数,\(P_i\)为从文档中提取的关键词\(i\),\(T_i\)为注释关键词的文件。召回率和F1的计算公式如下:

  \[召回 = \frac{1}{N} \sum_{i=0}^{N-1} \frac{\left|P_i \cap T_i\right|}{\left|T_i\right|} \]

  \[F1 = \frac{2*Precision*Recall}{Precision + Recall} \]

  测试集是刘志远老师提供的网易新闻标注数据集,共有13702篇文档。杰霸已经全面实现了关键词提取TFIDF和TextRank算法。基于解霸-0.39的评测实验代码如下:

  import jieba.analyse

import json

import codecs

def precision_recall_fscore_support(y_true, y_pred):

"""

evaluate macro precision, recall and f1-score.

"""

doc_num = len(y_true)

p_macro = 0.0

r_macro = 0.0

for i in range(doc_num):

tp = 0

true_len = len(y_true[i])

pred_len = len(y_pred[i])

for w in y_pred[i]:

if w in y_true[i]:

tp += 1

p = 1.0 if pred_len == 0 else tp / pred_len

r = 1.0 if true_len == 0 else tp / true_len

p_macro += p

r_macro += r

p_macro /= doc_num

r_macro /= doc_num

return p_macro, r_macro, 2 * p_macro * r_macro / (p_macro + r_macro)

file_path = 'data/163_chinese_news_dataset_2011.dat'

with codecs.open(file_path, 'r', 'utf-8') as fr:

y_true = []

y_pred = []

for line in fr.readlines():

d = json.loads(line)

content = d['content']

true_key_words = [w for w in set(d['tags'])]

y_true.append(true_key_words)

# for w in true_key_words:

# jieba.add_word(w)

key_word_pos = ['x', 'ns', 'n', 'vn', 'v', 'l', 'j', 'nr', 'nrt', 'nt', 'nz', 'nrfg', 'm', 'i', 'an', 'f', 't',

'b', 'a', 'd', 'q', 's', 'z']

extract_key_words = jieba.analyse.extract_tags(content, topK=2, allowPOS=key_word_pos)

# trank = jieba.analyse.TextRank()

# trank.span = 5

# extract_key_words = trank.textrank(content, topK=2, allowPOS=key_word_pos)

y_pred.append(extract_key_words)

prf = precision_recall_fscore_support(y_true, y_pred)

print('precision: {}'.format(prf[0]))

print('recall: {}'.format(prf[1]))

print('F1: {}'.format(prf[2]))

  其中,从每个文档中提取的关键词个数为2,通过词性过滤;span 表示 TextRank 算法中滑动窗口的大小。评估结果如下:

  方法 PrecisionRecallF1-Measure

  TFIDF

  0.2697

  0.2256

  0.2457

  TextRank 跨度=5

  0.2608

  0.2150

  0.2357

  TextRank 跨度=7

  0.2614

  0.2155

  0.2363

  如果将标签关键词添加到自定义字典中,则评估结果如下:

  方法 PrecisionRecallF1-Measure

  TFIDF

  0.3145

  0.2713

  0.2913

  TextRank 跨度=5

  0.2887

  0.2442

  0.2646

  TextRank 跨度=7

  0.2903

  0.2455

  0.2660

  直观感受关键词提取结果(添加自定义字典):

  // TFIDF, TextRank, labelled

['文强', '陈洪刚'] ['文强', '陈洪刚'] {'文强', '重庆'}

['内贾德', '伊朗'] ['伊朗', '内贾德'] {'制裁', '世博', '伊朗'}

['调控', '王珏林'] ['调控', '楼市'] {'楼市', '调控'}

['罗平县', '男子'] ['男子', '罗平县'] {'被砍', '副局长', '情感纠葛'}

['佟某', '黄玉'] ['佟某', '黄现忠'] {'盲井', '伪造矿难'}

['女生', '聚众*敏*感*词*'] ['女生', '聚众*敏*感*词*'] {'聚众*敏*感*词*', '东莞', '*敏*感*词*视频'}

['马英九', '和平协议'] ['马英九', '推进'] {'国台办', '马英九', '和平协议'}

['东帝汶', '巡逻艇'] ['东帝汶', '中国'] {'东帝汶', '军舰', '澳大利亚'}

['墨西哥', '*敏*感*词*'] ['墨西哥', '袭击'] {'*敏*感*词*手', '墨西哥', '打死'}

  从以上两个实验结果可以发现:

  另外,由于TextRank涉及到词图的构建和迭代计算,提取速度较慢。

  3. 参考资料

  [1] 拉达、米哈尔恰和保罗·塔劳。“TextRank:将秩序带入文本。” 自然语言处理中的经验方法 (2004): 404-411.

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线