485 个字符的 HTML 去标签后剩 10 行,判为正文的只有 5 行。 5 句按 bigram 权重打分取前 3 句,原文 148 字压到 98 字,压缩比 66.2%——抽取式摘要压不动, 因为它只能整句搬。
上一节做车牌,是「从图里取字」;这一节做网页,是「从一堆标签里取正文」。 两件事的骨架一样:先剔噪声,再取主体。
一、正文抽取:先把「不是正文的」剔掉
一个网页里,正文常常只占一成多。剩下的是导航、广告、推荐位、版权声明、评论区。 Demo 的 485 个字符,去标签后剩 10 个非空行。判为正文的 5 行,剔掉 5 行。 剔除规则很土:行太短(少于 12 字)不像正文; 命中「广告」「招租」「相关推荐」「版权所有」这类关键词的,直接扔。 真实系统不这么干。 它们算文本密度(这一块标签少、文字多)、链接密度(导航区链接扎堆),还看 DOM 结构路径。 土办法的毛病一眼能看出来:标题只有 12 字,正好卡在门槛上被误杀;而一条写得又臭又长的广告会被误留。
二、抽取式摘要:按句子打分,挑最高的几句
抽取式摘要只做一件事:从原文里挑句子,一个字都不改。 打分用的是 bigram 权重。先统计全文所有相邻两字组合出现的次数,去掉停用组合; 每个句子把它的 bigram 权重加起来,再除以句长归一。 Demo 的 5 句一共产生 122 种 bigram。得分最高的一句是 1.31。 这个打分的直觉是:反复出现的词组代表主题,含主题词多的句子更像摘要。 除以句长是为了防止长句靠字数刷分。 它有个明显的缺陷:三个句子可能说的是同一件事,摘要就重复了。 所以真实的抽取式算法后面还加一步「冗余惩罚」。
三、66.2% 的压缩比意味着什么
原文 148 字,摘要 98 字,压掉三分之一。三句分别是 37 字、30 字、31 字。 这个比例说明抽取式压不动。 原因在方法本身——它只能整句搬,不能合并、不能换说法、不能把三个短句揉成一句。 想压到 20%,只能改写。改写就得有生成模型。 所以真实的摘要产品很少纯抽取。 常见做法是抽取式先筛出候选段,再用生成模型改写压缩——抽取负责「不漏」,生成负责「压紧」。 这个两段式结构在别处也常见:先用便宜的方法把候选缩到很小,再让贵的模型处理小候选集。 检索增强生成就是这个思路。
四、抽取和生成,各有各的坑
抽取式的坑是啰嗦和断链。第三句开头的「不过」,在摘要里可能前面没有可转折的内容,读着就别扭。 生成式的坑是会编。 模型可能把「下降约四成」写成「下降四成以上」,数字一改,性质就变了,而且看不出痕迹。 所以做摘要产品的第一件事不是选模型,是定「能不能接受编」。 法律、医疗、财务类文档,宁可啰嗦也不能编。 折中的工程做法:生成完之后做数字和专有名词的回查,对不上的句子直接退回原文。 这一步不加模型,纯字符串匹配,成本极低,能挡掉大半事故。
五、动手 Demo:网页正文抽取与抽取式摘要:不联网也能跑的那一半
把一页 HTML 直接写在代码里(没有联网抓取),剥掉标签得到 10 个非空行; 按长度和关键词剔掉导航、广告、版权这类噪声,留下 5 行正文; 再切成句子,统计 bigram 权重给每句打分,取前三句拼成摘要,算压缩比。
txt = re.sub(r'<[^>]+>', u'\n', html)
lines = [t.strip() for t in txt.split(u'\n') if t.strip()]
body = [t for t in lines
if len(t) >= 12 and not any(k in t for k in NOISE)]
sc = sum(w.get(s[i:i + 2], 0.0) for i in range(len(s) - 1))
sc = sc / max(len(s), 1) # 按句长归一
实跑输出:
--------------------------------------------------------------------
网页正文抽取与抽取式摘要:不联网也能跑的那一半
--------------------------------------------------------------------
原始 HTML 485 字符
去标签后 10 个非空行
第 1 行 城市夜间照明节能改造观察(12 字)
第 2 行 首页 | 新闻 | 联系(12 字)
第 3 行 广告位招租,联系电话 400-000-0000(23 字)
第 4 行 近年来,多地推进城市夜间照明节能改造,把传统高压钠灯(37 字)
第 5 行 据某市城建部门统计,改造完成后主城区路灯年耗电量下降(30 字)
第 6 行 不过,也有居民反映部分路段亮度过高,影响临街住户休息(27 字)
第 7 行 业内人士建议,节能改造应同步建立亮度分区标准,避免一(31 字)
第 8 行 目前该市已完成三轮改造,涉及道路一千二百余条。(23 字)
第 9 行 相关推荐:十条必看(9 字)
第 10 行 版权所有(4 字)
判为正文 5 行
剔掉 5 行(导航、广告、页脚、标题)
句子数 5
bigram 种数 122
摘要取前 3 句
[1.31] 近年来,多地推进城市夜间照明节能改造,把传统高压钠灯替换为 LED 光源。
[1.27] 据某市城建部门统计,改造完成后主城区路灯年耗电量下降约四成。
[1.18] 业内人士建议,节能改造应同步建立亮度分区标准,避免一味追求亮。
原文长度 148 字
摘要长度 98 字
压缩比 66.2%
这是「抽取式」摘要:只挑原句,不改写。所以它一定不会编造,
但也一定不如人写得好——它不会合并、不会换说法。
「生成式」摘要(大模型那种)才会改写,代价是可能编。
这页 HTML 是我内嵌在代码里的字符串,没有联网抓取。
10 行里判为正文 5 行。被剔的五个:标题(正好 12 字,卡门槛被误杀)、导航、广告、推荐、版权。 标题被误杀是这套规则的直接后果——门槛是我拍的 12,而真实标题往往就这么短。 这条要说清,别让人以为抽取很准。 得分前三 1.31、1.27、1.18,三句内容正好是「做了什么、效果多少、还缺什么」。 这个顺序不是算法排的,是原文顺序。归一化之后分数差距不大。 压缩比 66.2%:原文 148 字压到 98 字。抽取式就这个水平,想再低只能改写。
30 秒实验
- 把长度门槛从 12 改成 8 和 20,看判为正文的行数怎么变。
- 把摘要句数从 3 改成 1 和 5,看压缩比和内容完整度怎么变。
- 想一想:为什么法律、财务类文档的摘要宁可啰嗦也不能编?
常见误区
- 「摘要就是压缩」——抽取式只是挑句子,一个字都没改。
- 「压缩比越低越好」——压得越狠越容易丢关键限定词。
- 「生成式摘要更先进」——它会编,数字一改性质就变了。
自测三问(点开对答案)
1. 正文抽取在真实系统里靠什么信号? —— 文本密度、链接密度和 DOM 结构路径,不是关键词表。 2. 抽取式摘要为什么压不到很低? —— 它只能整句搬,不能合并也不能换说法。 3. 生成式摘要最大的风险是什么? —— 改写时把数字和限定词改错,而且看不出痕迹。文本也过了一遍。本章最后一个实例回到声音:让 AI 和人对话。
- ☐ (本节完,下一节 5.2.8 实例8:使用AI进行语音聊天)