未解析指代检测器 (Has Unsolved Reference Detector)
基于规则路由 + BERT 语义分类的两层级联系统,用于检测自然语言陈述中是否存在未解析的指代表达。
项目简介
本项目判断给定陈述中是否包含未解析的指代——即尚未绑定到具体实体的代词、指示词、不定表达或省略结构。任务定义为二分类:
| 标签 | 含义 | 示例 |
|---|---|---|
false |
陈述中的对象已解析为具体实体或足够明确的最小描述 | "小李点了一杯美式咖啡。" |
true |
仍存在未解析指代、未绑定槽位或省略表达 | "用户和那位朋友约了周末见面。" |
系统架构
flowchart TD
A["输入: statement_text"] --> B{"第一层\n规则路由\n8 个特征检测"}
B -->|"所有特征 = 0"| C["输出: false\n高置信快速通道"]
B -->|"任一特征 = 1"| D["第二层\nBERT 二分类模型"]
D --> E{"P(true) >= 阈值?"}
E -->|"是"| F["输出: true"]
E -->|"否"| G["输出: false"]
style B fill:#4CAF50,color:#fff
style D fill:#2196F3,color:#fff
style C fill:#9E9E9E,color:#fff
style F fill:#FF9800,color:#fff
style G fill:#9E9E9E,color:#fff
第一层:规则路由
8 个规则特征扫描陈述中的指代信号。如果全部为 0,样本直接判定为 false,无需调用模型。该快速通道可处理约 79% 的真实流量,准确率为 100%。
| 特征 | 检测内容 | 示例 |
|---|---|---|
has_pronoun |
中英文人称、物主和泛指代词 | 他、你们、对方、it、their |
has_demonstrative |
中英文指示表达 | 这个、那位、these、those |
has_location |
依赖上下文的位置表达 | 这里、那边、此处 |
has_question |
可能代表未绑定槽位的疑问词 | 谁、哪个、哪里、多少 |
has_suspect |
带显式指代标记的复合表达 | 前者、另一方、某人、哪家 |
has_indefinite |
不定对象、泛称和省略表达 | 某个、一位老师、想了解一下 |
has_my_relation |
"我 + 关系角色"模式 | 我朋友、我女儿、我同事 |
has_en_ref |
英文关系/疑问代词 | who、which、whatever |
第二层:BERT 分类器
被规则层路由的样本进入微调后的 bert-base-chinese 模型。输入构造如下:
指代片段:[规则命中位置左右各 4 字的片段,多个用 | 分隔]
目标内容:[target_content,仅在 context 未包含它时附加]
上下文:[组装后的 context]
模型输出 P(true),通过验证集优化的阈值(0.41)决定最终标签。
性能指标
在独立测试集(1008 条样本,941 false / 67 true)上评估,checkpoint 和阈值均仅从验证集选择。
整体指标
| 指标 | 数值 |
|---|---|
| 准确率 | 97.62% |
| 宏平均精确率 | 0.9183 |
| 宏平均召回率 | 0.8833 |
| 宏平均 F1 | 0.8999 |
分类别指标
| 类别 | 精确率 | 召回率 | F1 | 样本数 |
|---|---|---|---|---|
| false | 0.9842 | 0.9904 | 0.9873 | 941 |
| true | 0.8525 | 0.7761 | 0.8125 | 67 |
分层统计
pie title 测试集分布 (1008 条样本)
"规则层 (79.4%, 准确率 100%)" : 800
"模型层 (20.6%, 准确率 88.46%)" : 208
| 层级 | 样本数 | 占比 | 准确率 |
|---|---|---|---|
| 规则层 | 800 | 79.4% | 100.00% |
| 模型层 | 208 | 20.6% | 88.46% |
混淆矩阵(模型层,208 条样本)
| 真实标签 \ 预测标签 | false | true | 合计 |
|---|---|---|---|
| false | 132 (TN) | 9 (FP) | 141 |
| true | 15 (FN) | 52 (TP) | 67 |
快速开始
环境要求
torch >= 2.0
transformers >= 4.30
命令行推理
python main.py --statement "用户和那位朋友约了周末见面"
带可选上下文:
python main.py ^
--statement "我朋友帮我下单" ^
--target_content "朋友" ^
--context "用户想给某人点外卖"
Python API 调用
from main import load_vocab, load_model, RuleLayer, predict
vocab = load_vocab()
rule = RuleLayer(vocab)
model, tokenizer, device = load_model()
result = predict(
statement="用户和那位朋友约了周末见面",
target_content="朋友",
context="用户想约人见面",
model=model,
tokenizer=tokenizer,
rule=rule,
device=device,
)
print(result["prediction"]) # "true"
print(result["confidence"]) # 0.87
print(result["source"]) # "model" 或 "rule"
项目结构
has_unsolved_reference2/
├── main.py # 推理脚本(两层管线)
├── README.md
├── model/
│ ├── config.json # BERT 模型配置
│ ├── model.safetensors # 微调后的模型权重
│ ├── tokenizer.json # 分词器词表
│ └── tokenizer_config.json
└── data/
├── ref_vocab.json # 指代关键词词表
└── sample.jsonl # 示例样本(5 条)
关键词词表
词表文件 data/ref_vocab.json 包含 10 个类别共 178 个关键词:
| 类别 | 数量 | 示例 |
|---|---|---|
| 中文代词 | 26 | 他、她、对方、你们... |
| 英文代词 | 41 | he、she、they、someone... |
| 中文指示词 | 14 | 这个、那个、这种... |
| 英文指示词 | 4 | this、that、these、those |
| 位置词 | 8 | 这里、那里、此处... |
| 疑问词 | 13 | 谁、什么、哪个、怎么... |
| 不定指代 | 15 | 某个、该用户、另一位... |
| 我+关系词 | 34 | 我朋友、我女儿、我同事... |
| 英文关系代词 | 7 | who、which、whatever... |
| 疑似复合词 | 16 | 前者、另一方、某某... |
关键词与正则模式结合使用,可覆盖未见过的变体。
已知限制
true类样本较少,验证集仅有 18 条,阈值估计仍存在方差- 当前 true 类召回率为 77.61%,漏报仍是主要问题
- 数据中存在重复模板句,甚至同一句式对应不同标签,可能影响模型学习
- 新增关键词应遵循"显式指代标记 + 结构模式 + 完整词排除"原则,避免误报