高效打造知識圖譜,使用LlamaIndex Relik實現實體關聯和關系抽取 精華
文本信息轉化為知識圖譜的技術,自問世以來一直是研究界的寵兒。大型語言模型(LLMs)的興起讓這個領域受到更多關注,但LLMs的成本之高令人卻步。然而,通過對小型模型微調優化,我們可以找到一種更經濟高效的解決方案。
今天向大家介紹Relik,這是由羅馬大學(Sapienza University of Rome)自然語言處理團隊精心研發的快速、輕量級信息提取框架。
1 信息提取流程
在不依賴LLMs的情況下,信息提取流程通常包括:
上圖呈現了信息提取的完整流程。始于一段簡單的文本輸入:“Tomaz likes to write blog posts. He is particularly interested in drawing diagrams.”。流程首先進行指代消解,將“Tomaz”和“He”識別為同一人。緊接著,命名實體識別(NER)技術辨識出“Tomaz”、“Blog”和“Diagram”等關鍵實體。
隨后,實體鏈接環節將這些識別出的實體與數據庫或知識庫中的相應條目相對應。例如,“Tomaz”對應到“Tomaz Bratanic (Q12345)”,“Blog”對應到“Blog (Q321)”。然而,"Diagram"在知識庫中未找到匹配項。
接下來,關系提取步驟進一步分析實體間的聯系,如識別出“Tomaz”與“Blog”之間存在“WRITES”關系,說明Tomaz撰寫博客;“Tomaz”與“Diagram”之間存在“INTERESTED_IN”關系,表明他對圖表有興趣。
最后,這些經過結構化的實體和關系信息被整合進知識圖譜中,為后續的數據分析或信息檢索提供了有序且易于訪問的資源。
在沒有大型語言模型(LLMs)支持的情況下,信息提取工作通常依賴一系列專業模型來分別處理指代消解、命名實體識別、實體鏈接和關系提取等任務。整合這些模型需要付出額外的工作和細致的調整,但這種方法能夠有效降低成本。通過使用和優化這些小型、特定任務的模型,可以在整體上減少系統的構建和維護成本。
代碼可在 GitHub 上獲取:https://github.com/tomasonjo/blogs/blob/master/llm/llama_relik.ipynb
2 環境搭建與數據準備
推薦使用獨立的Python環境,例如Google Colab,以便管理項目依賴項。
接下來配置Neo4j圖數據庫以存儲解析出的數據。推薦使用Neo4j Aura(https://neo4j.com/cloud/platform/aura-graph-database/),它提供便捷的免費云服務,且與Google Colab筆記本完美兼容。
完成數據庫的搭建后,可通過LlamaIndex建立數據庫連接。
from llama_index.graph_stores.neo4j import Neo4jPGStore
username="neo4j"
password="rubber-cuffs-radiator"
url="bolt://54.89.19.156:7687"
graph_store = Neo4jPGStore(
username=username,
password=password,
url=url,
refresh_schema=False
)
數據集
這里使用一個新聞數據集進行分析,這個數據集是通過Diffbot API(https://www.diffbot.com/data/article/)獲取的。
import pandas as pd
NUMBER_OF_ARTICLES = 100
news = pd.read_csv(
"https://raw.githubusercontent.com/tomasonjo/blog-datasets/main/news_articles.csv"
)
news = news.head(NUMBER_OF_ARTICLES)
3 技術實現
信息提取流程首先從指代消解著手,其任務是識別文本中指代相同實體的不同表述。
據了解,目前可用于指代消解的開源模型相對較少。經過嘗試比較,這里選擇使用spaCy的Coreferee(https://spacy.io/universe/project/coreferee)。需要注意的是,使用Coreferee可能會遇到一些依賴性問題。
加載spaCy中的指代消解模型,使用以下代碼實現:
import spacy, coreferee
coref_nlp = spacy.load('en_core_web_lg')
coref_nlp.add_pipe('coreferee')
Coreferee模型能夠識別文本中指代相同實體或實體組的表達式集群。為了根據這些識別出的集群對文本進行重寫,需要自定義函數來實現這一過程。
def coref_text(text):
coref_doc = coref_nlp(text)
resolved_text = ""
for token in coref_doc:
repres = coref_doc._.coref_chains.resolve(token)
if repres:
resolved_text += " " + "and".join(
[
t.text
if t.ent_type_ == ""
else [e.text for e in coref_doc.ents if t in e][0]
for t in repres
]
)
else:
resolved_text += " " + token.text
return resolved_text
測試下這個函數,確保模型和依賴項設置正確:
print(
coref_text("Tomaz is so cool. He can solve various Python dependencies and not cry")
)
在這個例子中,模型成功識別出“Tomaz”和“He”實際上指向同一實體。通過應用coref_text函數,將“Tomaz”替換“He”。
請注意,這種重寫機制并不總能生成完全符合語法規則的句子,因為它采用了一種直接的替換邏輯來處理文本中的實體集群。盡管如此,對于大多數應用場景,這種方法已經足夠有效。
現在把這一指代消解技術應用于我們的新聞數據集,并將其轉換為LlamaIndex文檔格式:
from llama_index.core import Document
news["coref_text"] = news["text"].apply(coref_text)
documents = [
Document(text=f"{row['title']}: {row['coref_text']}")
for i, row in news.iterrows()
]
實體鏈接和關系提取
Relik庫集成了實體鏈接和關系提取兩大功能,能夠將這兩種技術融合應用。實體鏈接時,Relik以維基百科為依托,實現文本實體與百科條目的精準對應。
將實體鏈接到維基百科
在關系提取方面,Relik通過辨識和定義文本中實體間的關系,幫助我們將原始的非結構化數據轉化為有序的結構化信息。
關系提取
如果你使用的是Colab的免費版本,請選擇relik-ie/relik-relation-extraction-small模型,這個模型專門負責關系提取。如果有Colab Pro版本,或者打算在本地更高性能的機器上運行,那么可以嘗試relik-ie/relik-cie-small模型,它不僅包含關系提取,還能進行實體鏈接的功能。
from llama_index.extractors.relik.base import RelikPathExtractor
relik = RelikPathExtractor(
model="relik-ie/relik-relation-extraction-small"
)
# 在Pro Collab上使用GPU
# relik = RelikPathExtractor(
# model="relik-ie/relik-cie-small", model_cnotallow={"skip_metadata": True, "device":"cuda"}
# )
此外,我們必須定義將用于嵌入實體的嵌入模型,以及用于問答流程的LLM:
import os
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.llms.openai import OpenAI
os.environ["OPENAI_API_KEY"] = "sk-"
llm = OpenAI(model="gpt-4o", temperature=0.0)
embed_model = OpenAIEmbedding(model_name="text-embedding-3-small")
注意在構建知識圖譜的過程中,不會使用大型語言模型(LLM)。
4 知識圖譜的構建與應用
目前,一切準備工作已經就緒。接下來,可以創建PropertyGraphIndex實例,并將新聞文檔作為數據輸入,整合進知識圖譜中。
此外,為了提取文檔中的關系,需要將relik模型設置為kg_extractors參數的值。
from llama_index.core import PropertyGraphIndex
index = PropertyGraphIndex.from_documents(
documents,
kg_extractors=[relik],
llm=llm,
embed_model=embed_model,
property_graph_store=graph_store,
show_progress=True,
)
構建圖后,可以打開Neo4j瀏覽器來驗證導入的圖。通過運行以下Cypher語句獲得類似的可視化:
MATCH p=(:__Entity__)--(:__Entity__)
RETURN p LIMIT 250
結果:
5 問答功能實現
使用LlamaIndex,現在可以輕松地進行問答。只需利用系統自帶的圖檢索器,便能夠直接提出問題:
query_engine = index.as_query_engine(include_text=True)
response = query_engine.query("What happened at Ryanair?")
print(str(response))
這就是定義的 LLM 和嵌入模型發揮作用的地方。
6 總結
不依賴大型語言模型構建知識圖譜是切實可行,具有成本效益且效率高。通過優化調整如Relik框架中的小型、任務專精的模型,檢索增強型生成應用便能高效提取信息。
實體鏈接作為關鍵步驟,確保了識別出的實體能夠準確映射到知識庫中的對應條目,從而維持了知識圖譜的完整性與實用性。
借助Relik框架和Neo4j平臺,我們能夠構建出功能強大的知識圖譜,這些圖譜可以助力復雜的數據分析和檢索任務,而且避免了部署大型語言模型所帶來的高昂成本。這種方法不僅讓先進的數據處理工具變得更加親民,也推動了信息提取流程的創新與效率。
本文轉載自 ??AI科技論談??,作者:小AI
