TextRank算法的基本思想是将文档看作一个词的网络(一种基于图的排序方法,用于提取相关句子或查找关键字),该网络中的链接表示词与词之间的语义关系。
TextRank算法主要包括:关键词抽取、关键短语抽取、关键句抽取。
(1)关键词抽取(keyword extraction)
关键词抽取是指从文本中确定一些能够描述文档含义的术语的过程。对关键词抽取而言,用于构建顶点集的文本单元可以是句子中的一个或多个字;根据这些字之间的关系(比如:在一个框中同时出现)构建边。根据任务的需要,可以使用语法过滤器(syntactic filters)对顶点集进行优化。语法过滤器的主要作用是将某一类或者某几类词性的字过滤出来作为顶点集。
(2)关键短语抽取(keyphrase extration)
关键词抽取结束后,我们可以得到的N个关键词,在原始文本中相邻的关键词构成关键短语。因此,从get_keyphrases函数的源码中我们可以看到,它先调用get_keywords抽取关键词,然后分析关键词是否存在相邻的情况,最后确定哪些是关键短语。
(3)关键句抽取(sentence extraction)
句子抽取任务主要针对的是自动摘要这个场景,将每一个sentence作为一个顶点,根据两个句子之间的内容重复程度来计算他们之间的“相似度”,以这个相似度作为联系,由于不同句子之间相似度大小不一致,在这个场景下构建的是以相似度大小作为edge权重的有权图。
这是利用TextRank提取的一些摘要
效果很差:
from snownlp import SnowNLP
import re
import jieba.analyse
import jieba.posseg
import os
import json
import re
import jieba.analyse
import jieba.posseg
class TextSummary:
def __init__(self, text):
self.text = text
def splitSentence(self):
sectionNum = 0
self.sentences = []
for eveSection in self.text.split("\n"):
if eveSection:
sentenceNum = 0
for eveSentence in re.split("!|。|?", eveSection):
if eveSentence:
mark = []
if sectionNum == 0:
mark.append("FIRSTSECTION")
if sentenceNum == 0:
mark.append("FIRSTSENTENCE")
self.sentences.append({
"text": eveSentence,
"pos": {
"x": sectionNum,
"y": sentenceNum,
"mark": mark
}
})
sentenceNum = sentenceNum + 1
sectionNum = sectionNum + 1
self.sentences[-1]["pos"]["mark"].append("LASTSENTENCE")
for i in range(0, len(self.sentences)):
if self.sentences[i]["pos"]["x"] == self.sentences[-1]["pos"]["x"]:
self.sentences[i]["pos"]["mark"].append("LASTSECTION")
def getKeywords(self):
self.keywords = jieba.analyse.extract_tags(self.text, topK=100, withWeight=False, allowPOS=('n', 'vn', 'v'))
def sentenceWeight(self):
# 计算句子的位置权重
for sentence in self.sentences:
mark = sentence["pos"]["mark"]
weightPos = 0
if "FIRSTSECTION" in mark:
weightPos = weightPos + 2
if "FIRSTSENTENCE" in mark:
weightPos = weightPos + 2
if "LASTSENTENCE" in mark:
weightPos = weightPos + 1
if "LASTSECTION" in mark:
weightPos = weightPos + 1
sentence["weightPos"] = weightPos
# 计算句子的线索词权重
index = [" 总之 ", " 总而言之 "]
for sentence in self.sentences:
sentence["weightCueWords"] = 0
sentence["weightKeywords"] = 0
for i in index:
for sentence in self.sentences:
if sentence["text"].find(i) >= 0:
sentence["weightCueWords"] = 1
for keyword in self.keywords:
for sentence in self.sentences:
if sentence["text"].find(keyword) >= 0:
sentence["weightKeywords"] = sentence["weightKeywords"] + 1
for sentence in self.sentences:
sentence["weight"] = sentence["weightPos"] + 2 * sentence["weightCueWords"] + sentence["weightKeywords"]
def getSummary(self, ratio=0.1):
self.keywords = list()
self.sentences = list()
self.summary = list()
# 调用方法,分别计算关键词、分句,计算权重
self.getKeywords()
self.splitSentence()
self.sentenceWeight()
# 对句子的权重值进行排序
self.sentences = sorted(self.sentences, key=lambda k: k['weight'], reverse=True)
length = 0
# 根据排序结果,取排名占前 ratio% 的句子作为摘要
for i in range(len(self.sentences)):
if length<3:
if i < ratio * len(self.sentences):
sentence = self.sentences[i]
self.summary.append(sentence["text"])
length+=1
return self.summary
def get_abstract(text):
testSummary = TextSummary(text)
abstract_content = ".".join(testSummary.getSummary())
return abstract_content
if __name__ == '__main__':
sample = ''
abstract_content = get_abstract(sample)