抽取式文本摘要:选择最重要的原文句子

FreeGuideOnline 最新 2026-06-15

抽取式文本摘要:从零基础到实战应用

什么是抽取式文本摘要?

面对长篇资讯、学术论文或报告,如何快速抓住核心内容?抽取式摘要(Extractive Summarization)给出了最直接的答案:直接从原始文本中选择最重要的几个句子,不生成任何新文本。就像用荧光笔在文章里划线,最终把所有高亮句子连起来形成摘要。

与“生成式摘要”相比,抽取式方法始终保留原文语句,因此语法更可靠、事实更准确,适合新闻摘编、法律文书凝练、文献综述等对准确性要求极高的场景。

抽取式摘要的通用工作流程

无论使用哪种算法,抽取式摘要都遵循三步流水线:

  1. 文本预处理
    分句、分词、去除停用词、词形还原或词干提取。中文还需要分词和词性标注。

  2. 句子重要性评分
    为每个句子打分,衡量它承载文章核心信息的程度。常见的评分思路包括词频统计、图模型排序、相似度比较及机器学习分类。

  3. 摘要生成
    按得分降序排列句子,选择Top-K个句子,再按原文顺序排列,保证摘要连贯性。K的大小取决于期望摘要长度(如原文20%的句子数)。

下面我们将深入剖析三种主流评分方法,并附上可直接运行的Python示例。

方法一:基于词频—统计(TF-IDF)

这是最直观的方法:出现频率高但在整个语料中稀有的词,往往承载文章主题。先计算每个词的TF-IDF值,再将句子中所有词的TF-IDF值求和或取平均,作为句子得分。

实现步骤

  • 将文档集合视为该单一文档,或使用预训练IDF词表。
  • 对文档分句,每句分词后计算每个词的TF-IDF权重。
  • 句子得分 = 句中各词TF-IDF值的平均值(可排除停用词)。
  • 按得分排序,选取前K句。

代码演示(Python + scikit-learn)

from sklearn.feature_extraction.text import TfidfVectorizer
from nltk.tokenize import sent_tokenize
import numpy as np

text = """此处放置长文本..."""  # 请用实际文本替换
sentences = sent_tokenize(text)

# 将每个句子视为一个文档,计算TF-IDF矩阵
vectorizer = TfidfVectorizer(stop_words='english')
tfidf_matrix = vectorizer.fit_transform(sentences)

# 每句得分等于该句所有词TF-IDF的均值
sentence_scores = np.array(tfidf_matrix.mean(axis=1)).flatten()

# 选择得分最高的3句,并按原文顺序输出
top_idx = sentence_scores.argsort()[-3:][::-1]
summary_sentences = [sentences[i] for i in sorted(top_idx)]
print(' '.join(summary_sentences))

优点:简单快速,无需标注数据。
缺点:忽略词序与语义,易偏向长句,且无法处理同义词。

方法二:基于图排序——TextRank

TextRank借鉴了PageRank思想,将句子看作图中的节点,句子间的相似度作为边的权重,通过迭代计算各节点的重要性得分。

原理简述

  1. 构建句子相似度矩阵:通常采用TF-IDF余弦相似度,也可使用词向量平均余弦。
  2. 构造加权无向图或全连接图,权重为相似度值。
  3. 用PageRank公式迭代更新每个句子的得分,直至收敛。
  4. 选取得分最高的句子作为摘要。

实战示例(使用NetworkX)

import nltk
import numpy as np
import networkx as nx
from sklearn.metrics.pairwise import cosine_similarity
from nltk.tokenize import sent_tokenize
from sklearn.feature_extraction.text import TfidfVectorizer

nltk.download('punkt')

# 分句并构建TF-IDF矩阵
sentences = sent_tokenize(text)
vectorizer = TfidfVectorizer()
sentence_vectors = vectorizer.fit_transform(sentences).toarray()

# 计算余弦相似度矩阵
sim_matrix = cosine_similarity(sentence_vectors)

# 构建图并应用PageRank
graph = nx.from_numpy_array(sim_matrix)
scores = nx.pagerank(graph)

# 排序选句
ranked_sentences = sorted(((scores[i], s) for i, s in enumerate(sentences)), reverse=True)
summary = ' '.join([s for _, s in ranked_sentences[:3]])
print(summary)

优点:不需要额外语料,能捕捉全局重要性。
缺点:相似度度量对短文本敏感,计算复杂度随句子数平方增长。

方法三:基于聚类——最大边缘相关(MMR)与K-中心点

单纯按重要性排序容易导致摘要冗余,比如两句话虽然得分很高但几乎表达同一意思。引入冗余控制即可在重要性与多样性之间取得平衡。

MMR(Maximal Marginal Relevance)

MMR是一种贪心选择策略:每次从候选句子中选出一个既与原文查询高度相关(重要性),又与已选摘要句子差异较大(多样性)的句子。

公式简化版:

$$MMR = \lambda \cdot Sim(S_i, Q) - (1-\lambda) \cdot \max_{S_j \in Summary} Sim(S_i, S_j)$$

其中$Q$可以是整篇文档的向量表示,$\lambda$调节多样性比重。

代码思想

  1. 用TF-IDF向量代表文档$Q$和所有句子。
  2. 初始化空摘要集合。
  3. 循环选择直到达到所需句子数:
    • 对剩余句子计算与$Q$的相似度(奖励)和与已选句子的最大相似度(惩罚)。
    • 选择综合得分最高的句子,加入摘要集合。
  4. 最后按原文顺序输出。

K-中心点聚类

将句子向量聚类成K个簇,每个簇的簇心(句子)即为该主题的代表,选出的摘要自然覆盖不同侧面。可使用K-Medoids算法直接选择真实句子作为簇心。

适用场景:话题分散、多主题长文档。

如何评估抽取式摘要的质量?

没有完美答案,常用ROUGE指标(Recall-Oriented Understudy for Gisting Evaluation)自动对比生成摘要与人工参考摘要的重叠度:

  • ROUGE-1:一元词组重叠率
  • ROUGE-2:二元词组重叠率
  • ROUGE-L:最长公共子序列匹配

计算前需要人工标注黄金摘要。同时建议人工阅读检查可读性与信息完整性。

进阶优化建议

  1. 句子位置先验
    首段、段落首句和尾句往往更具概括性,可对位置信息加权。

  2. 标题/特定词提示
    与标题词共现的句子提升得分。

  3. 结合词嵌入
    用Word2Vec、GloVe或BERT表示句子,计算相似度更准确。

  4. 有监督学习
    若拥有人工标注的重要/不重要句子,可训练二分类器(逻辑回归、XGBoost、BERT等),预测句子标签后按置信度抽取。这是当前效果最好的方向。

常见问题与误区

  • 只选长句:长句得分容易虚高,需做长度归一化或设定最短/最长限制。
  • 过度修剪:摘要句子数太少会丢失关键信息,建议保留原文10%-30%的句子。
  • 忽略指代:被选中的句子若含有代词(它、这),可能在摘要中找不到先行词。可加指代消解预处理,或尽量选取自包含句子。

零代码实践工具推荐

  • Sumy库:集成了LexRank、TextRank、LSA等多种抽取式算法,一行命令生成摘要。
  • Hugging Face Pipeline:使用transformers库的summarization管道,虽多为生成式,但社区存在抽取式模型卡。

抽取式文本摘要作为自然语言处理的经典任务,兼顾效率与可靠性。从简单的词频法到复杂的图模型和MMR,读者可根据数据和场景灵活选用。建议动手尝试不同算法,理解过程中的权衡,并始终以阅读体验为最终检验标准。