共计 1369 个字符,预计需要花费 4 分钟才能阅读完成。
背景痛点:为什么意图识别这么难?
在对话系统中,用户常常不会按照预设的模板说话。比如同样想查天气,有人问 ” 明天会下雨吗 ”,也有人直接说 ” 要不要带伞 ”。这种表达差异导致三大典型问题:

- 意图模糊 :短文本缺乏上下文线索(如 ” 打开 ” 可能指开灯、开窗或开应用)
- 多义词歧义 :像 ” 苹果 ” 既可能是水果也可能是手机品牌
- 长尾覆盖不足 :冷门意图训练样本少(比如 ” 帮我给盆栽浇水 ” 这类小众请求)
这些情况轻则导致答非所问,重则让用户直接流失。我们曾有个客服机器人,因为把 ” 账号被锁 ” 误判为 ” 修改密码 ”,导致投诉率上升 37%。
技术方案选型:从简单到复杂
1. 正则表达式(Rule-based)
- 优点 :零训练成本,毫秒级响应
- 缺点 :维护成本高,准确率通常 <60%
- 适用场景 :固定句式(如 ” 重置密码 ”)
2. 朴素贝叶斯(Naive Bayes)
- 优点 :训练快,小样本可用
- 缺点 :无法处理词序(” 不喜欢 ” 和 ” 欢喜不 ” 会被等同看待)
- 典型准确率 :70%~75%
3. SVM(支持向量机)
- 优点 :对高维特征适应好
- 缺点 :依赖人工特征工程
- 实测数据 :加入 n -gram 后准确率可达 82%
4. BERT(深度学习)
- 优点 :自动捕捉上下文,我们的测试集上达到 94%
- 缺点 :需要 GPU 资源,预测耗时约 150ms
- 选择建议 :当准确率要求 >90% 时必选
基于 BERT 的实现细节
数据预处理
- 清洗特殊字符 :
- 保留有意义符号(如 ”?” 可能体现疑问意图)
- 移除乱码和非常规 Unicode
def clean_text(text):
# 保留中英文、数字和常见标点
pattern = r'[^\u4e00-\u9fa5a-zA-Z0-9.,!?]'
return re.sub(pattern, '', text)
- 停用词处理 :
- 不要无差别去除(比如 ” 不 ” 是情感关键)
- 建议使用领域定制列表
标签体系设计
采用两级分类架构:
– 一级意图:大方向(如 ” 购物 ”)
– 二级意图:具体动作(如 ” 比价 ”、” 退货 ”)
常见错误 :把相似意图合并(如 ” 订机票 ” 和 ” 订酒店 ” 应该分开)
模型训练关键参数
from transformers import BertForSequenceClassification
model = BertForSequenceClassification.from_pretrained(
'bert-base-chinese',
num_labels=len(label_map) # 类别数
)
# 学习率设置
optimizer = AdamW(model.parameters(),
lr=2e-5, # 太小收敛慢,太大易震荡
eps=1e-8)
# 早停策略
early_stop = EarlyStopping(
monitor='val_f1',
patience=3,
mode='max' # 关注 F1 提升
)
生产环境优化建议
低置信度处理
当模型最高概率 <0.6 时:
1. 触发澄清话术(” 您是想问 X 还是 Y?”)
2. 记录日志供后续模型迭代
在线学习策略
- 新数据积累到 1000 条时触发增量训练
- 采用 A / B 测试对比新旧模型
延伸思考
- 小样本困境 :当只有 20 条训练数据时,是用数据增强还是 Few-shot Learning?
- 多语言场景 :直接混合训练中文和英文数据,还是分别建模后合并结果?
实际项目中,我们发现结合规则兜底 +BERT 主力的混合架构,能平衡效果和成本。曾经有个电商场景,仅用 3 周就实现了意图识别准确率从 68% 到 89% 的提升。
正文完
