整合文本和知识图谱嵌入提升RAG的性能
此前已经介绍过将知识图谱与RAG结合的示例,这次进一步把文本和知识图谱结合起来,看看如何提升RAG的性能。先从一个核心组件说起——文本嵌入。

文本嵌入的RAG
文本嵌入,本质上是单词或短语的数字表示,能高效地捕捉它们的语义和上下文。你可以把它想象成每个词独一无二的“身份证”——一个简洁的向量,封装了词的含义。有了这些嵌入,计算机对文本的理解和处理能力大大增强,在文本分类、情感分析、机器翻译等NLP任务中表现优异。
常用的预训练模型,比如Word2Vec、GloVe或BERT,都可以用来生成文本嵌入。这些模型在大量文本数据上训练过,已经学会了编码词汇及其关系的语义信息。
那么,如何生成文本嵌入呢?下面这段简单的代码(基于Word2Vec)展示了整个过程:
# Code Implementation: Generating Text Embeddings
import numpy as np
from gensim.models import Word2Vec
# Sample sentences
sentences = [
["I", "love", "natural", "language", "processing"],
["Text", "embeddings", "are", "fascinating"],
["NLP", "makes", "computers", "understand", "language"]
]
# Train Word2Vec model
model = Word2Vec(sentences, vector_size=5, window=5, min_count=1, sg=1)
# Get embeddings for words
word_embeddings = {}
for word in model.wv.index_to_key:
word_embeddings[word] = model.wv[word]
# Print embeddings
for word, embedding in word_embeddings.items():
print(f"Embedding for '{word}': {embedding}")
在这里,我们用一组示例句子训练了一个Word2Vec模型,然后为每个词生成嵌入。这些嵌入捕捉了句子中词之间的语义关系。代码输出如下:
Embedding for 'I': [-0.019782520.02348454 -0.0405227-0.018061030.00496107] Embedding for 'love': [ 0.01147135 -0.00716509 -0.023199190.03274594 -0.00713439] Embedding for 'natural': [ 0.033190940.025706180.02645341 -0.00284445 -0.01343429] Embedding for 'language': [-0.01165106 -0.02851446 -0.01676577 -0.01542572 -0.02357706]
每一行对应一个词的嵌入向量,例如“love”的向量是[-0.01978252 0.02348454 -0.0405227 -0.01806103 0.00496107]。RAG正是利用这种文本嵌入来理解输入查询的上下文,并提取相关信息。

接下来可以尝试用预训练模型(比如BERT)对输入查询进行标记和编码,把查询转换成捕捉其语义和上下文的数字表示:
# Code Implementation: Tokenization and Encoding
from transformers import BertTokenizer, BertModel
# Initialize BERT tokenizer and model
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')
# Tokenize and encode the input query
query = "What is the capital of France?"
input_ids = tokenizer.encode(query, add_special_tokens=True, return_tensors="pt")
用BERT对输入查询进行标记并编码成数字ID。由于涉及加载大型预训练模型,这个过程的输出包括:input_ids(令牌的数字ID)、attention_mask(指示哪些令牌是实际单词,哪些是填充)、token_type_ids(在多片段情况下区分所属句子)。示例输出如下:
{
'input_ids': tensor([[101,2054,2003,1996,3007,1997,2605,1029, 102, 0]]),
'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 0]]),
'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
}
有了编码后的查询,就可以从语料库中检索相关段落了。这里用余弦相似度来计算查询嵌入和段落嵌入之间的相似度:
# Code Implementation: Retrieval and Similarity Matching from sklearn.metrics.pairwise import cosine_similarity # Retrieve passages and compute similarity scores query_embedding = model(input_ids)[0].mean(dim=1).detach().numpy() passage_embeddings = ...# Retrieve passage embeddings similarity_scores = cosine_similarity(query_embedding, passage_embeddings)
选择相似度最高的段落,连同分数一起输出。分数越高,表示段落与查询越相关。在RAG模型中,得分最高的段落会被视为最相关的信息,用于后续生成:
# Select passage with highest similarity score
max_similarity_index = np.argmax(similarity_scores)
selected_passage = passages[max_similarity_index]
# Output selected passage and similarity score
print("Selected Passage:")
print(selected_passage)
print("Similarity Score:", similarity_scores[0][max_similarity_index])
文本嵌入是NLP中强大的工具,能够高效理解和处理文本信息。它们在问答、文本生成、情绪分析等任务中发挥着重要作用。通过把文本嵌入用到RAG里,可以提升性能和精度,从而获得更准确、上下文更一致的响应。
知识图谱嵌入的RAG
下面来聊聊如何定义和实现知识图谱嵌入——从非结构化数据中提取结构化的知识表示。
知识图谱是一种非常高效的信息组织方式——它将实体及其关系以有意义的方式连接起来。就像一个组织良好的信息仓库,捕捉现实世界中物体和它们之间的联系。不过,构建知识图谱只是第一步,要释放它的全部潜力,还得探索知识图谱嵌入。
为了演示,我们保持KG的基本结构,但简化了组件的使用。先把KG元素表示为嵌入,然后用评分函数来评估三元组的合理性,比如“Tim”、“is an”、“Artist”。知识图谱嵌入的实现步骤如下:

给定一段非结构化文本,首先用斯坦福的OpenIE框架提取关键实体、关系和属性。提取出三元组后,进行清洗和调整:
from openie import StanfordOpenIE
text = "Hawaii is a state in the United States. Barack Obama served as the 44th president of the United States. The Louvre Museum is located in Paris, France."
with StanfordOpenIE() as client:
triples = client.annotate(text)
for triple in triples:
print(triple)
cleaned_triples = [(subject.lower(), relation.lower(), object.lower()) for (subject, relation, object) in triples]
print("Cleaned Triples:", cleaned_triples)
输出如下:
('Hawaii', 'is', 'a state in the United States')
('Barack Obama', 'served as', 'the 44th president of the United States')
('The Louvre Museum', 'is located in', 'Paris, France')
Cleaned Triples: [('hawaii', 'is', 'a state in the united states'), ('barack obama', 'served as', 'the 44th president of the united states'), ('the louvre museum', 'is located in', 'paris, france')]
现在可以用这些信息构建知识图谱。使用NetworkX框架,实体→节点,关系→边:
import networkx as nx # Create a directed graph knowledge_graph = nx.DiGraph() # Add nodes and edges from cleaned triples for (subject, relation, object) in cleaned_triples: knowledge_graph.add_edge(subject, object, relation=relation) # Visualize the knowledge graph nx.draw(knowledge_graph, with_labels=True)
实体解析在各种NLP应用中至关重要,比如信息抽取、问答、知识图谱构建等。它能把文本中提到的实体准确对应到结构化知识表示中的相应实体,使机器更有效地理解和推理自然语言。实体解析的核心挑战是自然语言中的歧义和可变性——同一个实体可能有不同名称、同义词、缩写或变体,比如“巴拉克·奥巴马”可能被说成“奥巴马”“美国前总统”或“他”;而“Paris”可能指法国首都或其他同名地点。
几种常见的实体解析技术包括:
精确匹配:如果文本中提到“Hawaii”,可以直接链接到图中标记为“Hawaii”的节点。
部分匹配:如果文本提到“USA”而非“United States”,部分匹配算法可识别两者相似性,链接到“United States”节点。
命名实体识别(NER):系统将“巴拉克·奥巴马”识别为个人实体,然后链接到图中对应节点。
共同引用解析:如果文本说“他曾担任总统”,解析器可将“他”链接回前面的“巴拉克·奥巴马”,再关联到图节点。
消歧义:遇到“Paris”时,根据上下文或外部知识判断是“Paris, France”还是其他,再链接到对应节点。
一旦确定了正确的实体链接,文本中的提及就会连接到知识库或知识图中。评估实体解析系统的性能常用精确率、召回率和F1分数。下图展示了上面构造的图的实体解析示例,灰色圆圈表示给定实体的类类型解析。
最后一步,为实体和关系生成嵌入。这里使用TransE模型:
from pykeen.pipeline import pipeline
# Define pipeline configuration
pipeline_config = {
"dataset": "nations",
"model": {
"name": "TransE",
"embedding_dim": 50
},
"training": {
"num_epochs": 100,
"learning_rate": 0.01
}
}
# Create and run pipeline
result = pipeline(
**pipeline_config,
random_seed=1234,
use_testing_data=True
)
# Access trained embeddings
entity_embeddings = result.model.entity_embeddings
relation_embeddings = result.model.relation_embeddings
# Print embeddings
print("Entity Embeddings:", entity_embeddings)
print("Relation Embeddings:", relation_embeddings)
输出结果:
Entity Embeddings: [Embedding dimension: (120, 50)] Relation Embeddings: [Embedding dimension: (120, 50)]
文本和知识图谱进行整合
在组合这些嵌入之前,先理清它们的目标,并验证它们是否互补。
文本嵌入和知识图谱嵌入在NLP中有不同用途,代表语言和语义的不同方面。文本嵌入捕捉单个词或短语的语义,知识嵌入捕捉实体之间的明确关系。将两者集成,RAG模型就能更全面地掌握输入文本和知识图中的结构化信息。
下面通过代码,把文本嵌入和知识嵌入组合到同一个嵌入空间,然后根据查询和段落的组合嵌入之间的余弦相似度,从知识库中检索相关段落:
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
# Sample knowledge embeddings
knowledge_embeddings = { } #initialise the above knowledge embeddgings output
# Sample text embeddings
text_embeddings = { } #initialise the above text embeddgings output
# Consider passages from knowledge base
knowledge_base = {
"Passage 1": "Hawaii is a state in the United States.",
"Passage 2": "Barack Obama served as the 44th president of the United States.",
# Add more passages as needed
}
# Function to combine text and knowledge embeddings
def combine_embeddings(text_emb, know_emb):
combined_emb = {}
for entity, t_emb in text_emb.items():
if entity in know_emb:
combined_emb[entity] = np.concatenate([t_emb, know_emb[entity]])
else:
combined_emb[entity] = t_emb
return combined_emb
# Function to retrieve relevant passages using combined embeddings
def retrieve_passages(query_emb, knowledge_base_emb):
similarities = {}
for passage, kb_emb in knowledge_base_emb.items():
sim = cosine_similarity([query_emb], [kb_emb])[0][0]
similarities[passage] = sim
sorted_passages = sorted(similarities.items(), key=lambda x: x[1], reverse=True)
return sorted_passages
# Example usage
combined_embeddings = combine_embeddings(text_embeddings, knowledge_embeddings)
query = "query"
relevant_passages = retrieve_passages(combined_embeddings[query], knowledge_embeddings)
# Print relevant passages
for passage, similarity in relevant_passages:
print("Passage:", passage)
print("Similarity:", similarity)
输出如下:
Passage: Passage 1 Similarity: 0.946943628930774 Passage: Passage 2 Similarity: 0.9397945401928656
总结
在RAG中同时使用文本嵌入和知识嵌入,可以从多个层面增强模型性能和能力:
1. 更全面的表示:文本嵌入捕捉单个词或短语的语义,知识嵌入捕捉实体间的明确关系。两者集成使RAG模型能更完整地把握输入文本和知识图的结构化信息。
2. 上下文相关性提升:文本嵌入通过词共现提供上下文见解,知识嵌入通过图中关系提供上下文相关性。组合后,模型能够生成同时满足语义相关和结构化知识一致的响应。
3. 答案选择的精准度:在检索组件中集成知识嵌入,能显著提高答案选择的质量。利用知识嵌入对知识库中的段落进行索引和检索,模型不仅能检索出更准确的响应,而且信息更丰富。
4. 生成质量增强:文本嵌入带来广泛的语言特征和语义细微差别,知识嵌入提供结构化知识基础。两者结合,使模型生成的语言更流畅、语义更相关,且有扎实的知识支撑。
5. 对歧义的鲁棒性:文本嵌入捕捉非结构化文本中的可变性和模糊性,知识嵌入提供明确语义关系来增强和澄清理解。模型因此获得更强的抗歧义能力。
6. 结构化知识的无缝融合:知识嵌入让RAG模型将知识库的结构化知识直接集成到生成过程中。通过整合两种嵌入,模型实现了结构化知识与非结构化文本的平滑融合,最终输出更丰富、上下文更相关的响应。
总而言之,在RAG模型中同时使用文本嵌入和知识嵌入,能对输入文本和结构化知识进行更全面、更丰富的表示。这种集成增强了答案检索、答案生成、对歧义的鲁棒性以及结构化知识的有效利用,最终得到更准确、信息量更大的响应。
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名