2019独角兽企业重金招聘Python工程师标准>>>
因为项目内容中涉及自动生成文本摘要的功能,因此学习了一下TextRank算法实现摘要提取。
1.介绍一下TextRank算法
TextRank算法的思想是,拟定一个通用的评分标准,给文本中的每一个句子打分,所得分数就是该句子的权重,最后得到权重排名靠前的几个句子,构成最终的文本摘要。这就是所谓的TextRank自动生成摘要。
TextRank对每一个句子的打分思想由PageRank的迭代思想衍生而来,公式如下:
在这个公式中,WS(i)表示第i个句子的权重,右侧的求和表示的是每一个句子对所在文本的贡献程度。求和部分的分子wji表示两个句子j和i的相似程度,分母则是文本中相对应的部分的句子的权重之和,WS(Vj)表示上次迭代j的权重。
从整个公式可以看出这是一个反复迭代的过程。
由于wji需要计算两个句子的相似程度,因此这里我们需要引入另外的相似度算法,通常推荐使用BM25,这是目前已知的计算结果较为准确的算法之一。
这个公式中的d是一个常数,称为阻尼系数,通常在算法中我们取其值为0.85,当然也可以根据实际的情况进行调整。
2.TextRank算法的Java实现
2.1首先需要声明相关的变量
/**
* 阻尼系数(DampingFactor),一般取值为0.85
*/
final double d = 0.85f;
/**
* 最大迭代次数
*/
final int max_iter = 200;
final double min_diff = 0.001f;
/**
* 文档句子的个数
*/
int D;
/**
* 拆分为[句子[单词]]形式的文档
*/
List> docs;
/**
* 排序后的最终结果 score <-> index
*/
TreeMap
/**
* 句子和其他句子的相关程度
*/
double[][] weight;
/**
* 该句子和其他句子相关程度之和
*/
double[] weight_sum;
/**
* 迭代之后收敛的权重
*/
double[] vertex;
/**
* BM25相似度
*/
BM25 bm25;
2.2 实现文本切割成句子
List
if (document == null) return sentences;
for (String line : document.split("[\r\n]"))
{
line = line.trim();//去掉字符串的首尾空格
if (line.length() == 0) continue;
for (String sent : line.split("[,,.。::“”??!!;;]"))
{
sent = sent.trim();
if (sent.length() == 0) continue;
sentences.add(sent);
}
}
2.3 使用开源jar包对中文文本进行分词,并获得分词结果
List
List> docs = new ArrayList
>();
for (String sentence : sentenceList)
{
List
List
for (Term term : termList)
{
if (shouldInclude(term))
{
wordList.add(term.getRealName());
}
}
docs.add(wordList);
}
TextRankSummary textRankSummary = new TextRankSummary(docs);
int[] topSentence = textRankSummary.getTopSentence(size);
List
for (int i : topSentence)
{
resultList.add(sentenceList.get(i));
}
return resultList;
2.4 运用公式计算出每个句子的权重并进行排序
int cnt = 0;
for (List
{
double[] scores = bm25.simAll(sentence);//计算相似度
System.out.println(Arrays.toString(scores));
weight[cnt] = scores;
weight_sum[cnt] = sum(scores) - scores[cnt]; // 减掉自己,自己跟自己肯定最相似
vertex[cnt] = 1.0;
++cnt;
}
for (int _ = 0; _ < max_iter; ++_)
{
double[] m = new double[D];
double max_diff = 0;
for (int i = 0; i < D; ++i)
{
m[i] = 1 - d;
for (int j = 0; j < D; ++j)
{
if (j == i || weight_sum[j] == 0) continue;
m[i] += (d * weight[j][i] / weight_sum[j] * vertex[j]);
}
double diff = Math.abs(m[i] - vertex[i]);
if (diff > max_diff)
{
max_diff = diff;
}
}
vertex = m;
if (max_diff <= min_diff) break;
}
//
for (int i = 0; i < D; ++i)
{
top.put(vertex[i], i);
}
2.5 设置想要获取的目标摘要长度,并根据排序结果取出摘要
Collection
size = Math.min(size, values.size());
int[] indexArray = new int[size];
Iterator
for (int i = 0; i < size; ++i)
{
indexArray[i] = it.next();
}
return indexArray;
以上就是对TextRank算法的学习内容的概括。
---------------------
作者:GY_Grace
来源:CSDN
原文:https://blog.csdn.net/GY_Grace/article/details/72863632
版权声明:本文为博主原创文章,转载请附上博文链接!