本文目录导读:

我来详细介绍一下如何使用Python构建数据知识图谱。
知识图谱核心概念
知识图谱由实体(节点)和关系(边)组成,使用三元组表示:(实体1, 关系, 实体2)
Python构建知识图谱方案
使用NetworkX(轻量级)
import networkx as nx
import matplotlib.pyplot as plt
from typing import List, Tuple, Dict
class SimpleKnowledgeGraph:
def __init__(self):
self.graph = nx.MultiDiGraph() # 有向多重图
def add_entity(self, entity_id: str, properties: dict = None):
"""添加实体节点"""
self.graph.add_node(entity_id, **properties if properties else {})
def add_relationship(self, entity1: str, entity2: str,
relation: str, properties: dict = None):
"""添加关系边"""
self.graph.add_edge(entity1, entity2,
relation=relation,
**properties if properties else {})
def query_entity(self, entity_id: str):
"""查询实体信息"""
if entity_id in self.graph:
return dict(self.graph.nodes[entity_id])
return None
def query_relationships(self, entity_id: str):
"""查询实体的所有关系"""
relationships = []
for _, neighbor, data in self.graph.edges(entity_id, data=True):
relationships.append({
'entity1': entity_id,
'entity2': neighbor,
'relation': data['relation']
})
return relationships
def visualize(self, figsize=(12, 8)):
"""可视化知识图谱"""
pos = nx.spring_layout(self.graph)
plt.figure(figsize=figsize)
# 绘制节点
nx.draw_networkx_nodes(self.graph, pos, node_color='lightblue',
node_size=2000)
# 绘制边
nx.draw_networkx_edges(self.graph, pos, arrows=True)
# 添加标签
nx.draw_networkx_labels(self.graph, pos)
# 添加关系标签
edge_labels = {(u, v): d['relation']
for u, v, d in self.graph.edges(data=True)}
nx.draw_networkx_edge_labels(self.graph, pos, edge_labels=edge_labels)
plt.title("知识图谱")
plt.axis('off')
plt.show()
# 使用示例
kg = SimpleKnowledgeGraph()
# 添加实体
kg.add_entity("Python", {"type": "编程语言", "creator": "Guido van Rossum"})
kg.add_entity("Django", {"type": "Web框架", "language": "Python"})
kg.add_entity("Guido", {"type": "程序员", "nationality": "荷兰"})
# 添加关系
kg.add_relationship("Guido", "Python", "创造了")
kg.add_relationship("Python", "Django", "用于开发")
kg.add_relationship("Guido", "Python", "开发了")
# 查询
print(kg.query_entity("Python"))
print(kg.query_relationships("Python"))
# 可视化
kg.visualize()
使用Neo4j(企业级)
from neo4j import GraphDatabase
import pandas as pd
class Neo4jKnowledgeGraph:
def __init__(self, uri, user, password):
self.driver = GraphDatabase.driver(uri, auth=(user, password))
def close(self):
self.driver.close()
def create_entity(self, tx, entity_id, properties):
"""创建实体节点"""
query = """
CREATE (e:Entity {id: $entity_id})
SET e += $properties
RETURN e
"""
result = tx.run(query, entity_id=entity_id, properties=properties)
return result.single()
def create_relationship(self, tx, entity1_id, entity2_id, relation, properties):
"""创建关系"""
query = """
MATCH (e1:Entity {id: $entity1_id})
MATCH (e2:Entity {id: $entity2_id})
CREATE (e1)-[r:RELATION {type: $relation}]->(e2)
SET r += $properties
RETURN r
"""
result = tx.run(query, entity1_id=entity1_id, entity2_id=entity2_id,
relation=relation, properties=properties)
return result.single()
def load_from_dataframe(self, df: pd.DataFrame,
entity_col: str = 'entity',
relation_col: str = 'relation',
target_col: str = 'target'):
"""从DataFrame加载知识图谱"""
with self.driver.session() as session:
for _, row in df.iterrows():
session.execute_write(self.create_entity,
row[entity_col],
{'source': row[entity_col]})
session.execute_write(self.create_entity,
row[target_col],
{'target': row[target_col]})
session.execute_write(self.create_relationship,
row[entity_col],
row[target_col],
row[relation_col],
{})
def query_entity_relations(self, entity_id):
"""查询实体关系"""
with self.driver.session() as session:
result = session.run("""
MATCH (e:Entity {id: $entity_id})-[r]-(connected)
RETURN e.id as entity, type(r) as relation, connected.id as connected_entity
""", entity_id=entity_id)
return pd.DataFrame([r for r in result])
# 使用示例
# kg = Neo4jKnowledgeGraph("bolt://localhost:7687", "neo4j", "password")
# 准备数据
# data = {
# 'entity': ['Python', 'Python', 'Guido'],
# 'relation': ['用于开发', '有包管理器', '创造了'],
# 'target': ['Django', 'pip', 'Python']
# }
# df = pd.DataFrame(data)
# kg.load_from_dataframe(df)
从结构化数据构建
import json
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
class DataDrivenKnowledgeGraph:
def __init__(self):
self.entities = {}
self.relationships = []
def extract_entities_from_data(self, data: list, key_fields: list):
"""从数据中提取实体"""
for item in data:
entity_id = str(item.get(key_fields[0], ''))
properties = {k: v for k, v in item.items() if k in key_fields}
self.entities[entity_id] = properties
def infer_relationships(self, threshold=0.7):
"""基于相似度推断实体关系"""
# 将实体属性转换为向量
texts = []
entity_ids = []
for entity_id, properties in self.entities.items():
text = ' '.join([str(v) for v in properties.values()])
texts.append(text)
entity_ids.append(entity_id)
# 计算相似度
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(texts)
similarity_matrix = cosine_similarity(tfidf_matrix)
# 建立关系
for i in range(len(entity_ids)):
for j in range(i+1, len(entity_ids)):
if similarity_matrix[i][j] > threshold:
self.relationships.append({
'source': entity_ids[i],
'target': entity_ids[j],
'relation': 'similar',
'weight': similarity_matrix[i][j]
})
def export_to_json(self, filepath):
"""导出为JSON格式"""
output = {
'entities': self.entities,
'relationships': self.relationships
}
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(output, f, ensure_ascii=False, indent=2)
# 使用示例
data = [
{'id': 'Python', 'type': 'language', 'year': 1991, 'creator': 'Guido'},
{'id': 'JavaScript', 'type': 'language', 'year': 1995, 'creator': 'Brendan'},
{'id': 'Django', 'type': 'framework', 'year': 2005, 'language': 'Python'},
{'id': 'React', 'type': 'framework', 'year': 2013, 'language': 'JavaScript'}
]
kg = DataDrivenKnowledgeGraph()
kg.extract_entities_from_data(data, ['id', 'type', 'year'])
kg.infer_relationships(threshold=0.5)
print("Relationships found:", kg.relationships)
kg.export_to_json('knowledge_graph.json')
从文本中抽取(NLP方法)
import spacy
from collections import defaultdict
class TextToKnowledgeGraph:
def __init__(self):
self.nlp = spacy.load("zh_core_web_sm")
self.entities = set()
self.relationships = []
def extract_triples(self, text: str):
"""从文本中提取三元组"""
doc = self.nlp(text)
triples = []
# 提取命名实体
entities = [(ent.text, ent.label_) for ent in doc.ents]
# 简单的三元组提取规则
for token in doc:
if token.dep_ == "nsubj" and token.head.pos_ == "VERB":
subject = token.text
predicate = token.head.text
objects = [child.text for child in token.head.children
if child.dep_ == "dobj"]
for obj in objects:
triples.append((subject, predicate, obj))
return triples
def build_from_texts(self, texts: list):
"""从文本列表构建知识图谱"""
for text in texts:
triples = self.extract_triples(text)
for subj, pred, obj in triples:
self.entities.add(subj)
self.entities.add(obj)
self.relationships.append({
'subject': subj,
'predicate': pred,
'object': obj
})
def display_statistics(self):
"""显示统计信息"""
print(f"实体数量: {len(self.entities)}")
print(f"关系数量: {len(self.relationships)}")
# 统计关系类型
relation_types = defaultdict(int)
for rel in self.relationships:
relation_types[rel['predicate']] += 1
print("\n关系类型分布:")
for rel_type, count in sorted(relation_types.items(), key=lambda x: -x[1]):
print(f" {rel_type}: {count}")
# 使用示例
# 需要先下载中文模型: python -m spacy download zh_core_web_sm
# texts = [
# "Python是由Guido van Rossum创建的编程语言",
# "Django是用Python开发的Web框架",
# "TensorFlow是Google开发的机器学习框架"
# ]
# kg = TextToKnowledgeGraph()
# kg.build_from_texts(texts)
# kg.display_statistics()
数据存储方案
RDF格式存储
from rdflib import Graph, Literal, RDF, URIRef, Namespace
from rdflib.namespace import FOAF, XSD
# 创建RDF图
g = Graph()
ex = Namespace("http://example.org/")
# 添加三元组
python = URIRef(ex + "Python")
guido = URIRef(ex + "Guido")
g.add((guido, RDF.type, FOAF.Person))
g.add((guido, FOAF.name, Literal("Guido van Rossum", lang="en")))
g.add((python, ex.createdBy, guido))
# 序列化
print(g.serialize(format="turtle"))
g.serialize("knowledge_graph.rdf", format="xml")
实用建议
- 数据质量:确保实体ID唯一,关系明确
- 存储选择:
- 小规模(<10万节点):NetworkX
- 中规模:Neo4j Community
- 大规模:Neo4j Enterprise / JanusGraph
- 查询优化:使用索引,设计合适的图模式
- 可视化:D3.js, Cytoscape.js, vis.js
选择哪种方案取决于你的具体需求:数据规模、查询复杂度、实时性要求等。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播