Python 意图识别的轻量分类模型

7次阅读

sklearn50行内可实现轻量意图分类器:先清洗(繁转简、全角转半角、去url/空格),tfidfvectorizer设ngram_range=(1,2)和max_features=5000,stratifiedkfold分层切分,选用logisticregression因其小样本高维稀疏场景更鲁棒、可解释性强。

Python 意图识别的轻量分类模型

sklearn 训练一个够用的意图分类器,50 行内搞定

不需要 bert、不用 GPU,纯 CPU 上跑得动,准确率对简单业务场景(比如客服问答前 10 类意图)够用。关键不是模型多深,而是特征怎么提、数据怎么喂。

常见错误现象:predict 结果全是同一类;测试集准确率虚高但线上一用就崩;TfidfVectorizer 把“登录”和“登陆”当两个词分开了。

  • 先做基础清洗:统一繁体转简体、全角转半角、去掉 URL 和多余空格,别跳过这步——中文里标点、空格、异体字是分类最大干扰源
  • TfidfVectorizer 必须设 ngram_range=(1, 2),单字太稀疏,“忘记密码”这种短语必须靠二元组合才能捕获
  • 别用默认的 max_features=10000,小样本下建议直接设 max_features=5000,否则低频词噪声压不住
  • 训练前务必用 StratifiedKFold 分层切分,尤其当某类样本只有 20 条时,随机切容易某折里完全没它

为什么 LogisticRegressionSVC 更适合轻量意图识别

不是因为“线性模型简单”,而是它在小样本、高维稀疏文本上更鲁棒,预测快、可解释性强——你能直接看 coef_ 知道“重置”这个词对“密码找回”类的权重有多高。

使用场景:日均请求量

立即学习Python免费学习笔记(深入)”;

  • SVCkernel='rbf' 下对超参极其敏感,Cgamma 差一个数量级,F1 就掉 15 点
  • LogisticRegression 只需调 C(建议从 0.110 扫),配合 class_weight='balanced' 能稳住长尾类
  • 导出模型时用 joblib 而不是 pickle,前者对 scipy.sparse 矩阵序列化更省空间、加载更快

predict_proba 返回值不准?检查这三处

不是模型本身问题,90% 出在 pipeline 链路断裂:向量化器没保存好、类别顺序不一致、或者用了 decision_function 却当成概率用。

常见错误现象:predict_proba 输出里最大概率才 0.3;同一条文本两次运行结果不同;classes_ 数组顺序和你存的 label 映射表对不上。

  • 训练完立刻保存 vectorizer.get_feature_names_out()clf.classes_,别依赖模型内部属性动态读取
  • 调用 predict_proba 前,确认输入文本走的是和训练时**完全相同的预处理函数**(比如是否去停用词、是否小写化)
  • 如果用 CalibratedClassifierCV 包一层 LogisticRegression,能提升概率校准度,但推理慢 20%,只在需要可信置信度时加

上线前必测的边界 case

真实用户不会按你的训练集分布说话。模型在“正常句式”上表现好,不代表能扛住错别字、中英混输、甚至空格塞满的恶意输入。

性能影响:这些 case 不一定报错,但可能让 TfidfVectorizer.transform 返回全零向量,导致模型胡猜。

  • 输“登 录”,中间多个空格 → 预处理要 re.sub(r's+', ' ', text).strip()
  • 输“wo yao zhong zhi mi ma”,拼音输入 → 单独加一层拼音转汉字(可用 pypinyin),或训练时混入拼音样本
  • 输“?????”,纯标点 → 向量化前加判断:if not re.search(r'[u4e00-u9fffw]', text): return 'unknown'
  • 空字符串或只含空白符 → vectorizer.transform 会返回 shape=(1, N) 全零矩阵,必须前置拦截

最容易被忽略的是:训练时用了 jieba 分词,但线上没同步更新词典,新词(比如产品名“飞书会议”)被切成无意义单字,特征就废了。

text=ZqhQzanResources