見出し画像

GPT Index のナレッジグラフ機能を試す

GPT Index のナレッジグラフ機能を試したので、まとめました。

1. ナレッジグラフ

「ナレッジグラフ」 (Knowledge Graph) は、さまざまな知識の関係をグラフ構造で表したものです。知的システムの基盤となるデータベースとして用いられます。

「GPT Index」は、RDF フレームワークと直接互換性のある「トリプル」 (主語、述語、目的語) として表されるナレッジグラフデータをサポートします。内部的には、グラフデータは有向グラフとして管理されます。

現在、「GPT Index」は、LLMがサポートするトリプルの操作を2つ提供しています。

・グラフ抽出 (Graph extraction) : 与えられたテキストからトリプルを抽出
・グラフQ&A (Graph Q&A) : グラフデータを応答合成のコンテキストとして利用

2. グラフ抽出

Google Colabでの「GPT Index」でのグラフ抽出の生成手順は、次のとおりです。

(1) パッケージのインストール。
「GPT Index」でナレッジグラフが利用できるのは0.4.3以降です。

# パッケージのインストール (0.4.3以降)
!pip install git+https://github.com/jerryjliu/gpt_index

(2) 環境変数の準備。
以下のコードの <OpenAI_APIのトークン> にはOpenAI APIのトークンを指定します。(有料)

import os
os.environ["OPENAI_API_KEY"] = "<OpenAI_APIのトークン>"

(3) ログレベルをDEBUGに設定。

# ログの設定
import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, force=True)

(4) GPTKnowledgeGraphIndexでインデックスを生成。

from gpt_index import SimpleDirectoryReader, LLMPredictor
from gpt_index.indices.knowledge_graph.base import GPTKnowledgeGraphIndex
from gpt_index.indices.prompt_helper import PromptHelper
from langchain import OpenAI

# ドキュメントの読み込み
documents = SimpleDirectoryReader('data').load_data()

# LLMプレディクタの準備
llm_predictor = LLMPredictor(
    llm=OpenAI(temperature=0, model_name="text-davinci-003")
)

# インデックスの生成
index = GPTKnowledgeGraphIndex(
    documents=documents,
    llm_predictor=llm_predictor,
    prompt_helper=PromptHelper(
        max_input_size=4000,
        num_output=256,  
        chunk_size_limit=2000,
        max_chunk_overlap=0,
        separator="。"
    ),
)
DEBUG:root:> [SimpleDirectoryReader] Total files added: 1
DEBUG:root:> Adding chunk:  結束バンド

 後藤ひとりは友達を作れない陰キャでいつも一人で過ごしていたが、中学時代にテレ...
DEBUG:root:> Adding chunk: ひねくれ者なヨヨコは、結束バンドをライバル視しながらも、彼女たちにアドバイスを送り、ファンたち...
DEBUG:root:> Adding chunk: 幼い頃に母親と死別しており、父親も多忙なためさびしい日々を送っていた。姉の伊地知星歌の影響で、...
DEBUG:root:> Adding chunk: 「郁代」という名前が気に入らず、周囲には名字で呼ぶようにお願いしている。山田リョウを慕っており...
DEBUG:root:> Adding chunk: 金髪を長く伸ばした髪型が特徴。イギリス出身で、18歳までイギリスで暮らしていたため、片言の日本...
DEBUG:root:> Adding chunk: コミュニケーションを取るのも下手で敵をつくりがちであるため、友達もおらず、バンドメンバーも入れ...
DEBUG:root:> Adding chunk: 後藤ひとりと廣井きくりの路上ライブを見て、彼女たちのことを知り、ファンとなった。路上ライブの際...
DEBUG:root:> Adding chunk: 「完熟マンゴー」と書かれているため、「完熟マンゴー仮面」と呼ばれている。ひとりが人前に立つと緊...
DEBUG:openai:message='Request to OpenAI API' method=post path=https://api.openai.com/v1/completions
DEBUG:urllib3.connectionpool:https://api.openai.com:443 "POST /v1/completions HTTP/1.1" 200 None
DEBUG:root:(後藤ひとり, heard, can become popular by forming a band)
(後藤ひとり, started, guitar practice)
(後藤ひとり, joined, 結束バンド)
(結束バンド, participated in, 文化祭ライブ)
(結束バンド, participated in, 未確認ライオット)
(結束バンド, created, MV)
(結束バンド, encountered, SIDEROS)
(SIDEROS, belonged to, 大槻ヨヨコ)
(佐藤愛子, criticized, 結束バンド)
(廣井きくり, helped, 結束バンド)
(喜多郁代, returned to, 結束バンド)
DEBUG:root:> Extracted triplets: [('後藤ひとり', 'heard', 'can become popular by forming a band'), ('後藤ひとり', 'started', 'guitar practice'), ('後藤ひとり', 'joined', '結束バンド'), ('結束バンド', 'participated in', '文化祭ライブ'), ('結束バンド', 'participated in', '未確認ライオット'), ('結束バンド', 'created', 'MV'), ('結束バンド', 'encountered', 'SIDEROS'), ('SIDEROS', 'belonged to', '大槻ヨヨコ'), ('佐藤愛子', 'criticized', '結束バンド'), ('廣井きくり', 'helped', '結束バンド'), ('喜多郁代', 'returned to', '結束バンド')]
DEBUG:openai:message='Request to OpenAI API' method=post path=https://api.openai.com/v1/completions
DEBUG:urllib3.connectionpool:https://api.openai.com:443 "POST /v1/completions HTTP/1.1" 200 None
DEBUG:root:(後藤ひとり, is, 陰キャ)
(後藤ひとり, has, 押し入れ癖)
(後藤ひとり, has, ダンボール癖)
(後藤ひとり, wears, 完熟マンゴー仮面)
(後藤ひとり, is bad at, 運動)
(後藤ひとり, is bad at, 勉強)
(伊地知虹夏, has, ライトイエロー髪)
(伊地知虹夏, wears, 派手目ファッション)
(伊地知虹夏, is, 下北沢高校生)
(伊地知虹夏, is, 1学年上)
    :

3. グラフの可視化

グラフの可視化の手順は、次のとおりです。

(1) pyvisのインストール。

!pip install pyvis

(2) グラフを表示するHTMLの生成。
「example.html」が生成されます。

from pyvis.network import Network

g = index.get_networkx_graph()
net = Network(directed=True)
net.from_nx(g)
net.show("example.html")

(3)  「example.html」をダウンロードして、ブラウザで表示。

4. グラフQ&A

サンプルコードを元に日本語で質問してみましたがうまく動作しませんでした。
日本語のせいなのか、使い方が違うのかあとで調べる。

from IPython.display import Markdown, display

response = index.query(
    "後藤ひとりについて教えて下さい。", 
    include_text=False, 
    response_mode="tree_summarize"
)
display(Markdown(f"<b>{response}</b>"))
I'm sorry, but I do not have any information about 後藤ひとり.

関連



この記事が気に入ったらサポートをしてみませんか?