ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于知识图谱的《平凡的世界》智能问答系统实现

基于知识图谱的《平凡的世界》智能问答系统实现

1. 项目背景与核心价值

《平凡的世界》作为茅盾文学奖获奖作品,其复杂的人物关系和时代背景构成了一个天然的语义网络。这个毕设项目通过构建知识图谱实现智能问答,本质上是在解决文学作品的结构化解析难题。我在实际开发中发现,传统文学研究依赖人工标注,而知识图谱能自动建立人物、地点、事件的关联关系,这对长篇小说的数字化研究具有突破意义。

系统采用Flask+Neo4j技术栈,实现了从文本抽取到问答服务的完整链路。特别在实体关系抽取环节,结合规则匹配与BiLSTM-CRF模型,使F1值达到87.6%,远超单纯基于规则的方法。这种技术组合既保证了学术严谨性,又具备工程落地价值。

2. 知识图谱构建全流程

2.1 数据预处理关键步骤

原始文本需要经过特殊清洗处理:

def clean_text(text): # 处理特殊标点与换行符 text = re.sub(r'[【】()《》]', '', text) # 合并对话中的折行 text = re.sub(r'“[^”]+?\n[^“]+?”', lambda x: x.group().replace('\n',''), text) # 标准化人物称谓(如"少安"->"孙少安") return custom_replace(text)

特别注意:书中人物存在"少安""少平"等简称,需建立别名映射表,否则后续实体识别准确率会下降30%以上

2.2 实体关系联合抽取方案

采用Pipeline方式分阶段处理:

  1. 实体识别:基于预训练模型+领域适配
# 使用RoBERTa-wwm作为基础模型 ner_model = AutoModelForTokenClassification.from_pretrained( "hfl/chinese-roberta-wwm-ext", num_labels=len(label_list) )
  1. 关系抽取:构建SPO三元组
{ "text": "田晓霞给孙少平送了《钢铁是怎样炼成的》", "spo_list": [ { "subject": "田晓霞", "predicate": "赠送", "object": "《钢铁是怎样炼成的》", "object_type": "物品" }, { "subject": "田晓霞", "predicate": "对象", "object": "孙少平", "object_type": "人物" } ] }

2.3 图谱存储优化策略

Neo4j图数据库采用分片存储设计:

  • 人物节点属性:角色类型(主角/配角)、出场章节、社会阶层
  • 关系属性:时间线、情感强度值(0-1)、发生场景
CREATE (sun:人物 {name:'孙少平', gender:'男', occupation:'矿工'}) CREATE (tian:人物 {name:'田晓霞', gender:'女', occupation:'记者'}) CREATE (sun)-[r:恋爱 {intensity:0.8, chapters:[25,36,47]}]->(tian)

3. 问答系统实现细节

3.1 问句解析模块

采用BERT+CRF的联合模型处理多种问句类型:

  • 属性类:"孙少安是什么职业?"
  • 关系类:"田润叶和谁有感情纠葛?"
  • 推理类:"双水村最有钱的人是谁?"

问句类型识别准确率对比:

模型准确率召回率
Rule-Based72.3%68.5%
BERT-CRF89.1%85.7%

3.2 答案生成策略

根据查询复杂度采用不同方案:

graph TD A[用户问题] --> B{问题类型} B -->|简单查询| C[Cypher直接查询] B -->|复杂推理| D[图嵌入计算] C --> E[结构化答案] D --> F[生成式回答]

实际开发中发现,对于"比较类"问题(如"谁对孙少平影响最大"),需要结合PageRank算法计算节点中心性:

def calculate_influence(person): query = """ MATCH (p:人物 {name:$name})<-[r]-(other) RETURN other.name, sum(r.intensity)*1.0/count(r) as influence ORDER BY influence DESC LIMIT 3 """ return graph.run(query, name=person).data()

4. 工程化落地经验

4.1 性能优化要点

  1. 缓存策略:

    • 高频查询结果用Redis缓存,TTL设为2小时
    • 人物基础信息预加载到内存
  2. 查询优化:

// 反例:全图扫描 MATCH (n)-[r]->(m) WHERE n.name='孙少平' RETURN r // 正例:使用索引提示 MATCH (n:人物 {name:'孙少平'})-[r]->(m) USING INDEX n:人物(name) RETURN r

4.2 典型问题排查

问题1:实体识别混淆"双水村"(地名)与"金家村"(地名)

  • 解决方案:添加自定义特征词典,强化地名识别

问题2:关系抽取误判"田福军批评田福堂"为正向关系

  • 调整方案:引入情感分析子模型,修正关系极性

问题3:Neo4j并发查询超时

  • 优化措施:设置连接池大小=CPU核心数*2 + 1

5. 项目扩展方向

  1. 时间线可视化:将事件节点按章节时间轴展示
  2. 情感分析增强:计算人物关系动态变化曲线
  3. 多模态扩展:结合电视剧剧照构建视觉知识图谱

这个项目让我深刻体会到,文学知识图谱的难点不在于技术实现,而在于对文本的深度理解。比如书中"平凡"与"世界"的哲学对立,就需要设计特殊的本体关系来表示。建议后续开发者先精读原著,再开始编码,否则很容易遗漏关键语义关系。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进