整合文本和知識圖譜嵌入提升RAG的性能
共 11412字,需瀏覽 23分鐘
·
2024-05-19 17:37
來源:DeepHub IMBA 本文約4600字,建議閱讀10分鐘
本文中我們將文本和知識圖譜結合,來提升我們RAG的性能。
我們以前的文章中介紹過將知識圖譜與RAG結合的示例,在本篇文章中我們將文本和知識圖譜結合,來提升我們RAG的性能。
文本嵌入的RAG
文本嵌入是單詞或短語的數(shù)字表示,可以有效地捕捉它們的含義和上下文。可以將它們視為單詞的唯一標識符——捕獲它們所代表的單詞的含義的簡潔向量。這些嵌入使計算機能夠增強對文本的理解和處理,使它們能夠在各種NLP任務中脫穎而出,例如文本分類、情感分析和機器翻譯。
可以利用預先訓練的模型,如Word2Vec、GloVe或BERT來生成文本嵌入。這些模型已經在大量文本數(shù)據(jù)上進行了廣泛的訓練,并且已經獲得了對單詞及其關系的語義信息進行編碼的能力。
讓我們使用一個簡單的Python代碼片段(word2vec)來探索生成文本嵌入的過程:
# Code Implementation: Generating Text Embeddingsimport numpy as npfrom gensim.models import Word2Vec# Sample sentencessentences = [["I", "love", "natural", "language", "processing"],["Text", "embeddings", "are", "fascinating"],["NLP", "makes", "computers", "understand", "language"]]# Train Word2Vec modelmodel = Word2Vec(sentences, vector_size=5, window=5, min_count=1, sg=1)# Get embeddings for wordsword_embeddings = {}for word in model.wv.index_to_key:word_embeddings[word] = model.wv[word]# Print embeddingsfor word, embedding in word_embeddings.items():print(f"Embedding for '{word}': {embedding}")
在這段代碼中,我們通過對一組示例句子進行訓練來開發(fā)一個Word2Vec模型。然后模型為每個單詞生成嵌入。這些嵌入捕獲句子中單詞之間的語義關系。使用Word2Vec生成文本嵌入的代碼片段輸出如下:
Embedding for 'I': [-0.01978252 0.02348454 -0.0405227 -0.01806103 0.00496107]Embedding for 'love': [ 0.01147135 -0.00716509 -0.02319919 0.03274594 -0.00713439]Embedding for 'natural': [ 0.03319094 0.02570618 0.02645341 -0.00284445 -0.01343429]Embedding for 'language': [-0.01165106 -0.02851446 -0.01676577 -0.01542572 -0.02357706]
在上面的輸出中:
每一行對應一個詞的嵌入向量。每行以單詞開頭,然后是表示為數(shù)值列表的嵌入向量。例如,單詞“l(fā)ove”的嵌入:[-0.01978252 0.02348454 -0.0405227 -0.01806103 0.00496107]。
RAGs利用文本嵌入來掌握輸入查詢的上下文并提取相關信息。
現(xiàn)在讓我們嘗試使用預訓練的模型(如BERT)對輸入查詢進行標記和編碼。這將查詢轉換為捕獲其語義和上下文的數(shù)字表示形式。
# Code Implementation: Tokenization and Encodingfrom transformers import BertTokenizer, BertModel# Initialize BERT tokenizer and modeltokenizer = BertTokenizer.from_pretrained('bert-base-uncased')model = BertModel.from_pretrained('bert-base-uncased')# Tokenize and encode the input queryquery = "What is the capital of France?"input_ids = tokenizer.encode(query, add_special_tokens=True, return_tensors="pt")
我們使用BERT對輸入查詢進行標記并將其編碼為數(shù)字id。由于BERT模型初始化和標記化過程涉及加載一個大型預訓練模型,因此標記化和編碼步驟的輸出包括以下組件:
id:這些是輸入查詢中令牌的數(shù)字表示形式。每個令牌都被轉換成一個ID,該ID對應于BERT詞匯表中的索引。
注意力掩碼:這是一個二進制掩碼,指示哪些令牌是實際的單詞(1),哪些是填充令牌(0)。它確保模型在處理過程中只關注真實的令牌。
令牌類型id(對于像BERT這樣的模型):在多個片段的情況下,每個令牌屬于哪個片段或句子。對于單句輸入,所有令牌類型id通常設置為0。
輸出是包含這些組件的字典,可以將其用作BERT模型的輸入以進行進一步處理。
下面是輸出內容的示例:
{'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]])}
input_ids包含輸入查詢中令牌的數(shù)字id。Attention_mask指示哪些令牌是實際單詞(1),哪些是填充令牌(0)。Token_type_ids表示每個令牌所屬的片段或句子(本例中第一個句子為0)。
接下來,就可以根據(jù)編碼查詢從語料庫中檢索相關段落。我們使用余弦相似度計算查詢嵌入和段落嵌入之間的相似度分數(shù)。
# Code Implementation: Retrieval and Similarity Matchingfrom sklearn.metrics.pairwise import cosine_similarity# Retrieve passages and compute similarity scoresquery_embedding = model(input_ids)[0].mean(dim=1).detach().numpy()passage_embeddings = ... # Retrieve passage embeddingssimilarity_scores = cosine_similarity(query_embedding, passage_embeddings)
選擇相似度得分最高的文章,并將其與相似度得分一起輸出。相似度分數(shù)表示每個段落與輸入查詢之間的相似度,分數(shù)越高表示相似度越高。在RAG模型中,獲得最高相似性分數(shù)的文章被認為是與進一步處理最相關的。
最后我們將相似度得分最高的文章指定為最相關的文章。這一段為模型的生成階段提供了相關的信息。
# Select passage with highest similarity scoremax_similarity_index = np.argmax(similarity_scores)selected_passage = passages[max_similarity_index]# Output selected passage and similarity scoreprint("Selected Passage:")print(selected_passage)print("Similarity Score:", similarity_scores[0][max_similarity_index])
文本嵌入是自然語言處理(NLP)領域中非常強大的工具,它可以有效地理解和處理文本信息。它們對很多任務都有重要的影響,比如回答問題、生成文本和分析情緒。通過在RAG中使用文本嵌入,可以提高性能和精度,從而得到更加準確且符合上下文的響應。
知識圖譜嵌入的RAG
下面我們介紹如何定義和實現(xiàn)知識圖譜嵌入,從非結構化數(shù)據(jù)中表示結構域構造。
知識圖譜是組織信息、以有意義的方式連接實體及其關系的一種非常有效的方式。這些圖就像一個組織良好的信息倉庫,捕捉現(xiàn)實世界中物體的意義及其聯(lián)系。然而,這個過程并沒有隨著知識圖譜的發(fā)展而結束。探索知識圖譜嵌入領域對于釋放其全部潛力至關重要。
為了演示我們保持了KG的基本結構,但是簡化了KG組件的使用。在將KG元素表示為嵌入后,使用評分函數(shù)來評估三元組的合理性,例如“Tim”、“is an”、“Artist”。
以下是實現(xiàn)知識(圖)嵌入的步驟:
給定一個非結構化文本,我們首先將使用斯坦福大學的OpenIE框架提取關鍵實體、關系和屬性。一旦三元組被提取出來,我們就可以清理/調整它們。
from openie import StanfordOpenIEtext = "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')]
現(xiàn)在可以使用這些信息創(chuàng)建一個知識圖譜,使用NetworkX框架構造一個具有實體→節(jié)點和關系→邊的知識圖。下面是實現(xiàn):
import networkx as nx# Create a directed graphknowledge_graph = nx.DiGraph()# Add nodes and edges from cleaned triplesfor (subject, relation, object) in cleaned_triples:knowledge_graph.add_edge(subject, object, relation=relation)# Visualize the knowledge graphnx.draw(knowledge_graph, with_labels=True)
實體解析在各種NLP應用中起著關鍵作用,包括信息提取、問題回答、知識圖譜構建等。通過準確地將文本中實體的提及與結構化知識表示中的相應實體聯(lián)系起來,實體解析使機器能夠更有效地使用自然語言理解和推理,從而促進了廣泛的下游任務和應用。
實體解析解決了自然語言中模糊性和可變性的挑戰(zhàn)。在日常語言使用中,經常使用不同的名稱、同義詞、縮寫或變體來指代人員、位置、組織和概念等實體。例如,“巴拉克·奧巴馬”可能會被說成“奧巴馬”、“美國前總統(tǒng)”或簡單地說成“他”。另外也可能存在具有相似名稱或屬性的實體,從而導致潛在的混淆或歧義。例如,“Paris”可以指法國的首都,也可以指同名的其他地方。
我們簡單介紹每種實體解析技術:
精確匹配:在文本中,提到“Hawaii”可以直接鏈接到圖中標記為“Hawaii”的節(jié)點,因為它們完全匹配。
部分匹配:如果文本提到“USA”而不是“United States”,部分匹配算法可能會識別兩者之間的相似性,并將提及鏈接到圖中標記為“United States”的節(jié)點。
命名實體識別(NER):使用NER,系統(tǒng)可以將“巴拉克·奧巴馬”識別為文本中提到的個人實體。然后這個提及可以鏈接到圖中標記為“巴拉克?奧巴馬”的相應節(jié)點。
共同引用解析:如果文本提到“他曾擔任總統(tǒng)”,共同引用解析可以將“他”鏈接回文本前面提到的“巴拉克·奧巴馬”,然后將其鏈接到圖中標記為“巴拉克·奧巴馬”的相應節(jié)點。
消歧義:假設文本提到了“Paris”,但沒有指定它指的是法國的城市還是其他地方。消歧技術可能會考慮上下文信息或外部知識來源,以確定它指的是“Paris, France”,并將其鏈接到圖中相應的節(jié)點。
一旦確定了正確的實體鏈接,文本中的提及就會鏈接到知識庫或知識圖中相應的實體。實體解析系統(tǒng)的性能使用精度、召回率和f1分數(shù)等指標進行評估,并將預測的實體鏈接與基本事實或標準進行比較。下面給出了上面構造的圖的實體解析示例。灰色圓圈表示給定實體的類類型解析。
作為最后一步,我們現(xiàn)在將為實體和關系生成嵌入。我們這里使用TransE。
from pykeen.pipeline import pipeline# Define pipeline configurationpipeline_config = {"dataset": "nations","model": {"name": "TransE","embedding_dim": 50},"training": {"num_epochs": 100,"learning_rate": 0.01}}# Create and run pipelineresult = pipeline(**pipeline_config,random_seed=1234,use_testing_data=True)# Access trained embeddingsentity_embeddings = result.model.entity_embeddingsrelation_embeddings = result.model.relation_embeddings# Print embeddingsprint("Entity Embeddings:", entity_embeddings)print("Relation Embeddings:", relation_embeddings)
得到的輸出如下:
Entity Embeddings: [Embedding dimension: (120, 50)]Relation Embeddings: [Embedding dimension: (120, 50)]
文本和知識圖譜進行整合
在我們組合這些嵌入之前,要首先了解這些嵌入的目標,并驗證它們是否完全互補。
文本嵌入和知識圖譜嵌入在自然語言處理(NLP)中有著不同的用途,它們代表了語言和語義信息的不同方面。
我們下面的代碼通過將文本嵌入和知識嵌入組合到單個嵌入空間中來集成文本嵌入和知識嵌入,然后根據(jù)查詢和段落的組合嵌入之間的余弦相似度從知識庫中檢索相關段落。輸出顯示相關的段落以及它們與查詢的相似度得分。
import numpy as npfrom sklearn.metrics.pairwise import cosine_similarity# Sample knowledge embeddingsknowledge_embeddings = { } #initialise the above knowledge embeddgings output# Sample text embeddingstext_embeddings = { } #initialise the above text embeddgings output# Consider passages from knowledge baseknowledge_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 embeddingsdef 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_embreturn combined_emb# Function to retrieve relevant passages using combined embeddingsdef 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] = simsorted_passages = sorted(similarities.items(), key=lambda x: x[1], reverse=True)return sorted_passages# Example usagecombined_embeddings = combine_embeddings(text_embeddings, knowledge_embeddings)query = "query"relevant_passages = retrieve_passages(combined_embeddings[query], knowledge_embeddings)# Print relevant passagesfor passage, similarity in relevant_passages:print("Passage:", passage)print("Similarity:", similarity)
輸出如下:
Passage: Passage 1Similarity: 0.946943628930774Passage: Passage 2Similarity: 0.9397945401928656
總結
在(RAG)中同時使用文本嵌入和知識嵌入可以從幾個方面增強模型的性能和能力:
1. 文本嵌入捕獲單個單詞或短語的語義,而知識嵌入捕獲實體之間的明確關系。通過兩種嵌入的集成,RAG模型實現(xiàn)了對輸入文本和存儲在知識圖中的組織信息的更全面的把握。
2. 文本嵌入通過分析輸入文本中的詞共現(xiàn)提供有價值的上下文見解,而知識嵌入通過檢查知識圖中實體之間的關系提供上下文相關性。通過組合不同類型的嵌入,RAG模型能夠生成與輸入文本在語義上相關且在上下文中與結構化知識一致的響應。
3. 由于在檢索組件中集成了知識嵌入,在RAG模型中利用結構化知識可以顯著提高答案選擇。利用知識嵌入對知識庫中的相關段落進行索引和檢索,RAG模型不僅能夠檢索出更準確的響應,而且具有更豐富的信息。
4. 文本嵌入通過結合廣泛的語言特征和語義細微差別來增強RAG模型的生成組件。通過在答案生成過程中整合文本嵌入和知識嵌入,RAG模型能夠生成語言流暢性、語義相關性和結構化知識堅實基礎的回答。
5. 通過使用文本嵌入和知識嵌入,RAG模型獲得了對自然語言中模糊性和可變性的增強彈性。文本嵌入捕獲非結構化文本中存在的可變性和模糊性,而知識嵌入提供明確的語義關系,以增強和澄清模型的理解。
6、知識嵌入允許RAG模型無縫地將來自知識庫的結構化知識集成到生成過程中。通過知識嵌入和文本嵌入的集成,RAG模型實現(xiàn)了結構化知識和非結構化文本的無縫融合,從而獲得更豐富的信息和上下文相關的響應。
在RAG模型中,文本嵌入和知識嵌入都允許對輸入文本和結構化知識進行更全面、上下文更豐富的表示。這種集成增強了模型在答案檢索、答案生成、對歧義的魯棒性和結構化知識的有效結合方面的性能,最終導致更準確和信息豐富的響應。
編輯:黃繼彥
