首页 > 教程攻略 > ai资讯 >整合文本和知识图谱嵌入提升RAG的性能

整合文本和知识图谱嵌入提升RAG的性能

来源:互联网 时间:2026-08-03 14:11:45

此前已经介绍过将知识图谱与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模型中同时使用文本嵌入和知识嵌入,能对输入文本和结构化知识进行更全面、更丰富的表示。这种集成增强了答案检索、答案生成、对歧义的鲁棒性以及结构化知识的有效利用,最终得到更准确、信息量更大的响应。