NLP深入学习(十四):TextRank算法

avatar
作者
猴君
阅读量:0

文章目录


0. 引言

前情提要:
《NLP深入学习(一):jieba 工具包介绍》
《NLP深入学习(二):nltk 工具包介绍》
《NLP深入学习(三):TF-IDF 详解以及文本分类/聚类用法》
《NLP深入学习(四):贝叶斯算法详解及分类/拼写检查用法》
《NLP深入学习(五):HMM 详解及字母识别/天气预测用法》
《NLP深入学习(六):n-gram 语言模型》
《NLP深入学习(七):词向量》
《NLP深入学习(八):感知机学习》
《NLP深入学习(九):KNN 算法及分类用法》
《NLP深入学习(十):决策树(ID3、C4.5以及CART)》
《NLP深入学习(十一):逻辑回归(logistic regression)》
《NLP深入学习(十二):支持向量机(SVM)》
《NLP深入学习(十三):AdaBoost 算法》

1. 什么是TextRank

TextRank 算法是一种基于图的排序算法,主要用于文本处理中的关键词提取和文本摘要。它基于图中节点之间的关系来评估节点的重要性,类似于 Google 的 PageRank 算法。TextRank 算法的关键思想是,一个词语在文本中的重要性可以通过与其他词语的关系来评估,而这些关系可以表示为图中的边。

2. 基本原理

以下是TextRank算法的基本步骤:

  1. 图构建(Graph Construction): 将文本中的词语或短语表示为图的节点,词语之间的关系可以是共现关系、语义相似度等。通常,可以使用共现矩阵或者基于词向量的相似度来构建图。

  2. 边权重计算(Edge Weighting): 计算图中边的权重,反映节点之间的关系强度。例如,可以使用共现词频、词向量相似度等作为边的权重。

  3. 节点权重计算(Node Weighting): 利用图中节点之间的关系以及边的权重来计算节点的权重。通常采用迭代方法,类似于 PageRank 算法,根据节点之间的相互影响来计算节点的权重。

  4. 排名(Ranking): 根据节点的权重对节点进行排名,排名较高的节点被认为是重要的词语或短语。

下面是 TextRank 算法的节点得分更新公式:
W S ( V i ) = ( 1 − d ) + d × ∑ V j ∈ I n ( V i ) w j i ∑ V k ∈ O u t ( V j ) w j k W S ( V j ) WS(V_i) = (1 - d) + d \times \sum_{V_j \in In(V_i)} \frac{w_{ji}}{\sum_{V_k \in Out(V_j)} w_{jk}} WS(V_j) WS(Vi)=(1d)+d×VjIn(Vi)VkOut(Vj)wjkwjiWS(Vj)

其中:

  • W S ( V i ) WS(V_i) WS(Vi)是节点 V i V_i Vi 的得分。
  • d d d 是阻尼系数,一般设置为0.85。
  • I n ( V i ) In(V_i) In(Vi)是指向节点 V i V_i Vi 的节点集合。
  • O u t ( V j ) Out(V_j) Out(Vj) 是节点 V j V_j Vj指向的节点集合。
  • w j i w_{ji} wji 是从节点 V j V_j Vj到节点 V i V_i Vi的边的权重。

3. 例子

通过一个具体的例子来说明 TextRank 算法中节点得分的更新过程。假设我们有一个简单的图,包含5个节点和它们之间的边:

    A    / \   B   C  /     \ D-------E  A指向B、C; B指向D; C指向E; D和E互相指向对方; 

假设初始时每个节点的得分为1,阻尼系数 (d) 为0.85。我们将使用 TextRank 算法来更新节点的得分。

首先,我们需要定义节点之间的边权重。在这个例子中,我们假设所有的边权重都为1。

现在,我们将按照 TextRank 算法中的公式对节点的得分进行更新。假设我们进行迭代计算,直到收敛,这里我们假设只进行一次迭代。我们将使用 TextRank 的节点得分更新公式来计算每个节点的得分。

对于节点A:
W S ( A ) = ( 1 − 0.85 ) + 0.85 × 0 = 0.15 WS(A) = (1 - 0.85) + 0.85 \times 0= 0.15 WS(A)=(10.85)+0.85×0=0.15

对于节点B:
W S ( B ) = ( 1 − 0.85 ) + 0.85 × ( 1 2 × W S ( A ) ) = 0.15 + 0.85 × ( 1 2 × 1 ) = 0.15 + 0.85 × 0.5 = 0.775 WS(B) = (1 - 0.85) + 0.85 \times \left( \frac{1}{2} \times WS(A) \right) = 0.15 + 0.85 \times \left( \frac{1}{2} \times 1 \right) = 0.15 + 0.85 \times 0.5 = 0.775 WS(B)=(10.85)+0.85×(21×WS(A))=0.15+0.85×(21×1)=0.15+0.85×0.5=0.775

对于节点C:
W S ( C ) = ( 1 − 0.85 ) + 0.85 × ( 1 2 × W S ( A ) ) = 0.15 + 0.85 × ( 1 2 × 1 ) = 0.15 + 0.85 × 0.5 = 0.775 WS(C) = (1 - 0.85) + 0.85 \times \left( \frac{1}{2} \times WS(A) \right) = 0.15 + 0.85 \times \left( \frac{1}{2} \times 1 \right) = 0.15 + 0.85 \times 0.5 = 0.775 WS(C)=(10.85)+0.85×(21×WS(A))=0.15+0.85×(21×1)=0.15+0.85×0.5=0.775

对于节点D:
W S ( D ) = ( 1 − 0.85 ) + 0.85 × ( 1 1 × W S ( B ) + 1 1 × W S ( E ) ) = 0.15 + 0.85 × ( 1 1 × 1 + 1 1 × 1 ) = 0.15 + 0.85 × ( 1 + 1 ) = 1.7 WS(D) = (1 - 0.85) + 0.85 \times \left( \frac{1}{1} \times WS(B) + \frac{1}{1} \times WS(E) \right) = 0.15 + 0.85 \times \left( \frac{1}{1} \times 1 + \frac{1}{1} \times 1 \right) = 0.15 + 0.85 \times (1 + 1) = 1.7 WS(D)=(10.85)+0.85×(11×WS(B)+11×WS(E))=0.15+0.85×(11×1+11×1)=0.15+0.85×(1+1)=1.7

对于节点E:
W S ( E ) = ( 1 − 0.85 ) + 0.85 × ( 1 1 × W S ( C ) + 1 1 × W S ( D ) ) = 0.15 + 0.85 × ( 1 1 × 1 + 1 1 × 1 ) = 0.15 + 0.85 × ( 1 + 1 ) = 1.7 WS(E) = (1 - 0.85) + 0.85 \times \left( \frac{1}{1} \times WS(C) + \frac{1}{1} \times WS(D) \right) = 0.15 + 0.85 \times \left( \frac{1}{1} \times 1 + \frac{1}{1} \times 1 \right) = 0.15 + 0.85 \times (1 + 1) = 1.7 WS(E)=(10.85)+0.85×(11×WS(C)+11×WS(D))=0.15+0.85×(11×1+11×1)=0.15+0.85×(1+1)=1.7

经过一次迭代后,每个节点的得分已经更新。在实际应用中,通常需要多次迭代,直到节点的得分收敛到一个稳定的值。

4. 代码示例

下面是一个简单的 Python 示例,演示如何使用 TextRank 算法从文本中提取关键词:

import networkx as nx from sklearn.feature_extraction.text import CountVectorizer from nltk.tokenize import word_tokenize import numpy as np  def build_graph(sentences):     vectorizer = CountVectorizer()     matrix = vectorizer.fit_transform(sentences)     co_occurrence_matrix = (matrix.T * matrix)     np.fill_diagonal(co_occurrence_matrix.diagonal(), 0)  # Set diagonal elements to zero     graph = nx.from_numpy_array(co_occurrence_matrix)     return graph  def textrank(graph, max_iter=100, d=0.85, tol=1.0e-4):     n = graph.number_of_nodes()     scores = np.ones(n) / n  # Initialize scores     for _ in range(max_iter):         prev_scores = np.copy(scores)         for i in range(n):             scores[i] = (1 - d) + d * np.sum([graph[j][i]['weight'] / np.sum([graph[j][k]['weight'] for k in graph[j]]) * prev_scores[j] for j in graph.neighbors(i)])         if np.sum(np.abs(scores - prev_scores)) < tol:             break     return {node: score for node, score in zip(graph.nodes(), scores)}  # 示例文本 text = """ TextRank is a graph-based ranking model for text processing.  It was introduced by Mihalcea and Tarau in 2004.  The algorithm is based on the PageRank algorithm and is used for tasks such as keyword extraction and text summarization. """  # 分词 sentences = [word_tokenize(sentence.lower()) for sentence in text.split('.')] # 构建图 graph = build_graph(sentences) # 计算节点权重 scores = textrank(graph) # 输出排名前几的关键词 top_keywords = sorted(scores, key=scores.get, reverse=True)[:5] print("Top Keywords:", top_keywords) 

这个示例使用了 NetworkX 库来构建和操作图。

5. 参考

《NLP深入学习(一):jieba 工具包介绍》
《NLP深入学习(二):nltk 工具包介绍》
《NLP深入学习(三):TF-IDF 详解以及文本分类/聚类用法》
《NLP深入学习(四):贝叶斯算法详解及分类/拼写检查用法》
《NLP深入学习(五):HMM 详解及字母识别/天气预测用法》
《NLP深入学习(六):n-gram 语言模型》
《NLP深入学习(七):词向量》
《NLP深入学习(八):感知机学习》
《NLP深入学习(九):KNN 算法及分类用法》
《NLP深入学习(十):决策树(ID3、C4.5以及CART)》
《NLP深入学习(十一):逻辑回归(logistic regression)》
《NLP深入学习(十二):支持向量机(SVM)》
《NLP深入学习(十三):AdaBoost 算法》

欢迎关注本人,我是喜欢搞事的程序猿; 一起进步,一起学习;

欢迎关注知乎:SmallerFL;

也欢迎关注我的wx公众号:一个比特定乾坤

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!