知识图谱实战(一):数据采集与实体关系抽取(完整代码)

知识图谱实战(一):数据采集与实体关系抽取(完整代码)

从文档/网页里抽"实体和关系",拼成三元组,这是知识图谱的原材料。这篇讲清楚:数据从哪来、怎么把文字变成 (头实体, 关系, 尾实体),给一套完整可运行的抽取代码,并为 《知识图谱(二)Neo4j 构建》/《知识图谱(三)GraphRAG》的图谱构建与调用打底。

前言

上一篇 RAG 系列用向量检索解决"找相似内容",但遇到"任正非和华为是什么关系""华为的产品有哪些"这种精确关系问题,向量检索就力不从心了。知识图谱(Knowledge Graph)是另一种答案:把知识存成"实体---关系---实体"的图结构,用图查询精确回答关系型问题。

完整流程三步:采集数据 → 构建图谱(抽取三元组 + 存进图数据库)→ 调用查询。这篇做第一步:采集与抽取。

一、整体流程(先看地图)

bash 复制代码
数据采集(爬虫/公开数据)
   ↓
清洗与预处理
   ↓
实体关系抽取(规则 / LLM 两种方式)
   ↓
输出三元组(head, relation, tail)
   ↓
【《知识图谱(二)Neo4j 构建》】Neo4j 建图 → 【《知识图谱(三)GraphRAG》】图查询 / GraphRAG

知识图谱三要素:实体(Entity) ------人、公司、地点等;关系(Relation) ------"创始人""总部位于"等;三元组 ------(华为, 创始人, 任正非) 一条知识。

二、数据采集(来源与方法)

采集方式取决于数据在哪:

数据源 方式 参考
网页/新闻 爬虫(requests + BeautifulSoup) 《爬虫实战》
本地文档/Excel 直接读取(openpyxl / python-docx) 《办公自动化》
公开 API 接口直接拉取 《爬虫实战》

本文为了"开箱即跑",用一段内置的示例文本演示(真实采集请换成 《爬虫实战》的方法抓取你关心的领域)。

三、环境准备(先装依赖)

bat 复制代码
pip install requests beautifulsoup4
:: 词典分词可选:pip install jieba

四、完整代码:规则式抽取(可运行)

保存为 kg_extract.py

python 复制代码
# kg_extract.py --- 从文本抽取三元组,输出 triples.csv(完整可运行)
import re
import csv

# 1. 数据:实际项目中换成爬虫/文档采集结果(见 《爬虫实战》)
docs = [
    "华为技术有限公司成立于1987年,总部位于深圳。",
    "任正非是华为的创始人。",
    "华为生产手机、路由器、交换机等产品。",
    "任正非出生于贵州。",
]

# 2. 关系规则:正则匹配(原理展示,规则简单清晰)
RELATION_PATTERNS = [
    (r"(.+?)成立于(\d{4}年)", "成立时间"),
    (r"(.+?)总部位于(.+?)", "总部位于"),
    (r"(.+?)是(.+?)的创始人", "创始人"),
    (r"(.+?)生产(.+?)、(.+?)、(.+?)等产品", "生产"),
]

# 3. 抽取
def extract_triples(text):
    triples = []
    for pattern, rel in RELATION_PATTERNS:
        m = re.search(pattern, text)
        if m:
            groups = m.groups()
            head = groups[0]
            for tail in groups[1:]:
                triples.append((head, rel, tail))
    return triples

all_triples = []
for doc in docs:
    all_triples += extract_triples(doc)

# 4. 去重并输出 CSV(utf-8-sig 防 Excel 乱码)
seen = set()
rows = []
for h, r, t in all_triples:
    if (h, r, t) not in seen:
        seen.add((h, r, t))
        rows.append([h, r, t])

with open("triples.csv", "w", newline="", encoding="utf-8-sig") as f:
    writer = csv.writer(f)
    writer.writerow(["head", "relation", "tail"])
    writer.writerows(rows)

print("抽取到", len(rows), "条三元组:")
for r in rows:
    print("  ", r)

运行验证python kg_extract.py,期望看到打印 5 条左右三元组(如 ['华为技术有限公司', '总部位于', '深圳']),并生成 triples.csv(三列:head/relation/tail)------采集→抽取链路即通。

五、进阶:LLM 抽取(效果更好,直接可用)

规则式覆盖不了复杂句子,换成让大模型抽------本地 Ollama 或云端 API 都行:

python 复制代码
# kg_extract_llm.py --- LLM 抽取三元组(需本地 Ollama 或改 API)
import json
import requests
import csv

OLLAMA_URL = "http://localhost:11434/api/generate"   # 本地 Ollama
MODEL = "qwen2.5:7b"

def llm_extract(text):
    prompt = (
        "你是知识图谱构建助手。从下面的文本中抽取所有三元组,"
        "只输出 JSON 数组,格式:[{\"head\": \"实体\", \"relation\": \"关系\", \"tail\": \"实体\"}]\n"
        f"文本:{text}"
    )
    resp = requests.post(OLLAMA_URL, json={"model": MODEL, "prompt": prompt,
                                           "stream": False}, timeout=60)
    content = resp.json()["response"]
    # 提取 JSON 数组部分
    start = content.find("[")
    end = content.rfind("]") + 1
    return json.loads(content[start:end])

text = "华为技术有限公司1987年成立于深圳,任正非是其创始人,主要生产手机、路由器等通信设备。"
triples = llm_extract(text)
print("LLM 抽取结果:")
for t in triples:
    print("  ", t)

with open("triples_llm.csv", "w", newline="", encoding="utf-8-sig") as f:
    w = csv.writer(f)
    w.writerow(["head", "relation", "tail"])
    w.writerows([[t["head"], t["relation"], t["tail"]] for t in triples])

运行验证 :启动 Ollama(ollama run qwen2.5:7b 先拉模型),运行脚本,期望打印带关系的三元组 JSON,并生成 triples_llm.csv。没装 Ollama 就把 OLLAMA_URL 换成任何 OpenAI 兼容接口。

六、常见坑

解决
抽取结果重复/实体叫法不一 实体归一化:同义实体映射表("华为"→"华为技术有限公司")
规则式漏抽 规则覆盖常见句式即可,复杂句子交给 LLM 方式
LLM 输出不是纯 JSON 按示例截取 [] 再 json.loads;或提示词里加"只输出 JSON"
关系类别混乱 固定关系集合(创始人/总部位于/成立时间/生产/...),LLM 提示词里给出可选关系
数据量大抽得慢 分段抽取 + 多线程;或用批量接口

七、总结

  • 一句话:知识图谱 = 三元组集合;三元组 = 采集数据 + 实体关系抽取
  • 这篇产出 triples.csv,正是 《知识图谱(二)Neo4j 构建》 Neo4j 建图的输入------三篇连起来就是完整流程;
  • 接单角度:企业知识图谱(人事档案、供应链、文档体系)第一步都是"数据抽取成三元组",这套代码是通用起点。

觉得有用点个赞收藏,下一篇《知识图谱(二):Neo4j 构建与导入》见。

相关推荐
方方洛1 分钟前
vllm教程-00-前言与导读
人工智能·算法·vllm
IT毕设实战小研18 分钟前
电影数据可视化推荐系统
大数据·后端·爬虫·python·算法·信息可视化·课程设计
且随疾风前行.23 分钟前
从驱动来分析服务的添加过程
算法
CoderYanger1 小时前
A.每日一题:输入单词需要的最少按键次数 Ⅰ+Ⅱ
java·数据结构·算法·leetcode·面试
xiaokcehui2 小时前
地球物理大地测量学计算系列之十七局部重力场SRBF逼近及其性能指标测评
人工智能·算法·机器学习
Navigator_Z2 小时前
LeetCode //C - 1221. Split a String in Balanced Strings
c语言·算法·leetcode
天疆说2 小时前
庞特里亚金极小值原理的详细推导
算法
余俊晖3 小时前
Self-OPD:去掉教师机的流匹配模型 On-Policy 蒸馏
人工智能·算法·机器学习
手写码匠3 小时前
华为云Flexus+DeepSeek征文|华为云MaaS DeepSeek推理服务 × Flexus云服务器 × Dify一键部署:性能评测实战
人工智能·深度学习·算法·aigc
啥都想学点的研究生4 小时前
一篇文章讲清楚:逻辑回归
算法·机器学习·逻辑回归