在前几节中,我们学习了传统的机器学习方法。今天,我们将进入知识表示与检索领域,探索现代AI系统中重要的知识组织和检索技术。我们将重点学习知识图谱和向量检索这两种关键技术,它们在搜索引擎、推荐系统和大语言模型中发挥着重要作用。
知识表示与检索概览
知识表示与检索是AI系统理解和利用知识的关键技术。随着大数据和深度学习的发展,现代知识表示方法已经从传统的符号表示发展到向量表示。
graph TD
A[知识表示与检索] --> B[符号表示]
A --> C[向量表示]
B --> D[知识图谱]
B --> E[规则引擎]
C --> F[向量检索]
C --> G[Embedding技术]
D --> H[实体与关系]
D --> I[图数据库]
F --> J[相似度计算]
F --> K[向量数据库]
知识图谱基础
知识图谱是一种结构化的语义知识库,用于描述现实世界中的实体及其相互关系。
知识图谱的核心概念
知识图谱由实体(Entities)、属性(Attributes)和关系(Relationships)组成,通常表示为三元组(头实体,关系,尾实体)。
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
# 创建一个简单的知识图谱示例
class SimpleKnowledgeGraph:
"""简单知识图谱实现"""
def __init__(self):
self.entities = {}
self.relations = {}
self.triples = []
def add_entity(self, entity, entity_type=None):
"""添加实体"""
self.entities[entity] = entity_type or "Unknown"
def add_relation(self, head, relation, tail):
"""添加关系"""
if head not in self.entities:
self.add_entity(head)
if tail not in self.entities:
self.add_entity(tail)
self.relations[relation] = self.relations.get(relation, 0) + 1
self.triples.append((head, relation, tail))
def query_one_hop(self, entity):
"""单跳查询"""
results = []
for head, relation, tail in self.triples:
if head == entity:
results.append((relation, tail))
elif tail == entity:
results.append((relation, head))
return results
def get_entities_by_type(self, entity_type):
"""根据类型获取实体"""
return [entity for entity, e_type in self.entities.items() if e_type == entity_type]
# 创建知识图谱实例
kg = SimpleKnowledgeGraph()
# 添加实体
kg.add_entity("爱因斯坦", "科学家")
kg.add_entity("普林斯顿大学", "大学")
kg.add_entity("相对论", "理论")
kg.add_entity("光电效应", "理论")
kg.add_entity("诺贝尔物理学奖", "奖项")
kg.add_entity("德国", "国家")
kg.add_entity("美国", "国家")
# 添加关系
kg.add_relation("爱因斯坦", "工作于", "普林斯顿大学")
kg.add_relation("爱因斯坦", "提出", "相对论")
kg.add_relation("爱因斯坦", "提出", "光电效应")
kg.add_relation("爱因斯坦", "获得", "诺贝尔物理学奖")
kg.add_relation("爱因斯坦", "国籍", "德国")
kg.add_relation("爱因斯坦", "居住于", "美国")
kg.add_relation("普林斯顿大学", "位于", "美国")
kg.add_relation("相对论", "属于领域", "物理学")
kg.add_relation("光电效应", "属于领域", "物理学")
# 查询示例
print("知识图谱查询示例:")
print("爱因斯坦的相关信息:")
for relation, entity in kg.query_one_hop("爱因斯坦"):
print(f" {relation}: {entity}")
print("\n科学家实体:")
scientists = kg.get_entities_by_type("科学家")
print(f" {scientists}")
# 可视化知识图谱
def visualize_knowledge_graph(kg):
"""可视化知识图谱"""
G = nx.DiGraph()
# 添加节点
for entity in kg.entities:
G.add_node(entity, type=kg.entities[entity])
# 添加边
for head, relation, tail in kg.triples:
G.add_edge(head, tail, relation=relation)
# 设置布局
pos = nx.spring_layout(G, k=2, iterations=50)
# 绘制节点
plt.figure(figsize=(14, 10))
# 按类型着色节点
node_colors = []
type_colors = {"科学家": "red", "大学": "blue", "理论": "green",
"奖项": "orange", "国家": "purple", "Unknown": "gray"}
for node in G.nodes():
node_type = G.nodes[node]['type']
node_colors.append(type_colors.get(node_type, "gray"))
nx.draw_networkx_nodes(G, pos, node_color=node_colors, node_size=1500, alpha=0.8)
nx.draw_networkx_labels(G, pos, font_size=10, font_weight="bold")
# 绘制边和关系标签
nx.draw_networkx_edges(G, pos, width=2, alpha=0.5, edge_color='black', arrows=True, arrowsize=20)
# 添加边标签
edge_labels = nx.get_edge_attributes(G, 'relation')
nx.draw_networkx_edge_labels(G, pos, edge_labels, font_size=8)
plt.title("爱因斯坦知识图谱", size=15)
plt.axis("off")
plt.tight_layout()
plt.show()
# 可视化知识图谱
visualize_knowledge_graph(kg)
使用公开知识图谱API
# 模拟使用DBpedia API查询知识图谱
def simulate_dbpedia_query(entity):
"""模拟DBpedia查询"""
# 这是一个模拟函数,实际使用时需要调用真实的API
mock_data = {
"爱因斯坦": {
"abstract": "阿尔伯特·爱因斯坦是一位理论物理学家,被广泛认为是历史上最伟大的科学家之一。",
"birthPlace": "德国乌尔姆",
"deathPlace": "美国新泽西州普林斯顿",
"knownFor": ["相对论", "光电效应", "质能等价"],
"awards": ["诺贝尔物理学奖(1921)", "科普利奖章(1925)"]
},
"相对论": {
"abstract": "相对论是阿尔伯特·爱因斯坦提出的物理学理论,包括狭义相对论和广义相对论。",
"field": "理论物理学",
"year": "1905年(狭义), 1915年(广义)",
"implications": ["时空弯曲", "质能等价", "引力波"]
}
}
return mock_data.get(entity, {"error": f"未找到实体 {entity} 的信息"})
# 查询示例
print("模拟DBpedia查询结果:")
einstein_info = simulate_dbpedia_query("爱因斯坦")
for key, value in einstein_info.items():
print(f"{key}: {value}")
print("\n" + "="*50 + "\n")
relativity_info = simulate_dbpedia_query("相对论")
for key, value in relativity_info.items():
print(f"{key}: {value}")
向量检索基础
向量检索是一种基于向量相似度的检索方法,通过将文本、图像等数据转换为向量,然后计算向量间的相似度来实现检索。
文本向量化
# 简单的文本向量化方法
class SimpleTextVectorizer:
"""简单文本向量化器"""
def __init__(self):
self.vocabulary = {}
self.vocab_size = 0
def fit(self, documents):
"""构建词汇表"""
vocab_set = set()
for doc in documents:
words = doc.lower().split()
vocab_set.update(words)
self.vocabulary = {word: idx for idx, word in enumerate(sorted(vocab_set))}
self.vocab_size = len(self.vocabulary)
return self
def transform(self, documents):
"""将文档转换为向量"""
vectors = []
for doc in documents:
vector = np.zeros(self.vocab_size)
words = doc.lower().split()
for word in words:
if word in self.vocabulary:
vector[self.vocabulary[word]] += 1
vectors.append(vector)
return np.array(vectors)
def fit_transform(self, documents):
"""拟合并转换"""
return self.fit(documents).transform(documents)
# 示例文档
documents = [
"机器学习是人工智能的一个重要分支",
"深度学习是机器学习的一个子领域",
"神经网络是深度学习的核心技术",
"自然语言处理是人工智能的应用领域",
"计算机视觉是人工智能的重要方向"
]
# 向量化文档
vectorizer = SimpleTextVectorizer()
doc_vectors = vectorizer.fit_transform(documents)
print("词汇表:")
for word, idx in vectorizer.vocabulary.items():
print(f" {word}: {idx}")
print(f"\n文档向量形状: {doc_vectors.shape}")
print("文档向量示例:")
for i, vector in enumerate(doc_vectors):
print(f" 文档 {i+1}: {vector}")
向量相似度计算
# 向量相似度计算
def cosine_similarity(vec1, vec2):
"""计算余弦相似度"""
dot_product = np.dot(vec1, vec2)
norm1 = np.linalg.norm(vec1)
norm2 = np.linalg.norm(vec2)
if norm1 == 0 or norm2 == 0:
return 0
return dot_product / (norm1 * norm2)
def euclidean_distance(vec1, vec2):
"""计算欧几里得距离"""
return np.linalg.norm(vec1 - vec2)
# 计算文档间的相似度
print("文档相似度计算:")
print("余弦相似度矩阵:")
similarity_matrix = np.zeros((len(documents), len(documents)))
for i in range(len(documents)):
for j in range(len(documents)):
similarity_matrix[i][j] = cosine_similarity(doc_vectors[i], doc_vectors[j])
print(f"{similarity_matrix[i][j]:.4f}", end=" ")
print()
# 可视化相似度矩阵
plt.figure(figsize=(8, 6))
plt.imshow(similarity_matrix, cmap='viridis', interpolation='nearest')
plt.colorbar(label='余弦相似度')
plt.title('文档相似度矩阵')
plt.xlabel('文档索引')
plt.ylabel('文档索引')
# 添加数值标签
for i in range(len(documents)):
for j in range(len(documents)):
plt.text(j, i, f'{similarity_matrix[i][j]:.2f}',
ha='center', va='center', color='white')
plt.tight_layout()
plt.show()
# 查询最相似的文档
def find_most_similar(query, documents, doc_vectors, vectorizer):
"""查找最相似的文档"""
query_vector = vectorizer.transform([query])[0]
similarities = []
for i, doc_vector in enumerate(doc_vectors):
similarity = cosine_similarity(query_vector, doc_vector)
similarities.append((i, similarity))
# 按相似度排序
similarities.sort(key=lambda x: x[1], reverse=True)
return similarities
# 查询示例
query = "人工智能和机器学习的关系"
similarities = find_most_similar(query, documents, doc_vectors, vectorizer)
print(f"\n查询: '{query}'")
print("最相似的文档:")
for idx, similarity in similarities[:3]:
print(f" 文档 {idx+1} (相似度: {similarity:.4f}): {documents[idx]}")
使用预训练的Embedding模型
# 模拟使用预训练的Word2Vec模型
class MockWord2Vec:
"""模拟Word2Vec模型"""
def __init__(self):
# 模拟词向量
np.random.seed(42)
self.vocab = {
'人工智能': np.random.randn(100),
'机器学习': np.random.randn(100),
'深度学习': np.random.randn(100),
'神经网络': np.random.randn(100),
'自然语言': np.random.randn(100),
'计算机': np.random.randn(100),
'视觉': np.random.randn(100),
'处理': np.random.randn(100)
}
def get_vector(self, word):
"""获取词向量"""
return self.vocab.get(word, np.zeros(100))
def similarity(self, word1, word2):
"""计算词相似度"""
vec1 = self.get_vector(word1)
vec2 = self.get_vector(word2)
return cosine_similarity(vec1, vec2)
# 使用模拟的Word2Vec
word2vec = MockWord2Vec()
print("词向量相似度示例:")
word_pairs = [
("人工智能", "机器学习"),
("机器学习", "深度学习"),
("神经网络", "深度学习"),
("自然语言", "处理"),
("计算机", "视觉")
]
for word1, word2 in word_pairs:
sim = word2vec.similarity(word1, word2)
print(f" {word1} - {word2}: {sim:.4f}")
# 词向量可视化(使用PCA降维)
from sklearn.decomposition import PCA
words = list(word2vec.vocab.keys())
vectors = [word2vec.get_vector(word) for word in words]
# 使用PCA降维到2D
pca = PCA(n_components=2)
vectors_2d = pca.fit_transform(vectors)
# 可视化词向量
plt.figure(figsize=(10, 8))
plt.scatter(vectors_2d[:, 0], vectors_2d[:, 1], s=100)
for i, word in enumerate(words):
plt.annotate(word, (vectors_2d[i, 0], vectors_2d[i, 1]),
xytext=(5, 2), textcoords='offset points', fontsize=12)
plt.title('词向量可视化 (PCA降维)')
plt.xlabel('第一主成分')
plt.ylabel('第二主成分')
plt.grid(True, alpha=0.3)
plt.show()
向量数据库简介
向量数据库是专门用于存储和检索向量数据的系统,支持高效的相似性搜索。
# 简单的向量数据库实现
class SimpleVectorDB:
"""简单向量数据库"""
def __init__(self):
self.vectors = []
self.metadata = []
def add(self, vector, meta=None):
"""添加向量"""
self.vectors.append(np.array(vector))
self.metadata.append(meta or {})
def search(self, query_vector, top_k=5):
"""搜索最相似的向量"""
query_vector = np.array(query_vector)
similarities = []
for i, vector in enumerate(self.vectors):
similarity = cosine_similarity(query_vector, vector)
similarities.append((i, similarity, self.metadata[i]))
# 按相似度排序
similarities.sort(key=lambda x: x[1], reverse=True)
return similarities[:top_k]
# 创建向量数据库示例
vector_db = SimpleVectorDB()
# 添加一些示例数据
sample_vectors = [
([0.1, 0.2, 0.3, 0.4], {"text": "人工智能是计算机科学的一个分支", "category": "AI"}),
([0.2, 0.3, 0.4, 0.5], {"text": "机器学习是实现人工智能的方法", "category": "ML"}),
([0.3, 0.4, 0.5, 0.6], {"text": "深度学习使用多层神经网络", "category": "DL"}),
([0.7, 0.8, 0.9, 1.0], {"text": "自然语言处理处理文本数据", "category": "NLP"}),
([0.8, 0.9, 1.0, 1.1], {"text": "计算机视觉处理图像数据", "category": "CV"})
]
for vector, meta in sample_vectors:
vector_db.add(vector, meta)
# 查询示例
query = [0.15, 0.25, 0.35, 0.45]
results = vector_db.search(query, top_k=3)
print("向量数据库查询结果:")
print(f"查询向量: {query}")
print("最相似的结果:")
for i, (idx, similarity, meta) in enumerate(results):
print(f" {i+1}. 相似度: {similarity:.4f}")
print(f" 文本: {meta['text']}")
print(f" 类别: {meta['category']}")
print()
知识图谱与向量检索的融合
现代AI系统往往将符号表示(知识图谱)和向量表示(向量检索)相结合,发挥各自优势。
# 知识图谱与向量检索结合的示例
class HybridKnowledgeSystem:
"""混合知识系统"""
def __init__(self):
self.kg = SimpleKnowledgeGraph()
self.vector_db = SimpleVectorDB()
self.vectorizer = SimpleTextVectorizer()
def add_knowledge(self, entity, entity_type, description):
"""添加知识"""
self.kg.add_entity(entity, entity_type)
# 将描述添加到向量数据库
self.vector_db.add(description, {"entity": entity, "type": entity_type})
def add_relation(self, head, relation, tail):
"""添加关系"""
self.kg.add_relation(head, relation, tail)
def query_by_relation(self, entity):
"""基于关系的查询"""
return self.kg.query_one_hop(entity)
def query_by_similarity(self, query_text, top_k=3):
"""基于相似度的查询"""
return self.vector_db.search(query_text, top_k)
# 创建混合知识系统
hybrid_system = HybridKnowledgeSystem()
# 添加知识
hybrid_system.add_knowledge("爱因斯坦", "科学家", "阿尔伯特·爱因斯坦是著名的理论物理学家")
hybrid_system.add_knowledge("相对论", "理论", "相对论是爱因斯坦提出的物理学理论")
hybrid_system.add_knowledge("机器学习", "技术", "机器学习是人工智能的一个重要分支")
hybrid_system.add_knowledge("神经网络", "技术", "神经网络是深度学习的核心技术")
# 添加关系
hybrid_system.add_relation("爱因斯坦", "提出", "相对论")
hybrid_system.add_relation("神经网络", "属于", "机器学习")
# 查询示例
print("混合知识系统查询示例:")
print("\n1. 基于关系的查询 - 爱因斯坦:")
relations = hybrid_system.query_by_relation("爱因斯坦")
for relation, entity in relations:
print(f" {relation}: {entity}")
print("\n2. 基于相似度的查询 - '物理学理论':")
similar_results = hybrid_system.query_by_similarity("物理学理论", top_k=2)
for idx, similarity, meta in similar_results:
print(f" 实体: {meta['entity']}, 相似度: {similarity:.4f}")
print("\n3. 基于相似度的查询 - 'AI技术':")
similar_results = hybrid_system.query_by_similarity("AI技术", top_k=2)
for idx, similarity, meta in similar_results:
print(f" 实体: {meta['entity']}, 相似度: {similarity:.4f}")
本周学习总结
今天我们学习了现代知识表示与检索的重要技术:
-
知识图谱
- 理解了知识图谱的基本概念和结构
- 学会了构建和查询简单的知识图谱
- 了解了公开知识图谱的使用方法
-
向量检索
- 掌握了文本向量化的基本方法
- 学会了计算向量相似度
- 了解了向量数据库的基本原理
-
融合应用
- 了解了符号表示与向量表示的结合方法
- 实现了混合知识系统
graph TD
A[知识表示与检索] --> B[知识图谱]
A --> C[向量检索]
B --> D[实体与关系]
B --> E[图谱查询]
C --> F[文本向量化]
C --> G[相似度计算]
C --> H[向量数据库]
A --> I[融合应用]
课后练习
- 运行本节所有代码示例,理解知识图谱和向量检索的原理
- 扩展SimpleKnowledgeGraph类,添加更多查询功能(如多跳查询)
- 实现不同的向量相似度计算方法(如欧几里得距离、曼哈顿距离等)
- 研究真实的向量数据库(如Faiss、Weaviate等)的使用方法
下节预告
下一节我们将学习强化学习基础,包括Q-Learning等经典算法,这些方法在游戏AI和机器人控制中应用广泛,敬请期待!
有任何疑问请在讨论区留言,我们会定期回复大家的问题。