A26

NLP 基础

点击正文段落选定收藏或划线位置;未选定时使用屏幕内第一段。

课内目录

1 NLP 基础要回答什么

自然语言处理,简称 NLP,研究怎样让计算机从文本中提取可用信息,或按任务要求生成文本。这里的“理解”需要落到可以检查的行为:把垃圾短信筛出来,把求助内容分到正确类别,或者从评论中识别情感倾向。模型输出听起来流畅,并不等于分类准确;分类成绩较高,也不等于模型具备完整的语言理解能力。本课以短文本分类为主线,建立从原始句子到可评估预测的基础流程。

先把问题写成输入与输出。对于短信过滤,输入是收到的短信正文,输出可以是“正常”或“垃圾”,以及供阈值判断使用的分数。标签应描述实际要做的决定。“带有优惠词”是输入线索,“应送入垃圾箱”才可能是任务标签。家人发送优惠信息仍可能是正常短信,因此不能把某个关键词直接当作标签定义,也不能以为模型只要记住敏感词就能完成任务。

文本分类与其他机器学习任务有共同骨架。在表格流失预测中,每条记录可能有登录次数、使用时长等数值特征;图像分类把像素转换成可学习的表示;文本分类则需要把长度不等的文字转换成特征。它们都需要训练集学习规律、验证集选择方案、测试集估计最终效果。但文本里同义表达多、词序有意义、拼写变化常见,不能照搬表格中“每列含义固定”的直觉。

公开的 UCI SMS Spam Collection 包含 5574 条英文短信及正常、垃圾标签,适合演示入门基线。它的规模有限、垃圾类别占比较低,且来自特定收集背景。用它完成实验,可以证明流程是否跑通,却不能证明系统能够处理今天的中文短信、企业工单或其他来源的消息。数据集名称、语言、来源和时间范围,都是结果解释的一部分。

文本任务从业务问题走向可评估预测
文本任务从业务问题走向可评估预测

设想模型看见“免费领取礼品”,它可能根据“免费”“领取”提高垃圾分数。但“提醒:不要点击免费领取礼品的链接”包含相同词语,意图却不同。入门方法能够捕捉词语与类别的统计关联,对否定、引用和复杂上下文的处理往往有限。基础课要学会同时描述能力和边界,避免把任务中的局部成功说成普遍理解。

开始实验前,至少明确谁提供文本、预测用于什么动作、哪类错误代价更高。垃圾短信漏过会打扰用户,正常短信被拦截可能造成更大损失。业务可以先采用“进入待检查列表”,积累证据后再考虑自动拦截。评价指标与上线动作应对应:先定义目标,才能判断得到的分数是否有用。

2 分词、词表与表示

计算机需要把文本变成可计算的对象。字符编码解决文字怎样保存,例如 UTF-8 如何保存汉字;分词解决模型把什么当作单位;表示解决怎样把这些单位转换成数字。文件能够正确显示,只说明编码可读,还没有解决“这句话有哪些可用特征”。这几层出错时表现不同,排查时应分别检查。

英文常以空格提供词边界,但“don't”、网址、表情和连字符仍需要规则。中文通常没有天然空格,“研究生命起源”需要选择合理的切分方式。按词切分更接近日常词语,按字切分更容易覆盖陌生词;按字符片段切分还能捕捉局部组合。不存在对所有任务都最好的切法,应根据语言、数据规模与错误样例选择。中文任务不能因为英文示例能运行,就直接沿用默认英文分词规则。

分词之前可能要做 Unicode 规范化、大小写处理、空白合并等清洗。每步都需要理由。“FREE”和“free”在英文垃圾短信中常可合并,但大小写可能对代码、专名有用。删除所有标点会丢掉问号、感叹号等线索;删除所有数字可能抹去金额、日期或验证码。清洗不是越彻底越好,而是减少无关差异,同时保留任务需要的差异。

词表把训练中选中的单位映射为特征位置。假设词表只有“免费、领取、会议、明天”这 4 项,“明天会议”可以表示成 [0, 0, 1, 1]。词袋表示记录每个词是否出现或出现多少次,不记录完整词序。所以“我喜欢你”和“你喜欢我”可能得到相同向量。这个限制不是代码错误,而是表示本身丢弃了信息。

TF-IDF 在词频基础上调整权重:某个词在当前文档中突出、在许多其他文档中不常见时,往往获得较高权重。实际公式可能使用平滑、对数和向量归一化,应记录所用实现。常见词不必然无用,罕见词也不必然有用;随机编号可能很罕见,却只是噪声。TF-IDF 是可检验的基线选择,不是对语言意义的直接测量。

分词和词表如何生成稀疏表示
分词和词表如何生成稀疏表示

词表和逆文档频率都必须只从训练集拟合。假如提前让向量器浏览全部文本,再切训练集与测试集,测试集的词分布就参与了表示选择,即使标签没有传入,也破坏了独立评估。验证、测试和线上文本只能使用已经冻结的规则转换。新文本中的陌生词怎样处理,也应在这里确定,而不是上线后临时补丁。

词袋向量通常很长,但每条短文本只占少数位置,因此适合稀疏存储。长度为 10000 的向量不意味着每条短信要保存 10000 个浮点数。稀疏表示主要保存非零位置及其数值,能够配合线性分类器快速训练。后续课程会讨论稠密向量与上下文表示;本课先理解“原文经过什么规则,哪些信息被保留或丢弃”。

还可以加入相邻词组合,例如把“not good”作为 2 元词组特征,补充单词特征看不见的局部顺序。这通常会扩大词表,需要更多数据支持。停用词表也应谨慎使用:删除“not”可能直接破坏否定信息。选择表示时,先观察真实句子经过转换后的结果,再讨论模型复杂度,比凭经验堆叠清洗操作更可靠。

3 语言模型与文本分类边界

文本分类模型回答“这段文本属于哪个类别”。本课的逻辑回归接收 TF-IDF 向量,学习每个特征对垃圾类别分数的影响,再通过阈值形成决定。它不需要生成句子,也不需要预测下个词。特征权重可以帮助检查模型依赖什么,但高权重仅表示训练数据中的关联,不能直接解释成某个词在所有语境下都代表垃圾信息。

语言模型学习文本序列中的统计规律,常见训练目标包括根据上下文预测后续单位。它可以成为生成、表示学习或分类系统的组成部分,但“会预测文本”与“满足当前分类要求”是不同的检验问题。即使使用语言模型完成分类,仍需要固定标签定义、输入格式、输出解析方式和评估数据,不能用几次看似合理的回答代替系统测量。

对于标签稳定、数据量不大、需要低延迟的任务,词袋加线性模型通常值得先做。它训练快、容易追踪特征,也能暴露数据问题。对于强依赖语境、长距离关系或多义词的任务,简单表示可能遇到上限。是否更换模型,应看错误来自哪里:标签含糊、数据重复、输入缺失造成的问题,不会因为换用更复杂模型就自然消失。

假设 1000 条测试短信中有 100 条垃圾短信。模型抓住 80 条垃圾短信,错放 20 条;另把 20 条正常短信误判成垃圾,正确放行 880 条。把垃圾设为正类,就有 TP=80、FN=20、FP=20、TN=880。精确率 precision=TP/(TP+FP)=0.80,召回率 recall=TP/(TP+FN)=0.80,F1 为两者的调和平均,在这个例子中也是 0.80。

从混淆矩阵理解阈值下的分类指标
从混淆矩阵理解阈值下的分类指标

这个例子的准确率是 0.96,但全部预测为正常也能得到 0.90。类别不平衡时,只看准确率会掩盖正类是否被识别。F1 同时考虑精确率和召回率,却不直接体现正常短信误拦的具体业务损失。报告中应明确正类、各类样本数、阈值与混淆矩阵,才能让指标对应到实际错误。

ROC-AUC 衡量连续分数把正例排在负例前面的能力,需要每条样本的分数,不能从某个阈值的混淆矩阵直接推算。它不代表上线阈值已经合适,也不表示输出概率已经校准。正类很少时,还可补充精确率—召回率曲线。入门阶段先记住:排序质量、阈值下的错误、概率是否可信,是需要分别检查的问题。

4 动手:构建一次文本分类基线

实验目标是用英文短信正文预测 ham 或 spam,把 spam 定义为正类。准备 UCI SMS Spam Collection 解压后的 SMSSpamCollection 文件,原始记录以制表符分隔标签和正文。下面的代码要求本地已有这个公开数据文件,并已安装 pandas 与 scikit-learn;它不会下载数据。记录数据来源、文件摘要、依赖版本和代码版本,才能让另一个人复现实验。

先做确定性的规范化与重复检查,再冻结划分。本例将 Unicode 兼容形式统一、合并空白并折叠大小写,但保留数字和标点。规范化后相同的句子只保留 1 条;相同句子标签冲突的记录全部隔离,另行检查。去重需要浏览文本以确定重复组,这是划分前的数据治理;它不学习词表或分类参数,也不能被当成随意研究测试样例的理由。

import re
import unicodedata
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import (
    precision_score, recall_score, f1_score,
    roc_auc_score, confusion_matrix,
)

def normalize(text):
    text = unicodedata.normalize("NFKC", text).casefold()
    return re.sub(r"\s+", " ", text).strip()

df = pd.read_csv(
    "SMSSpamCollection", sep="\t", header=None,
    names=["label", "raw"], encoding="utf-8",
    keep_default_na=False,
)
assert set(df["label"]) == {"ham", "spam"}
df["text"] = df["raw"].map(normalize)
conflict = df.groupby("text")["label"].transform("nunique") > 1
print("隔离冲突记录:", int(conflict.sum()))
df = df.loc[~conflict & df["text"].ne("")]
df = df.drop_duplicates("text").copy()
df["y"] = df["label"].eq("spam").astype(int)

train, rest = train_test_split(
    df, test_size=0.40, random_state=26, stratify=df["y"],
)
val, test = train_test_split(
    rest, test_size=0.50, random_state=26, stratify=rest["y"],
)
for name, part in [("train", train), ("val", val), ("test", test)]:
    print(name, "样本数:", len(part), "正类数:", int(part["y"].sum()))

model = Pipeline([
    ("tfidf", TfidfVectorizer(
        lowercase=False, token_pattern=r"(?u)\b\w+\b",
        ngram_range=(1, 1), min_df=2, max_features=10000,
    )),
    ("clf", LogisticRegression(max_iter=1000, random_state=26)),
])
model.fit(train["text"], train["y"])
positive_col = list(model.classes_).index(1)
val_score = model.predict_proba(val["text"])[:, positive_col]

# 演示规则:只在验证集上,从预先列出的阈值中选择 F1 最高者。
candidates = [0.30, 0.50, 0.70]
threshold = max(
    candidates,
    key=lambda t: f1_score(val["y"], val_score >= t, zero_division=0),
)
print("验证集选择的阈值:", threshold)

# 完成全部选择后才执行以下最终测试;不要按结果反复改方案。
test_score = model.predict_proba(test["text"])[:, positive_col]
test_pred = test_score >= threshold
print("precision:", precision_score(test["y"], test_pred, zero_division=0))
print("recall:", recall_score(test["y"], test_pred, zero_division=0))
print("F1:", f1_score(test["y"], test_pred, zero_division=0))
print("ROC-AUC:", roc_auc_score(test["y"], test_score))
print("混淆矩阵:", confusion_matrix(test["y"], test_pred, labels=[0, 1]))

划分比例约为 60% 训练、20% 验证、20% 测试,实际条数受去重与取整影响,应以程序输出为准。分层抽样尽量保持类别比例,却不能阻止近重复短信或同一发送者跨集合。若掌握发送者、模板或会话标识,应按这些群组划分;若目标是预测未来短信,应考虑按时间留出后续数据。随机划分只是本地教学起点。

流水线的作用是把向量器和分类器绑定起来:fit 时只用训练集建立词表、计算 IDF 并学习分类参数;验证与测试只执行转换和预测。本例分词器保留字母、数字等词字符组成的片段,标点虽在规范化文本中保留,却不会成为当前词级特征。应区分“清洗未删除”和“模型实际使用”,避免误以为所有保留字符都进入了模型。

冻结划分后训练、选择与最终测试的顺序
冻结划分后训练、选择与最终测试的顺序

示例按验证 F1 选择阈值,是为了展示完整流程。实际短信拦截可能要求精确率达到某个下限,再尽量提高召回率;如果验证集上没有候选满足要求,应报告没有可接受方案。不能为了得到上线结论而降低事先定义的验收条件。阈值也是方案参数,需要和模型、词表、清洗规则一起保存。

先把“始终预测正常”作为对照,再检查模型在哪些句子上改进。验证错误可以按短句、含网址、含数字、否定表达等类型归组,观察是否集中失败。模型训练出现迭代未收敛警告时应处理,不要忽略后直接报成绩。本文不提供预设跑分;没有实际执行与固定数据版本,就不能把示意数字写成实验结论。

5 复杂度与语料规模取舍

模型成本不只来自样本条数,还来自词表大小、每条文本的长度和非零特征数量。对词级 TF-IDF 而言,文本变长通常增加分词与转换工作;词表扩大增加参数与索引占用;引入相邻词组合会产生更多候选特征。稀疏矩阵能节省空间,但无法让无限扩展词表变得免费。应记录训练耗时、模型文件大小和单条预测延迟。

max_features 限制最多保留多少个特征,min_df 限制特征至少出现在多少篇训练文档中。前者能控制规模,后者能过滤偶发拼写和噪声。限制太紧可能删掉罕见但关键的垃圾线索;限制太松可能保留大量只出现过少数次的编号或错字。取舍应由验证效果和资源测量共同决定,不能假定词表越大越好。

交互中的曲线只用于理解取舍,不是 UCI 数据集的测量结果。真实实验可固定其余设置,比较 1000、3000、6000、10000 个特征上限,记录验证 F1、精确率、召回率、耗时与模型大小。小范围比较后冻结选择。尝试的组合越多,越可能偶然迎合验证集,因此也应记录选择次数,避免把验证集当成无限可用的最终证据。

语料和特征选择如何共同影响成本与效果
语料和特征选择如何共同影响成本与效果

增加语料时,首先区分“新增独立信息”和“复制已有模板”。重复 1000 条相似广告,未必比补充 100 条来自新来源的困难样本更有价值。学习曲线可以在固定验证集上,使用逐步增大的训练子集比较效果。如果训练效果很好、验证效果明显落后,可能存在过拟合或分布差异;如果两者都差,可能需要检查标签、表示和任务是否可由当前输入解决。

更多字符特征有时能缓解陌生词问题,例如让新品牌名中的局部片段复用已有特征;代价是特征空间扩大,也可能把无意义片段当线索。中文可以比较按字、按词和有限长度字符片段,但每次变更都应保持划分一致。资源预算紧时,先修复输入和标注问题,往往比直接升级复杂模型更有效。

数据清洗、人工标注与误判复核也有成本。若新数据的标签质量不稳定,扩大训练量可能同时扩大噪声。应优先收集与线上错误有关、来源可解释的样本,再评估新增样本是否补足少数类或新表达。语料规模应服务于覆盖范围,而不是成为脱离任务的数字目标。

6 常见坑:泄漏的测试句当作成绩

最容易制造漂亮成绩的错误,是让测试信息提前参与训练或方案选择。比如先在全部短信上生成 TF-IDF,再切集合;同一广告模板稍改号码后同时出现在训练与测试中;看完测试错例后修改停用词,再把原测试集成绩当作最终结果。它们不一定表现为代码报错,却会让离线成绩高估未来能力。

数据泄漏也可能来自标签之后才出现的信息。若数据导出时把“已举报”或人工审核结论拼进正文,模型会学到真实预测时不存在的特征。另一个例子是把文件名中的 spam 目录名当作输入。要按预测发生的时刻检查每项特征:当时能否取得、取得方式是否一致、是否由目标结果派生。字段存在于数据表,并不代表它可以用于预测。

测试集应在实验开始时冻结,并限制访问。验证集用于选词表、模型和阈值,测试集只在选择完成后报告最终结果。如果测试结果暴露了新的故障,可以修复,但修复后要诚实说明原测试集已参与开发,并另准备独立评估数据。不能继续把同一份被反复查看的数据叫作从未接触的测试集。

从成绩异常到泄漏定位的排查路径
从成绩异常到泄漏定位的排查路径

近重复检测不能只比较原始字符串。“免费领取,点击链接 A”和“免费领取,点击链接 B”可能来自同一模板。可用规范化文本、字符片段相似度和人工抽查识别相关样本,再按模板组划分。相似度规则也会误把不同意图合并,不能盲目删除。应记录分组依据,并检查重复簇里的标签冲突与真实差异。

类别不平衡是另一个常见陷阱。验证集只有很少正例时,少错几条就可能让召回率大幅变化。除了分层划分,还要报告正类支持数;必要时用仅发生在训练范围内的交叉验证了解波动。若使用过采样,必须放在每个训练折内部,不能先复制少数类再切集合,否则复制品可能跨集合形成泄漏。

阈值移动可以交换精确率与召回率,却不能创造模型没有学到的排序能力。加类别权重也会改变训练侧重点,但不保证所有指标同时改善。排查顺序宜从数据与划分开始,再看特征与阈值,最后评估模型是否不足。异常高分和异常低分都值得检查;“成绩很好”不是跳过数据审计的理由。

7 案例:未登录词导致线上崩坏

某个短文本分类实验在历史英文短信上表现稳定,上线试运行后却频繁漏掉新垃圾消息。发送者使用新品牌名、缩写、夹杂符号的拼写,还混入中文。这里的“未登录词”指当前输入中出现、训练词表中没有的单位,并不是用户没有登录账号。它揭示的是训练表示对新表达覆盖不足。

例如词表学过“free”“claim”,新短信改写成“fr33”“cl@im”。固定词表的词级向量器可能忽略这些新片段,而不是自动理解它们等价于原词。若整条文本都没有命中词表,转换结果就是全零向量。逻辑回归仍可能根据截距给出一个分数,系统表面没有异常,但这个分数几乎不包含这条文本的实际信息。

先用证据定位。记录规范化后的语言分布、文本长度、空文本比例、零向量比例,以及分词后未命中词表的单位比例。未命中比例的分母应是分词器实际产出的单位数;完全没有单位的文本另计,避免除以 0。不要直接把所有原文写入普通日志,可以保存统计量,并在受控抽样中查看经过适当处理的样例。

用输入、特征和结果信号定位线上退化
用输入、特征和结果信号定位线上退化

如果零向量比例明显上升,同时新来源的召回率下降,就有理由怀疑表示覆盖与分布漂移。还要检查线上是否加载了错误词表、是否漏做规范化、是否把正文传成空字段。相同原始短信在线下和线上转换结果不同,首先是流程一致性问题;转换一致但新语料普遍失效,才更支持数据分布变化的解释。

修复可以从恢复训练与推理的相同处理规则开始,再收集有代表性的新表达,比较字符片段与原词级基线。不要在线上遇到新词就自动追加到词表:词表维度与分类器权重绑定,扩展词表后原模型并没有对应的新权重。需要重新拟合、验证并作为完整版本发布。临时把所有陌生词判成垃圾,也会严重伤害正常的新表达。

这个案例中的数字可以用来演示告警判读:假设零向量比例从 1% 升到 12%,它是需要调查的变化,不能直接证明准确率下降了多少。真实效果仍需要后续人工标签,并考虑标签到达延迟和抽样偏差。漂移监测提供排查线索,不能代替精确率、召回率的实际测量。

部署前可以给零向量、异常长度、未知语言等输入定义回退行为,例如进入人工复核或保持原处理路径。回退应对应业务风险,并单独统计触发比例。修复后既要测新来源,也要保留旧来源评估,确认改进没有以大幅增加正常短信误拦为代价。输入覆盖、模型效果和处理动作需要一起审视。

8 把文本处理契约写进 NLP 方案

文本处理契约是一组可以检查的约定:输入如何进入系统、怎样转换、输出表示什么、遇到例外怎样处理。它让数据准备者、训练者与使用者对同一条文本得到一致预期。方案不能只写“采用 NLP 识别垃圾短信”,还应写清语言范围、输入字段、长度单位、编码、允许为空与否,以及标签的业务含义。

例如“最长 500 个字符”仍有歧义:字符是 Unicode 码点、字节,还是用户看到的字形?截断发生在规范化之前还是之后?若本课实现按 Python 字符串长度限制,应明确记录该口径,并说明超长文本如何处理。训练使用完整正文、线上却只传前半段,会制造隐蔽分布差异,可能把决定性信息截掉。

契约还应写出清洗顺序和模型依赖:先做哪种 Unicode 规范化,再怎样处理空白与大小写,分词器使用什么规则,词表与 IDF 来自哪个训练版本。若训练使用词级特征,线上改成字符特征,即使输出维度碰巧一样也不兼容。模型、词表、清洗代码和阈值应作为完整单元绑定发布与回滚。

文本处理契约连接训练、推理和验收
文本处理契约连接训练、推理和验收

输出部分要区分类别、分数与动作。spam_score=0.72 的含义不能只靠字段名推测:正类是什么、分数是否经过概率校准、阈值是多少,都应有说明。相同分数可以触发提醒、人工检查或自动拦截,属于不同产品决定。调整动作阈值也会改变用户看到的错误,应经过验证并保留版本记录。

验收不只看总 F1。可按语言、文本长度、来源、是否含网址等切片比较;切片样本太少时,要标记证据不足。对正常短信误拦特别敏感的场景,应单独列出误拦数量、精确率要求和复核流程。若线上数据缺少可靠标签,应说明如何抽样复核、多久回收结果,以及怎样避免只评估被模型拦住的样本。

责任也应具体到操作:谁维护标签定义,谁批准清洗规则变化,谁监控零向量比例,谁处理申诉。公开数据可以用于教学,但不能把其中的分布默认视为本业务的分布。引入业务数据时,还要确定可使用的字段、保留期限和查看范围,避免在排查时无目的复制原始文本。

最后给每条关键约定配可观察证据。编码问题看解码失败数量,空输入看比例,表示覆盖看零向量与未命中比例,效果看带标签的切片指标,版本一致性看加载记录。这样当效果变化时,团队能沿着输入、转换、模型、阈值与动作逐层定位,而不是只围着一个总分猜测。

9 从NLP 基础走向Transformer(A27)

本课的词袋表示能够学习“哪些片段与哪个类别相关”,但对顺序、指代、上下文和跨句关系表达有限。增加相邻词组合可以补充局部信息,却会迅速扩大特征空间;同一个词在不同语境中的含义,仍很难只靠固定位置表示。由此产生一个自然问题:能否让每个位置的表示随上下文变化?

Transformer 是后续课程讨论这类问题的重要架构。A27 将从序列、位置与注意力的基本作用继续,不在这里展开多头注意力的矩阵运算、训练稳定性或大模型内部细节。现在只需要建立直觉:模型不仅要知道出现了哪些单位,还可能需要根据周围内容判断每个单位与其他位置的关系。

分词、编码与模型架构也不能混为一谈。子词切分能把某些陌生词拆成已有片段,但并不保证所有新语言、新拼写都被正确理解。Transformer 可以使用不同词元方案,词级或字符级分类器也能处理各自的序列表示。更换架构之后,仍需检查输入覆盖、标签质量和任务边界。

进入 A27 前,应能解释为什么词表只能在训练集拟合,为什么 F1 不等于全部业务价值,以及为什么零向量仍可能产生正常格式的预测。这些问题都与可靠机器学习有关,不会随着模型升级而过时。复杂模型可能提高表达能力,也可能带来更多数据、计算与评估负担,是否值得需要同一任务下的证据。

保留本课基线的价值,在于为后续比较提供参照。采用相同的冻结划分、相同的正类定义和验收动作,才能判断新模型究竟改善了哪类错误。若它只提高总体分数,却让关键来源的误拦增加,应继续分析。下一步的目标是理解更强表示如何产生,同时保留对数据和评估的约束。

放进方案里

本方案以短文本垃圾识别为目标,输入为允许使用的短信正文,输出为垃圾类别分数、类别与处理建议。教学基线采用 UCI SMS Spam Collection,正类为垃圾短信;该数据仅用于验证流程,不承担中文或当前业务场景的效果承诺。业务使用前需补充目标语言、来源与近期样本,并确认标注定义与实际处理动作一致。

数据先按固定规则规范化,隔离冲突标签,按重复模板或可用的来源群组划分。教学实验约用 60% 训练、20% 验证、20% 测试,保存样本归属与版本。TF-IDF 词表、IDF 和分类参数只在训练集拟合,验证集选择特征配置与阈值,冻结后再评估测试集;测试结果不得继续用于反复选型。

基线采用词级 TF-IDF 与逻辑回归,保存清洗规则、分词规则、词表、模型及阈值的绑定版本。输入契约明确编码、语言、空输入和超长文本的处理;零向量与不支持语言进入约定的回退路径。阈值依据误拦与漏放代价制定,未满足验收要求时保留人工复核,不用总体准确率替代上线依据。

验收同时报告精确率、召回率、F1、ROC-AUC、混淆矩阵与各类样本数,并按来源、语言和长度检查切片。成本记录训练耗时、模型大小及目标环境中的预测延迟。报告保留错误样例类型与适用范围,不将示意数据写成实测成绩,也不把公开数据结果直接外推到业务。

运行期间监控空输入、零向量、未命中词表比例、输入来源变化和版本一致性,通过受控抽样回收人工标签。发现漂移后先检查处理链路,再补充语料并重训;新版本同时评估旧来源与新来源,保留回滚能力。指定标签、模型、监控与复核责任人,记录规则变更与验收证据,保证方案能够持续维护。

10 小结:下一步Transformer(A27)

NLP 基础把文本转换成可测量的任务:先明确标签和输入边界,再选择分词与表示,使用独立数据选择方案、估计效果。词袋加线性模型提供了容易检查的起点,也暴露出词序丢失、未登录词与分布变化等限制。

自测可以围绕 3 个问题展开:测试集新词为什么不能先加进词表再报分?准确率很高时,为什么垃圾召回率仍可能很低?线上所有请求都返回合法分数,为什么仍可能发生大面积失效?回答时应分别联系数据泄漏、类别不平衡和表示覆盖。

A27 将继续讨论 Transformer 怎样利用上下文构造表示。带着本课保存的数据划分、基线与错误分类进入下一课,才能把架构变化与实际改进联系起来。

同阶段相关课

AI 答疑

默认关闭。启用后,只发送本课标题、最近阅读的屏幕内正文摘录(最多 6000 字)与本次问题。

配置自己的服务