知识图谱实战(一):数据采集与实体关系抽取(完整代码)
知识图谱实战一数据采集与实体关系抽取完整代码从文档/网页里抽实体和关系拼成三元组这是知识图谱的原材料。这篇讲清楚数据从哪来、怎么把文字变成 (头实体, 关系, 尾实体)给一套完整可运行的抽取代码并为 《知识图谱二Neo4j 构建》/《知识图谱三GraphRAG》的图谱构建与调用打底。前言上一篇 RAG 系列用向量检索解决找相似内容但遇到任正非和华为是什么关系华为的产品有哪些这种精确关系问题向量检索就力不从心了。知识图谱Knowledge Graph是另一种答案把知识存成实体—关系—实体的图结构用图查询精确回答关系型问题。完整流程三步采集数据 → 构建图谱抽取三元组 存进图数据库→ 调用查询。这篇做第一步采集与抽取。一、整体流程先看地图数据采集爬虫/公开数据 ↓ 清洗与预处理 ↓ 实体关系抽取规则 / LLM 两种方式 ↓ 输出三元组head, relation, tail ↓ 【《知识图谱二Neo4j 构建》】Neo4j 建图 → 【《知识图谱三GraphRAG》】图查询 / GraphRAG知识图谱三要素实体Entity——人、公司、地点等关系Relation——“创始人”总部位于等三元组——(华为, 创始人, 任正非)一条知识。二、数据采集来源与方法采集方式取决于数据在哪数据源方式参考网页/新闻爬虫requests BeautifulSoup《爬虫实战》本地文档/Excel直接读取openpyxl / python-docx《办公自动化》公开 API接口直接拉取《爬虫实战》本文为了开箱即跑用一段内置的示例文本演示真实采集请换成 《爬虫实战》的方法抓取你关心的领域。三、环境准备先装依赖pip install requests beautifulsoup4 :: 词典分词可选pip install jieba四、完整代码规则式抽取可运行保存为kg_extract.py# kg_extract.py — 从文本抽取三元组输出 triples.csv完整可运行importreimportcsv# 1. 数据实际项目中换成爬虫/文档采集结果见 《爬虫实战》docs[华为技术有限公司成立于1987年总部位于深圳。,任正非是华为的创始人。,华为生产手机、路由器、交换机等产品。,任正非出生于贵州。,]# 2. 关系规则正则匹配原理展示规则简单清晰RELATION_PATTERNS[(r(.?)成立于(\d{4}年),成立时间),(r(.?)总部位于(.?),总部位于),(r(.?)是(.?)的创始人,创始人),(r(.?)生产(.?)、(.?)、(.?)等产品,生产),]# 3. 抽取defextract_triples(text):triples[]forpattern,relinRELATION_PATTERNS:mre.search(pattern,text)ifm:groupsm.groups()headgroups[0]fortailingroups[1:]:triples.append((head,rel,tail))returntriples all_triples[]fordocindocs:all_triplesextract_triples(doc)# 4. 去重并输出 CSVutf-8-sig 防 Excel 乱码seenset()rows[]forh,r,tinall_triples:if(h,r,t)notinseen:seen.add((h,r,t))rows.append([h,r,t])withopen(triples.csv,w,newline,encodingutf-8-sig)asf:writercsv.writer(f)writer.writerow([head,relation,tail])writer.writerows(rows)print(抽取到,len(rows),条三元组)forrinrows:print( ,r)运行验证python kg_extract.py期望看到打印 5 条左右三元组如[华为技术有限公司, 总部位于, 深圳]并生成triples.csv三列head/relation/tail——采集→抽取链路即通。五、进阶LLM 抽取效果更好直接可用规则式覆盖不了复杂句子换成让大模型抽——本地 Ollama 或云端 API 都行# kg_extract_llm.py — LLM 抽取三元组需本地 Ollama 或改 APIimportjsonimportrequestsimportcsv OLLAMA_URLhttp://localhost:11434/api/generate# 本地 OllamaMODELqwen2.5:7bdefllm_extract(text):prompt(你是知识图谱构建助手。从下面的文本中抽取所有三元组只输出 JSON 数组格式[{\head\: \实体\, \relation\: \关系\, \tail\: \实体\}]\nf文本{text})resprequests.post(OLLAMA_URL,json{model:MODEL,prompt:prompt,stream:False},timeout60)contentresp.json()[response]# 提取 JSON 数组部分startcontent.find([)endcontent.rfind(])1returnjson.loads(content[start:end])text华为技术有限公司1987年成立于深圳任正非是其创始人主要生产手机、路由器等通信设备。triplesllm_extract(text)print(LLM 抽取结果)fortintriples:print( ,t)withopen(triples_llm.csv,w,newline,encodingutf-8-sig)asf:wcsv.writer(f)w.writerow([head,relation,tail])w.writerows([[t[head],t[relation],t[tail]]fortintriples])运行验证启动 Ollamaollama run qwen2.5:7b先拉模型运行脚本期望打印带关系的三元组 JSON并生成triples_llm.csv。没装 Ollama 就把OLLAMA_URL换成任何 OpenAI 兼容接口。六、常见坑坑解决抽取结果重复/实体叫法不一做实体归一化同义实体映射表“华为→华为技术有限公司”规则式漏抽规则覆盖常见句式即可复杂句子交给 LLM 方式LLM 输出不是纯 JSON按示例截取[到]再 json.loads或提示词里加只输出 JSON关系类别混乱固定关系集合创始人/总部位于/成立时间/生产/…LLM 提示词里给出可选关系数据量大抽得慢分段抽取 多线程或用批量接口七、总结一句话知识图谱 三元组集合三元组 采集数据 实体关系抽取这篇产出triples.csv正是 《知识图谱二Neo4j 构建》 Neo4j 建图的输入——三篇连起来就是完整流程接单角度企业知识图谱人事档案、供应链、文档体系第一步都是数据抽取成三元组这套代码是通用起点。觉得有用点个赞收藏下一篇《知识图谱二Neo4j 构建与导入》见。