资讯详情

资讯详情

从零构建中文短文本情绪与意图分析服务:规则词典与FastAPI实践

做客服对话分析、用户反馈总结或者社交媒体情绪监控时业务方最常问的一句话是用户这句话到底在想什么。为了更清楚地回答这个问题我通常会先搭建一个轻量级的中文短文本情绪与意图分析服务项目代号就叫“sakura在想什么呢”。名字来自那句日常口语——看起来是在问一个角色在想什么实际上是在做一次文本语义结构拆解判断一句话表达了什么情绪属于什么意图。本文会沿着这条主线从规则词典开始实现一个最小可运行的分析器再用 FastAPI 把它包装成 HTTP 接口最后给出调优、排错和生产落地建议。适合刚接触 NLP 工程化、想从零做一个可调用文本分析服务的读者。整个项目不需要 GPU不需要标注数据只要 Python 环境和几千行以内的代码就能跑起来。1. 把“在想什么”翻译成可计算的工程问题在工程上回答“在想什么”不是要去揣测用户心理而是把一段文本映射到有限的结构化标签。以客服场景为例一句“网络太差了一直崩溃”和一句“这个功能怎么用啊”业务方需要知道的信息完全不同。前一句是用户的消极情绪在表达抱怨后一句是用户的中性情绪在寻求帮助。如果系统能把这两种情况自动分开后续就可以做工单分级、质量分析和智能回复。所以这里要拆解两类信号“网络太差了一直崩溃。” - 情绪negative意图complaint “这个功能怎么用啊” - 情绪neutral意图inquiry一个是情绪倾向一个是意图类型二者组合起来才是这句话的完整结构。1.1 一句话里的两类信号情绪倾向和意图类型情绪倾向Sentiment描述的是说话人对主题的情感态度。常见粒度有正向、负向、中性也可以细分到惊讶、愤怒、失望等。情绪分析在文本挖掘里属于句子级分类任务输入是文本输出是标签和置信度。意图识别Intent Recognition描述的是这句话想达到什么目的。用户说“怎么登录”意图是询问用户说“登录按钮不见了”意图是问题反馈用户说“建议增加记住密码”意图是建议。意图识别通常是一个多分类问题类别集合需要根据业务场景预先定义。这两个任务经常一起出现因为它们在产品上强关联情绪决定处理优先级意图决定处理方式。把两者同时输出比单独做任何一个都更有价值。1.2 为什么第一版选规则词典而不是深度学习模型第一版用规则和词典核心原因有三个不需要标注数据。深度学习模型需要有标签的训练集冷启动阶段往往没有这些数据。可解释、可调试。规则命中哪个关键词、触发哪个情绪词逻辑是透明的出问题可以直接改规则。速度快、成本低。词典匹配和字符串检索都是毫秒级不需要加载模型权重也不依赖 GPU。等系统运行一段时间积累了足够多的 bad case 之后再考虑用模型替换规则效果会更好。这也符合“先上线、再迭代”的工程节奏。直接在第一版就引入大模型或微调模型常常会因为数据质量、延迟和成本问题拖慢项目进度。1.3 项目输入、输出与边界“sakura在想什么呢”作为最小项目处理范围这样定义输入单条中文短文本长度不超过 500 字。输出情绪标签、情绪分数、情绪置信度、命中情绪词、意图标签、意图置信度、命中关键词。不处理多轮对话不做指代消解不识别专有名词实体。这个边界是刻意的。先把单句分析做成稳定接口后续再扩展上下文和实体抽取。2. 环境准备Python依赖、目录结构与规则文件2.1 Python环境与依赖版本推荐使用 Python 3.9 及以上版本。依赖方面核心只需要三个库jieba 负责中文分词FastAPI 负责 HTTP 服务uvicorn 负责启动服务。依赖版本建议作用Python3.9运行环境jieba0.42.x中文分词fastapi0.110.xHTTP 服务框架uvicorn0.29.xASGI 服务器安装命令pip install jieba fastapi uvicorn如果是为了稳定交付建议安装后执行pip freeze requirements.txt固定住实际环境里的版本。下面这份requirements.txt可以作为初始参考实际项目以自己的解析结果为准jieba0.42.1 fastapi0.110.0 uvicorn0.29.02.2 项目目录结构项目结构不需要复杂但要把“分析逻辑”和“HTTP服务”分开方便后续测试和扩展sakura-thinking/ ├── main.py ├── analyzer.py ├── data/ │ ├── emotion_dict.json │ └── intention_rules.json ├── requirements.txt └── README.mdanalyzer.py只负责文本分析不依赖 FastAPImain.py负责接收 HTTP 请求调用分析器并返回结果。规则和词典放在data目录下因为它们是外部配置不应该硬编码在代码里。2.3 用JSON准备情感词典和意图规则情感词典包含三类信息正向词、负向词、程度副词、否定词。注意这里的情感词要尽量选择能被 jieba 切分出来的词例如“差”“崩溃”可以“太差”这种短语通常会被切分成“太”和“差”所以建议放在意图规则里用子串匹配。创建data/emotion_dict.json{ positive: [开心, 喜欢, 满意, 期待, 好用, 感谢, 点赞], negative: [差, 糟糕, 生气, 难过, 失望, 垃圾, 崩溃, 讨厌, 难用, 故障], degree: { 非常: 1.5, 特别: 1.5, 太: 1.3, 很: 1.2, 有点: 0.8, 稍微: 0.6 }, negation: [不, 没, 没有, 别, 不太, 无法] }创建data/intention_rules.json{ praise: { priority: 10, keywords: [满意, 好用, 喜欢, 点赞, 太棒了] }, complaint: { priority: 10, keywords: [太差, 垃圾, 慢死了, 故障, 崩溃, 难用, 不行] }, thanks: { priority: 8, keywords: [感谢, 谢谢, 辛苦了] }, suggestion: { priority: 6, keywords: [建议, 希望, 能不能, 可不可以, 如果] }, inquiry: { priority: 5, keywords: [怎么, 为什么, 如何, 可以吗, 哪里, 是否] } }为什么要用 JSON 而不是直接写在 Python 代码里因为规则会频繁变化。业务方觉得“易仕”这个词属于投诉时只需要改 JSON 让运营人员维护即可不需要改动代码。priority字段用来处理多意图冲突例如“希望你说一下这个功能怎么用”同时命中了suggestion和inquiry此时按优先级取高者会更合理。3. 核心分析器实现清洗、分词、情绪打分与意图匹配3.1 文本清洗和分词把一句话变成可匹配的最小单元文本清洗要解决的问题是“如何不被标点和符号干扰”。中文文本里常见的逗号、句号、感叹号、问号以及英文标点都需要在匹配前去掉否则“怎么用”里的问号会影响规则判断。分词使用 jieba。例如import jieba print(list(jieba.cut(网络太差了一直崩溃)))输出类似[网络, 太, 差, 了, ,, 一直, 崩溃]。分完词之后情绪分析就可以对每个词做词典匹配意图分析则可以直接用“原文子串匹配”因为意图关键词往往是短语例如“慢死了”“太差了”子串匹配更稳定。3.2 情绪打分情感词、程度副词和否定词怎么配合情绪打分的核心规则是这样遇到正向词加 1 分。遇到负向词减 1 分。如果情感词前一个窗口内出现程度副词则把分数乘以对应权重。如果出现否定词则把分数符号反转也就是“不开心”应该识别为负面。最终把总分限制在[-3, 3]之间避免极端值影响展示。创建analyzer.pyimport json import re from typing import List import jieba class SakuraAnalyzer: def __init__(self, emotion_dict_path: str, intention_rules_path: str): self.emotion_dict self._load_json(emotion_dict_path) self.intention_rules self._load_json(intention_rules_path) self.positive_words: set set(self.emotion_dict.get(positive, [])) self.negative_words: set set(self.emotion_dict.get(negative, [])) self.degree_words: dict self.emotion_dict.get(degree, {}) self.negation_words: set set(self.emotion_dict.get(negation, [])) self.punctuation_regex re.compile(r[\s。!?,.;、~\-—]) # 预热分词器避免首次请求耗时过高 jieba.lcut(初始化分词器) staticmethod def _load_json(path: str): with open(path, r, encodingutf-8) as f: return json.load(f) def clean_text(self, text: str) - str: text self.punctuation_regex.sub(, text) return text.strip() def segment(self, text: str) - List[str]: return list(jieba.cut(text)) def _local_weight(self, words: List[str], index: int, window: int 2): weight 1.0 negated False start max(0, index - window) for j in range(index - 1, start - 1, -1): w words[j] if w in self.degree_words: weight * self.degree_words[w] elif w in self.negation_words: negated not negated return weight, negated def analyze_emotion(self, text: str): cleaned self.clean_text(text) words self.segment(cleaned) score 0.0 hit_words [] for i, word in enumerate(words): if word in self.positive_words: weight, negated self._local_weight(words, i) delta weight if not negated else -weight score delta hit_words.append(word) elif word in self.negative_words: weight, negated self._local_weight(words, i) delta -weight if not negated else weight score delta hit_words.append(word) score max(-3.0, min(3.0, score)) if score 0.2: emotion positive elif score -0.2: emotion negative else: emotion neutral confidence min(0.95, 0.5 abs(score) * 0.15) return { emotion: emotion, emotion_score: round(score, 4), emotion_confidence: round(confidence, 4), emotion_hit_words: hit_words, } def analyze_intention(self, text: str): cleaned self.clean_text(text) results [] for intent_name, config in self.intention_rules.items(): hit [kw for kw in config[keywords] if kw in cleaned] if hit: results.append({ intention: intent_name, hit_count: len(hit), priority: config.get(priority, 0), keywords: hit, }) if not results: return { intention: other, confidence: 0.1, matched_keywords: [], } results.sort(keylambda x: (-x[priority], -x[hit_count])) top results[0] confidence min(0.9, 0.5 0.1 * top[hit_count]) return { intention: top[intention], confidence: round(confidence, 4), matched_keywords: top[keywords], } def analyze(self, text: str): emotion_result self.analyze_emotion(text) intention_result self.analyze_intention(text) return { input_text: text, **emotion_result, **intention_result, }这里有两个关键方法要重点解释。_local_weight方法负责处理否定词和程度副词。它从当前情感词的位置往前最多看两个词倒序遍历遇到程度副词就累乘权重遇到否定词就翻转一次符号。这种窗口机制适合短句能覆盖大多数“不太好”“非常差”这类结构但不适合处理很长的多重否定句。analyze_emotion里的置信度公式是简单启发式情绪越极端置信度越高。0.5 abs(score) * 0.15表示基础置信度 0.5每偏离中性 1 分增加 0.15上限 0.95。3.3 意图识别关键词命中、优先级和置信度意图识别的实现比情绪识别更简单本质是对原文做关键词子串匹配。因为“太差”这种短语在分词后会被拆开而子串匹配可以完整命中。多个意图同时命中时按priority降序、命中次数降序排序。例如“这个功能太差了建议优化”同时命中complaint的“太差”和suggestion的“建议”因为complaint的 priority 是 10suggestion是 6最终输出complaint。置信度公式是0.5 0.1 * hit_count上限 0.9。这样设计是为了让“单一关键词命中”不至于给出过高的置信度至少留出优化空间。3.4 把两类结果组装成统一返回结构返回结构里同时包含原始文本、情绪信息、意图信息。这样一个前端或下游服务只需要调用一次接口就能拿到完整分析结果。字段设计如下字段类型含义input_textstring原始输入文本emotionstringpositive / negative / neutralemotion_scorefloat情绪总分范围约 -3 到 3emotion_confidencefloat情绪置信度emotion_hit_wordsarray命中的情绪词intentionstring意图标签confidencefloat意图置信度matched_keywordsarray命中的意图关键词这种结构的好处是调试时可以直接看emotion_hit_words和matched_keywords知道结果是由哪些词触发的。4. 用FastAPI暴露分析接口单条与批量的服务结构4.1 搭建FastAPI应用和请求校验模型main.py里做三件事加载分析器、定义请求和响应模型、暴露接口。为了让服务不依赖当前工作目录这里用Path(__file__).resolve().parent构造词典路径。import logging import time from pathlib import Path from typing import List from fastapi import FastAPI, HTTPException from pydantic import BaseModel, Field from analyzer import SakuraAnalyzer logging.basicConfig( levellogging.INFO, format%(asctime)s %(levelname)s %(name)s %(message)s, ) logger logging.getLogger(sakura) BASE_DIR Path(__file__).resolve().parent analyzer SakuraAnalyzer( str(BASE_DIR / data / emotion_dict.json), str(BASE_DIR / data / intention_rules.json), ) app FastAPI(titlesakura在想什么呢, version0.1.0) class AnalyzeRequest(BaseModel): text: str Field(..., min_length1, max_length500, description待分析文本) class AnalyzeResponse(BaseModel): input_text: str emotion: str emotion_score: float emotion_confidence: float emotion_hit_words: List[str] intention: str confidence: float matched_keywords: List[str] class BatchAnalyzeRequest(BaseModel): texts: List[str]初始化分析器放在模块顶层是为了让服务启动时只加载一次规则和分词器而不是每个请求都重复加载。jieba.lcut(初始化分词器)这行预热代码能明显减少第一次请求的耗时。4.2 单条分析接口单条接口接收 JSON 请求体返回AnalyzeResponse。为了观察线上效果在接口里记录耗时和输入文本。app.post(/analyze, response_modelAnalyzeResponse) def analyze_single(req: AnalyzeRequest): start time.time() result analyzer.analyze(req.text) cost_ms (time.time() - start) * 1000 logger.info(analyze text%s cost%.2fms, req.text, cost_ms) return result这里不手动做异常捕获因为通用异常会交给 FastAPI 返回 500参数错误会返回 422。生产环境再加入业务告警即可。4.3 批量分析接口和请求日志批量接口用于分析多条文本比如一次性处理一批问卷反馈。批量条数限制在 100 条以内避免单次请求占用过多 CPU。app.post(/analyze/batch) def analyze_batch(req: BatchAnalyzeRequest): if not req.texts: raise HTTPException(status_code400, detailtexts 不能为空) if len(req.texts) 100: raise HTTPException(status_code400, detail单次最多分析 100 条) results [] for text in req.texts: if not text.strip(): raise HTTPException(status_code400, detail批量文本中不能包含空字符串) results.append(analyzer.analyze(text)) logger.info(batch analyze count%d cost%.2fms, len(req.texts), time.time() * 1000) return {total: len(results), results: results}批量接口的返回值不直接绑定AnalyzeResponse因为里面需要包一层total字段。这样调用方可以根据total判断是否丢数据。5. 运行验证启动服务、curl调用与bad case复盘5.1 安装依赖并启动本地服务在项目根目录执行cd sakura-thinking pip install -r requirements.txt uvicorn main:app --reload --port 8000正常情况下可以看到类似输出INFO: Uvicorn running on http://127.0.0.1:8000--reload参数适合开发环境改代码后服务会自动重启。生产环境不要加--reload。5.2 用curl验证三类典型文本打开一个新终端执行下面的请求。第一类中性询问curl -s -X POST http://127.0.0.1:8000/analyze \ -H Content-Type: application/json \ -d {text: 这个功能怎么用啊}预期响应{ input_text: 这个功能怎么用啊, emotion: neutral, emotion_score: 0.0, emotion_confidence: 0.5, emotion_hit_words: [], intention: inquiry, confidence: 0.6, matched_keywords: [怎么] }第二类负面抱怨curl -s -X POST http://127.0.0.1:8000/analyze \ -H Content-Type: application/json \ -d {text: 网络太差了一直崩溃}预期响应{ input_text: 网络太差了一直崩溃, emotion: negative, emotion_score: -2.3, emotion_confidence: 0.845, emotion_hit_words: [差, 崩溃], intention: complaint, confidence: 0.6, matched_keywords: [崩溃] }注意这里情绪命中词是“差”和“崩溃”而不是“太差”因为 jieba 把“太差了”切成了“太”“差”“了”。意图识别用子串匹配所以能命中“崩溃”。“太差”如果出现在文本中也会被意图规则捕获。第三类正向表扬curl -s -X POST http://127.0.0.1:8000/analyze \ -H Content-Type: application/json \ -d {text: 你们这个工具很好用我非常满意}预期响应{ input_text: 你们这个工具很好用我非常满意, emotion: positive, emotion_score: 2.7, emotion_confidence: 0.905, emotion_hit_words: [好用, 满意], intention: praise, confidence: 0.7, matched_keywords: [好用, 满意] }“好用”前面有“很”程度权重 1.2“满意”前面有“非常”程度权重 1.5所以总分为 2.7。这说明程度副词机制生效了。5.3 从bad case反推规则缺陷规则系统一定会遇到 bad case关键是能快速定位原因。举个例子如果输入“这个方案不是不行”jieba 切分可能得到“这个/方案/不是/不行”。意图规则中“不行”属于 complaint所以会输出“抱怨”。但这句话的真实语义是“这个方案是可以的”。出现这种情况有两个原因。第一意图规则没有处理否定词第二业务中没有为“否定负面词”的双重否定场景定义规则。解决方法是把这类句式加入正则例外或者在业务对接层面接受这个误判率等数据量大了再交给模型处理。排查 bad case 时不要只盯着最终标签要看中间结果emotion_hit_words命中了什么matched_keywords命中了什么。这两个字段就是整个系统的可解释性。6. 调优词典粒度、否定词窗口、规则优先级与置信度6.1 情感词典的粒度要与分词结果对齐“太差”在情感词典里是负面词但 jieba 分词成“太”和“差”所以“太差”作为词典项几乎不会被命中。这解释了为什么情感词典里要放“差”而不是只放“太差”。一个实用的调优流程是收集一批代表业务场景的真实句子。执行list(jieba.cut(sentence))把分词结果打印出来。观察哪些词反复出现且明显有情绪倾向把它们加入词典。观察多字短语和分词的差异用短语匹配补充。这样比凭感觉堆词典词更高效。6.2 否定词和程度副词的上下文窗口_local_weight的窗口默认是 2也就是只看情感词前面的两个词。这个值不是越大越好。窗口太大会导致远距离否定词误伤例如“我今天早上没有吃饭但是很开心”中的“没有”离“开心”太远不应该影响情绪。窗口太小的缺点是无法处理“不是很满意”这种连续结构因为“很”和“不”都在窗口内窗口至少要为 2。建议先保留window2然后结合自己的语料统计。如果发现三重否定或长距离否定经常出现就需要换思路先做否定范围识别再计算情绪分。6.3 意图关键词需要避免互相覆盖当前规则中suggestion包含“如果”inquiry包含“怎么”。句子“如果不知道怎么操作你会怎么处理”会同时命中多个意图。虽然priority可以排序但如果业务上希望这类句子归为“询问”就要调整关键词或优先级。以下是几个常见冲突和调整建议冲突场景当前配置可能误判调整方向“能不能”同时是询问还是建议suggestion 命中可能忽略 inquiry优先保留 suggestion或根据上下文切换“怎么”在提问中也可能出现在抱怨inquiry 优先级低抱怨被判为询问观察数据分布后调 priority“不行”可能是否定反馈complaint 命中双重否定误判引入否定词前置例外规则“建议”在商务文本中可能是名词suggestion 命中误判维护领域停用词或白名单调优的核心不是设计一套万能规则而是建立 bad case 集每次改规则都跑一遍回归确保不会修一个新问题拆掉一个旧功能。6.4 阈值与置信度的调节方式当前情绪判定阈值是 0.2也就是说分数大于 0.2 判为正小于 -0.2 判为负之间判为中性。这个值可以调调大阈值会有更多句子被判为中性减少误判但会漏掉一些弱情绪表达。调小阈值能捕捉更多弱情绪但中性噪声会变多。置信度公式同样可以调整。如果业务对“高置信度”有更严格的要求可以把公式改成0.5 abs(score) * 0.2上限保持不变更合理的方式是准备一小批标注样本统计分数和真实标签的关系拟合一个更合适的映射函数。7. 常见问题与排查从分词不一致到请求报错7.1 先按这个顺序排查能省一半时间遇到问题不要直接怀疑代码按顺序检查输入是否正确请求体字段名、Content-Type、中文字符编码。文件路径是否正确启动命令所在目录、JSON 文件是否存在。词典和规则文件是否加载打印len(analyzer.positive_words)等字段。分词结果是否符合预期把jieba.lcut的结果打印出来。匹配逻辑是否正确确认是子串匹配还是分词匹配。服务是否加载了最新规则--reload是否生效必要时手动重启。端口和进程是否正常8000 是否被占用。日志里有哪条明确异常。这个顺序的核心逻辑是先排除输入问题和环境问题再排查逻辑问题。7.2 高频问题速查表问题现象可能原因检查方式处理建议所有文本都返回中性情绪情感词典没加载成功或情感词与分词不一致打印positive_words、negative_words长度打印分词结果检查 JSON 路径和 UTF-8 编码扩充与分词对齐的词“太差了”识别为抱怨但情绪为 neutral“太差”没有被分词命中可能只命中了“差”但词典缺少“差”打印emotion_hit_words在负向词典中加入“差”确认程度副词“太”生效多字关键词始终不命中词典里的词是 jieba 切不开的长词打印jieba.lcut结果改用子串匹配或把短语放入意图规则批量接口返回 400texts 为空或包含空字符串检查请求体增加字段校验前端过滤空行接口返回 422字段名写错或 JSON 格式不对查看 FastAPI 返回的错误详情对照AnalyzeRequest字段名修正端口被占用上一次服务未退出lsof -i:8000或 netstat -anofindstr 8000首次请求特别慢jieba 首次加载词典耗时较高看日志时间戳初始化时执行一次“预热”切分7.3 规则类问题如何定位打印中间结果如果结果不符合预期最直接的方法是在接口外写一段临时脚本直接调用SakuraAnalyzer的中间方法from analyzer import SakuraAnalyzer analyzer SakuraAnalyzer( data/emotion_dict.json, data/intention_rules.json, ) text 这个方案不是不行 print(clean:, analyzer.clean_text(text)) print(words:, analyzer.segment(text)) print(emotion:, analyzer.analyze_emotion(text)) print(intention:, analyzer.analyze_intention(text))这样能一次性看到清洗后文本、分词结果、情绪命中词和意图命中词规则缺陷会变得非常直观。相比直接调用 HTTP 接口这种方式更适合调试。8. 从学习项目到生产模型化、监控与交付清单8.1 学习环境能跑通生产环境还需要补什么学习环境只要服务能启动、接口能返回结果就行。生产环境还需要补齐下面这些能力配置外置化。词典路径、规则路径、服务端口、日志级别不能硬编码要用环境变量或配置文件控制。日志结构化。不要只打印一行文本建议输出 JSON 日志包含text_hash、cost_ms、emotion、intention等字段。结果监控。统计每类情绪和意图的数量占比、平均耗时、batch 大小用指标暴露给监控系统。规则版本管理。JSON 规则文件纳入 Git版本号要随着规则更新而递增方便回滚。高频词缓存。如果同一个文本会被重复分析可以在 Redis 或本地内存里做一层缓存减少重复计算。异常兜底。不要让分析器抛异常直接击穿接口可以记录日志后返回一个默认的other结果。8.2 扩展方向槽位抽取、多轮上下文与模型化“sakura在想什么呢”目前只能输出情绪和意图。实际产品里往往还需要更多信息。槽位抽取是第一个扩展方向。例如用户问“导出功能在哪里”意图是询问但“导出功能”是用户要问的对象。可以用正则或序列标注模型把关键实体抽取出来直接跳到对应文档或操作入口。多轮上下文是第二个方向。用户在前一轮问了“导出功能怎么用”下一轮说“那删除功能呢”这里的“那删除功能呢”只有结合上文才能判断意图。这时候需要为每个会话维护一个上下文状态。模型化是第三个方向。词典规则在冷启动阶段好使但泛化能力有限。当积累了几千条带标签数据后可以用 BERT 类模型做文本分类输出语情绪和意图。同时保留规则结果作为兜底当模型置信度低时回退到规则。无论是规则还是模型输出结构都不要变。这样下游系统不用关心上游是怎么算出来的只需要消费统一的 JSON 结构。8.3 可复用的交付检查清单把这个项目从本地脚本升级成可交付服务前可以按下面这份清单做检查[ ]requirements.txt已固定实际安装版本[ ] 数据目录放在项目内部使用基于Path(__file__)的绝对路径[ ] 情感词典是 UTF-8 编码能覆盖 positive / negative / neutral 三类验证样本[ ] 意图规则覆盖 praise / complaint / thanks / suggestion / inquiry 五类验证样本[ ] 单条接口和批量接口都做过 curl 验证[ ] 至少准备了 10 条 bad case 作为回归测试集[ ] 请求日志记录了输入文本、耗时和结果且不包含用户敏感信息[ ] 服务启动无 warning首次请求耗时在可接受范围[ ] 配置文件没有硬编码绝对路径和密钥[ ] README 写清楚了启动命令和数据目录结构如果后续团队已经有标注数据和 GPU 资源可以把规则结果作为 baseline再用 ERNIE 或 BERT 模型做意图分类。这样既保留了可解释的兜底逻辑又能用模型提高泛化能力。当前这个项目的最小闭环就是先把情绪和意图两类信号输出稳定至于“sakura在想什么”这个问题能回答到什么程度取决于词典覆盖率、规则质量和后续模型迭代。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →