🧠 第五章 深度学习算法
📄 一句话概括

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 秒实验

  1. 把长度门槛从 12 改成 8 和 20,看判为正文的行数怎么变。
  2. 把摘要句数从 3 改成 1 和 5,看压缩比和内容完整度怎么变。
  3. 想一想:为什么法律、财务类文档的摘要宁可啰嗦也不能编?

常见误区

  1. 「摘要就是压缩」——抽取式只是挑句子,一个字都没改。
  2. 「压缩比越低越好」——压得越狠越容易丢关键限定词。
  3. 「生成式摘要更先进」——它会编,数字一改性质就变了。
自测三问(点开对答案) 1. 正文抽取在真实系统里靠什么信号? —— 文本密度、链接密度和 DOM 结构路径,不是关键词表。 2. 抽取式摘要为什么压不到很低? —— 它只能整句搬,不能合并也不能换说法。 3. 生成式摘要最大的风险是什么? —— 改写时把数字和限定词改错,而且看不出痕迹。

文本也过了一遍。本章最后一个实例回到声音:让 AI 和人对话。

相关笔记