利用 LlamaIndex 和 Python,我們可以有效地構建知識圖譜索引,並結合相似度計算和排序演算法,打造高效的查詢引擎。首先,透過 LlamaIndex 將檔案轉換為圖形結構,並建立索引以供後續查詢。接著,使用 NetworkX 視覺化圖形結構,方便理解索引分佈。透過定義使用者提示和超引數,可以精確控制查詢過程。利用 sentence-transformers 等相似性評分套件,計算查詢結果和檔案的相似度,並根據分數重新排序結果,提升查詢的準確性和相關性。最後,透過評估樣本和指標計算,可以客觀評估查詢引擎的效能。

步驟1:生成知識圖索引

首先,我們需要建立一個知識圖索引。這個過程可能需要一些時間,因此我們使用 time 函式來測量建立索引的時間:

import time

# 啟動計時器
start_time = time.time()

接下來,我們可以使用 LlamaIndex 來建立知識圖索引。這個過程涉及將檔案轉換為圖形結構,並建立索引以便於查詢。

內容解密:

import llama_index

# 建立知識圖索引
index = llama_index.create_index(documents)

在這個例子中,documents 是一個包含多個檔案的列表。每個檔案都需要被轉換為圖形結構,以便於建立索引。

步驟2:顯示圖形

建立索引後,我們可以使用 networkx 來顯示圖形結構:

import networkx as nx

# 顯示圖形
G = nx.Graph()
G.add_nodes_from(index.nodes)
G.add_edges_from(index.edges)
nx.draw(G, with_labels=True)

這個過程可以幫助我們瞭解圖形的結構和索引的分佈。

步驟3:定義使用者提示

接下來,我們需要定義使用者提示。這個提示將被用於查詢索引:

prompt = "What is the meaning of life?"

步驟4:定義超引數

我們需要定義超引數以控制索引的查詢過程:

hyperparams = {"top_k": 5, "threshold": 0.5}

這些超引數將被用於控制查詢的結果。

圖表翻譯:

  graph LR
    A[使用者提示] --> B[索引查詢]
    B --> C[查詢結果]
    C --> D[排名]
    D --> E[輸出]

這個圖表顯示了查詢過程的流程。

步驟5:安裝相似性評分套件

我們需要安裝相似性評分套件以計算查詢結果的相似性:

import similarity

步驟6:定義相似性評分函式

我們需要定義相似性評分函式以計算查詢結果的相似性:

def similarity_score(query, document):
    # 計算相似性評分
    return similarity.cosine_similarity(query, document)

內容解密:

# 計算查詢結果的相似性評分
scores = [similarity_score(prompt, doc) for doc in documents]

這個過程可以幫助我們瞭解查詢結果的相似性。

步驟7:執行樣本相似性比較

我們可以執行樣本相似性比較以評估相似性評分函式的效果:

# 執行樣本相似性比較
sample_query = "What is the meaning of life?"
sample_documents = [doc1, doc2, doc3]
scores = [similarity_score(sample_query, doc) for doc in sample_documents]

圖表翻譯:

  graph LR
    A[樣本查詢] --> B[樣本檔案]
    B --> C[相似性評分]
    C --> D[排名]
    D --> E[輸出]

這個圖表顯示了樣本相似性比較的流程。

步驟8:重新排名輸出向量

我們可以重新排名輸出向量以改善查詢結果的相關性:

# 重新排名輸出向量
ranked_scores = sorted(scores, reverse=True)

步驟9:執行評估樣本和應用metrics和人工反饋評分

我們可以執行評估樣本和應用metrics和人工反饋評分以評估查詢結果的品質:

# 執行評估樣本和應用metrics和人工反饋評分
evaluation_samples = [sample_query, sample_documents]
metrics = [precision, recall, f1_score]
human_feedback_scores = [0.8, 0.9, 0.7]

內容解密:

# 計算metrics和人工反饋評分
metrics_scores = [metric(evaluation_samples) for metric in metrics]
human_feedback_scores = [score(evaluation_samples) for score in human_feedback_scores]

這個過程可以幫助我們瞭解查詢結果的品質。

步驟10:執行metric計算和顯示metrics

最後,我們可以執行metric計算和顯示metrics以評估查詢結果的品質:

# 執行metric計算和顯示metrics
metric_calculations = [metric(evaluation_samples) for metric in metrics]
print(metric_calculations)

這個過程可以幫助我們瞭解查詢結果的品質。

圖表翻譯:

  graph LR
    A[查詢結果] --> B[metric計算]
    B --> C[顯示metrics]
    C --> D[輸出]

這個圖表顯示了metric計算和顯示metrics的流程。

透過這些步驟,我們可以建立一個知識圖索引,並使用它來查詢和排名檔案。同時,我們也可以使用相似性評分函式和metric計算來評估查詢結果的品質。

建立知識圖索引與查詢引擎

在本文中,我們將建立一個知識圖索引,並使用它來查詢相關資訊。首先,我們需要建立一個知識圖索引,該索引包含從檔案中提取的嵌入式向量。

import time
from knowledge_graph_index import KnowledgeGraphIndex

# 計時開始
start_time = time.time()

# 建立知識圖索引
documents = [...]  # 檔案集合
max_triplets_per_chunk = 2  # 每個 chunk 的三元組數量上限
include_embeddings = True  # 是否包含嵌入式向量

graph_index = KnowledgeGraphIndex.from_documents(
    documents,
    max_triplets_per_chunk=max_triplets_per_chunk,
    include_embeddings=include_embeddings,
)

# 計時結束
end_time = time.time()

# 計算並列印索引建立時間
elapsed_time = end_time - start_time
print(f"索引建立時間:{elapsed_time:.4f} 秒")

print(type(graph_index))

輸出結果顯示索引建立時間約為 371.9844 秒,且 graph_index 的型別為 KnowledgeGraphIndex

接下來,我們需要設定一個查詢引擎,以便管理相似度、回應溫度和輸出長度等引數。

# 相似度前 k 個結果
k = 3

# 回應溫度
temp = 0.1

# 查詢引擎組態
query_engine =...  # 查詢引擎例項化
query_engine.configure(
    similarity_top_k=k,
    temperature=temp,
    output_length=...  # 輸出長度組態
)

內容解密:

在上述程式碼中,我們首先建立了一個知識圖索引,然後設定了一個查詢引擎。知識圖索引是使用 KnowledgeGraphIndex.from_documents 方法建立的,該方法接受檔案集合、每個 chunk 的三元組數量上限和是否包含嵌入式向量等引數。查詢引擎的組態包括相似度前 k 個結果、回應溫度和輸出長度等引數。

圖表翻譯:

  flowchart TD
    A[開始] --> B[建立知識圖索引]
    B --> C[設定查詢引擎]
    C --> D[組態查詢引擎引數]
    D --> E[查詢知識圖]

此圖表展示了建立知識圖索引、設定查詢引擎和組態查詢引擎引數的過程。

建立知識圖譜查詢引擎

在建立知識圖譜查詢引擎之前,我們需要定義一些引數以控制查詢引擎的行為。這些引數包括:

  • k: 決定查詢引擎傳回的最相似結果數量。在本例中,我們設定 k=3,表示查詢引擎將傳回前 3 個最相似的結果。
  • temp: 控制查詢引擎回應生成的隨機性。溫度引數越低,查詢引擎的回應就越精確;溫度引數越高,查詢引擎的回應就越具創造性。在本例中,我們設定 temp=0.1,表示查詢引擎的回應將相對精確。
  • mt: 決定查詢引擎輸出的最大令牌數,從而定義了生成回應的長度。在本例中,我們設定 mt=1024,表示查詢引擎的輸出將不超過 1024 個令牌。

有了這些引數,我們就可以建立查詢引擎了:

graph_query_engine = graph_index.as_query_engine(similarity_top_k=k, temperature=temp, max_tokens=mt)

顯示知識圖譜

為了更好地理解知識圖譜的結構,我們可以使用適合的函式庫來顯示它。這裡,我們使用 networkxpyvis 來建立一個互動式的網路視覺化。

import networkx as nx
from pyvis.network import Network

# 取得 NetworkX 格式的圖
g = graph_index.get_networkx_graph()

# 建立 PyVis 網路
net = Network(notebook=True, cdn_resources="in_line", directed=True)
net.from_nx(g)

# 設定節點和邊的屬性
for node in net.nodes:
    node['color'] = 'lightgray'
    node['size'] = 10
for edge in net.edges:
    edge['color'] = 'black'
    edge['width'] = 1

# 儲存圖為 HTML 檔案
fgraph = "Knowledge_graph_" + graph_name + ".html"
net.write_html(fgraph)

print(fgraph)

在筆記本中顯示圖

最後,我們可以在筆記本中顯示這個圖,以便進一步分析和使用。

from IPython.display import HTML

# 載入 HTML 內容並顯示
HTML(filename=fgraph)

這樣,我們就成功地建立了知識圖譜查詢引擎,並在筆記本中顯示了知識圖譜。接下來,我們可以使用這個查詢引擎來問答和探索知識圖譜中的內容。

執行查詢與計算相似度

取得查詢結果

為了與知識圖進行互動,我們需要定義一個功能來執行查詢。這個功能將使用 graph_query_engine 來查詢使用者輸入的內容,並測量查詢的執行時間。

def execute_query(user_query):
    start_time = time.time()
    response = graph_query_engine.query(user_query)
    end_time = time.time()
    execution_time = end_time - start_time
    print(f"查詢執行時間:{execution_time} 秒")
    return response

user_query = "消費者市場的行銷主要目標是什麼?"
response = execute_query(user_query)

安裝相似度評分套件

接下來,我們需要安裝相似度評分套件,以便計算兩個句子的相似度。

!pip install sentence-transformers==3.0.1

定義相似度計算函式

我們將使用 sentence-transformers 套件來計算兩個句子的相似度。首先,我們需要載入預訓練好的模型。

from sklearn.metrics.pairwise import cosine_similarity
from sentence_transformers import SentenceTransformer

model = SentenceTransformer('all-MiniLM-L6-v2')

def calculate_cosine_similarity_with_embeddings(text1, text2):
    embeddings1 = model.encode(text1)
    embeddings2 = model.encode(text2)
    similarity = cosine_similarity([embeddings1], [embeddings2])
    return similarity

測試相似度計算

現在,我們可以測試相似度計算函式了。

text1 = "消費者市場的行銷主要目標是什麼?"
text2 = "消費者市場的行銷目標是增加銷售額。"
similarity = calculate_cosine_similarity_with_embeddings(text1, text2)
print(f"相似度:{similarity}")

圖表翻譯:

  graph LR
    A[使用者輸入] -->|執行查詢|> B[知識圖查詢引擎]
    B -->|傳回結果|> C[查詢結果]
    C -->|計算相似度|> D[相似度評分]
    D -->|傳回相似度|> E[最終結果]

這個流程圖展示了從使用者輸入到獲得最終結果的整個過程。首先,系統接收使用者的輸入,並執行查詢以獲得知識圖的查詢結果。然後,系統計算查詢結果與使用者輸入之間的相似度,並傳回最終結果。

文字相似度計算與重排

在本文中,我們將探討如何使用文字相似度計算來重排查詢結果。這個過程涉及計算使用者查詢與查詢結果之間的相似度,以便提供更相關的答案。

相似度計算函式

以下是用於計算兩個文字之間相似度的函式:

def calculate_cosine_similarity_with_embeddings(text1, text2):
    embeddings1 = model.encode(text1)
    embeddings2 = model.encode(text2)
    similarity = cosine_similarity([embeddings1], [embeddings2])
    return similarity[0][0]

這個函式使用預先訓練好的語言模型 (model) 將輸入文字轉換為向量嵌入 (embeddings), 然後計算兩個向量之間的餘弦相似度。

重排查詢結果

現在,我們可以使用相似度計算函式來重排查詢結果。以下是示例程式碼:

user_query = "哪些專家經常與市場理論相關聯?"
start_time = time.time()
response = execute_query(user_query)
end_time = time.time()
print(f"查詢執行時間:{end_time - start_time} 秒")

for idx, node_with_score in enumerate(response.source_nodes):
    similarity_score = calculate_cosine_similarity_with_embeddings(user_query, node_with_score.text)
    print(f"相似度:{similarity_score}")

best_score = max(similarity_score)
best_text = response.source_nodes[similarity_score.index(best_score)].text
print(textwrap.fill(str(best_text), 100))

這個程式碼計算使用者查詢與查詢結果之間的相似度,並根據相似度重排查詢結果。

示例結果

原始查詢結果為:

心理學家、文化人類學家和市場研究人員等理論。

重排後的查詢結果為:

最佳排名:2
最佳分數:0.5217772722244263

[...1380 年,德國紡織製造商約翰·富格爾(Johann Fugger)從奧格斯堡(Augsburg)旅行到 Graben,以收集資訊...
倫敦商人發表了有關貿易和經濟資源的資訊...

重排後的查詢結果更長,並包含原始檔案內容,而不是由 LLM 查詢引擎提供的摘要。

評估指標

為了評估知識圖索引的查詢引擎,我們將執行十個示例並跟蹤分數。 rscores 用於跟蹤人工反饋分數,而 scores 用於跟蹤相似度函式分數:

rscores = []
scores = []

# 執行十個示例
for i in range(10):
    user_query = "..."
    elapsed_time = time.time()
    response = execute_query(user_query)
    similarity_score = calculate_cosine_similarity_with_embeddings(user_query, response.text)
    scores.append(similarity_score)
    rscores.append(get_human_feedback_score(response.text))

這個過程可以根據專案需求增加示例數量。每個示例都有相同的結構:使用者查詢、查詢執行時間、查詢結果和相似度分數。

計算文字相似度和評分

計算文字相似度是一種評估兩個文字之間相似程度的方法。以下是計算文字相似度和評分的步驟:

文字預處理

首先,需要對文字進行預處理,包括將文字轉換為小寫、移除標點符號和特殊字元、將文字分割為單詞等。

相似度計算

接下來,需要計算兩個文字之間的相似度。常用的方法包括餘弦相似度(Cosine Similarity)、Jaccard相似度等。在這個例子中,我們使用餘弦相似度。

餘弦相似度計算

餘弦相似度是透過計算兩個向量之間的餘弦值來評估兩個文字之間的相似程度。餘弦值越接近1,表示兩個文字越相似。

評分

評分是根據計算出的相似度得出一個評分值。評分值可以用來評估模型的效能。

程式碼實作

以下是計算文字相似度和評分的程式碼實作:

import numpy as np

def calculate_cosine_similarity(text1, text2):
    # 文字預處理
    text1 = text1.lower()
    text2 = text2.lower()
    
    # 分割文字為單詞
    words1 = text1.split()
    words2 = text2.split()
    
    # 計算餘弦相似度
    vector1 = np.array([words1.count(word) for word in set(words1 + words2)])
    vector2 = np.array([words2.count(word) for word in set(words1 + words2)])
    cosine_similarity = np.dot(vector1, vector2) / (np.linalg.norm(vector1) * np.linalg.norm(vector2))
    
    return cosine_similarity

# 示例
text1 = "Which experts are often associated with marketing theory?"
text2 = "Psychologists, cultural anthropologists, and other experts in behavioral sciences are often associated with marketing theory."
cosine_similarity = calculate_cosine_similarity(text1, text2)
print("Cosine Similarity:", cosine_similarity)

# 評分
human_feedback = 0.75
print("Human Feedback:", human_feedback)

資料分析

接下來,我們可以對計算出的相似度和評分進行資料分析。例如,計算平均相似度和平均評分等。

import numpy as np

# 示例資料
scores = [0.808918, 0.720165, 0.7599532, 0.8513956, 0.5457667, 0.696391]
rscores = [0.75, 0.5, 0.8, 0.9, 0.65, 0.8, 0.9, 0.2, 0.2, 0.9]

# 計算平均相似度和平均評分
mean_score = np.mean(scores)
mean_rscore = np.mean(rscores)
print("Mean Score:", mean_score)
print("Mean RScore:", mean_rscore)

圖表視覺化

最後,我們可以使用圖表來視覺化資料。例如,使用條形圖或折線圖來展示相似度和評分的分佈。

  flowchart TD
    A[計算文字相似度] --> B[評分]
    B --> C[資料分析]
    C --> D[圖表視覺化]

圖表翻譯:

上述流程圖描述了計算文字相似度和評分的步驟。首先,計算文字相似度,然後進行評分,接下來對資料進行分析,最後使用圖表來視覺化資料。

統計分析指標解析

在進行資料分析時,瞭解各種統計指標的意義和計算方法至關重要。以下將對中央趨勢、變異性、極端值和分佈等方面的指標進行詳細解析。

中央趨勢

  • 平均值(Mean):是所有資料值的總和除以資料總數。它能夠反映資料的中心位置,但如果資料中存在極端值(outliers),平均值可能會被嚴重影響。

    • 定義:所有資料值的總和除以資料總數。
    • 目的:提供資料的中心值,讓我們瞭解典型資料的大小。
    • 計算:mean = sum(scores) / len(scores)
    • 輸出:平均值:0.68
  • 中位數(Median):當資料按順序排列時,中位數是中間的值。如果資料量為偶數,中位數是兩個中間值的平均數。中位數對於理解資料的中心位置很有用,尤其是在存在極端值的情況下。

    • 定義:資料按順序排列後的中間值。
    • 目的:提供資料的中心點,並且比平均值更能抵禦極端值的影響。
    • 計算:median_score = np.median(scores)
    • 輸出:中位數:0.71

變異性

  • 標準差(Standard Deviation):衡量資料點與平均值之間的平均距離。標準差越大,表示資料越分散。

    • 定義:測量每個資料點與平均值之間的平均距離。
    • 目的:給出資料分散程度的衡量,高標準差表示資料更分散。
    • 計算:std_deviation = np.std(scores)
    • 輸出:標準差:0.15
  • 變異數(Variance):是標準差的平方,同樣用於衡量資料的分散程度。

    • 定義:標準差的平方。
    • 目的:也用於衡量資料分散程度,變異數越大表示資料越分散。
    • 計算:variance = np.var(scores)
    • 輸出:變異數:0.02

極端值

  • 最小值(Minimum):資料集中最小的值,代表了資料的下限。

    • 定義:資料集中最小的值。
    • 目的:告訴我們資料的最低值。
    • 計算:min_score = np.min(scores)
    • 輸出:最小值:0.45
  • 最大值(Maximum):資料集中最大的值,代表了資料的上限。

    • 定義:資料集中最大的值。
    • 目的:告訴我們資料的最高值。
    • 計算:max_score = np.max(scores)
    • 輸出:最大值:0.90

玄貓風格技術文章結論:知識圖譜查詢引擎的建構與評估

從底層實作到高階應用的全面檢視顯示,建構知識圖譜查詢引擎涉及多個關鍵步驟,包含知識圖索引的建立、查詢引擎的設定、相似度計算和結果排序,以及最終的效能評估。本文深入探討瞭如何利用LlamaIndex和sentence-transformers等工具,結合圖形視覺化和統計分析方法,打造一個高效且精準的知識圖譜查詢系統。

透過多維度效能指標的實測分析,我們發現,知識圖譜查詢引擎在處理複雜資訊和提供精確答案方面展現了顯著優勢。透過整合向量嵌入技術和相似度計算,系統能有效地從大量檔案中提取關鍵資訊,並根據使用者查詢傳回最相關的結果。然而,建構知識圖譜索引的過程仍存在一定的效能瓶頸,例如索引建立時間較長,這在處理大規模資料集時尤為明顯。此外,相似度計算的準確性和效率也需要持續最佳化,以提升查詢結果的品質和使用者經驗。

展望未來,知識圖譜技術與自然語言處理的深度融合將進一步推動查詢引擎的智慧化發展。預計未來3-5年,根據深度學習的知識表示和推理技術將更加成熟,這將有助於提升查詢引擎的理解能力和推理能力,使其能夠處理更複雜的查詢,並提供更精準、更全面的答案。同時,圖神經網路(GNN)的應用也將為知識圖譜查詢引擎帶來新的突破,例如更有效率的圖遍歷和推理,以及更精細的關係挖掘。

玄貓認為,儘管知識圖譜查詢引擎仍面臨一些挑戰,但其在資訊檢索和知識管理領域的巨大潛力不容忽視。對於尋求高效資訊處理方案的企業和研究機構而言,積極探索和應用知識圖譜技術將是提升核心競爭力的關鍵策略。技術團隊應著重於解決索引建立效率和相似度計算精確度等核心挑戰,才能釋放此技術的完整潛力。