OpenAI GPT3.5 とLangchainを使って、特定のPDFからの情報を答えさせてみる
なぜやろうと思ったか&どうだったか
仕事でもですが、非公開情報を含む色々なPDFの情報をまとめておいて、そこから正しい情報を抜き出せないか?と常々思っていました。自分で作成した文書はPDFになる前の情報がありますが、外部から受け取ったものはそうでもなく、なにかできないか?ということで試しにやってみました。
先に結論を書いておくと、PDFからの情報を与えることで、回答に具体性が増し、PDFにある情報を答えさせることは可能でした。
対象にするPDF
2021年12月16日一般社団法人日本感染症学会 ワクチン委員会発行のCOVID-19 ワクチンに関する提言(第4版)とします。
https://www.kansensho.or.jp/uploads/files/guidelines/2112_covid-19_4.pdf
GPT3.5は、2021年9月までのデータを基にしているので、この文書そのものはGPT3.5のモデルには含まれないはずです。
PDFの読み込み
Langchain の PyPDFLoader を使用します。
from langchain.document_loaders import PyPDFLoader
loader= PyPDFLoader('target.pdf') # PDFファイルのパス
docs = loader.load()
# PDF の各ページの内容を結合します
text = ""
for doc in docs:
text += doc.page_content
# 結合してファイルに書き出します
with open('loaded.txt', 'w') as f:
f.write(text)
PyPDFの他にも、Langchain にはPDFLoaderが用意されています。PyPDFLoaderが比較的文書の構造を維持することができました。
また、PDF上のページが異なると別オブジェクトになってしまい、文の意味が不必要にバラけてしまうため、一旦全部テキストとして結合・ファイルに書き出します。テキストファイルで整形、紛れ込んだページ番号の削除を行いました。
インデックスの作成
import sys
import os
import pinecone
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Pinecone
# API Key
openai_api_key = '***OPENAI_API_KEY***'
pinecone.init(api_key='***PINECONE_API_KEY***', environment='gcp-starter')
# Pinecone のIndex情報
index_name = 'name-database' # Index の名前
index = pinecone.Index(index_name)
embeddings_model='text-embedding-ada-002'
# このモデルの dimension 1536, max token = 8191
# PineCone の Index のDimensionは、1536 で作成する必要があります。
chunk_size=4096
separator='\n'
def createIndex(filepath):
filepath = os.getcwd() +'/'+ filepath
# PDFを変換したテキストデータを読み込みます
loader= TextLoader(filepath)
documents = loader.load()
# チャンクに分割します
text_splitter = CharacterTextSplitter(
separator=separator,
chunk_size=chunk_size,
chunk_overlap=0
)
texts = text_splitter.split_documents(documents)
## Embedding の定義です。
embeddings = OpenAIEmbeddings(
openai_api_key=openai_api_key,
deployment=embeddings_model,
model=embeddings_model,
chunk_size=chunk_size,
show_progress_bar=True, # to visualize progress
)
## Pinecone のIndexに保存します
vectorstore = Pinecone.from_documents(texts, embeddings, index_name=index_name)
createIndex('loaded.txt')
IndexにはPineconeを使用します。Index一つまでは無料で使用できます。今回の文書ではローカルに保存するVectorDatabase でも十分ですが、勉強も兼ねて使ってみたという意味しかありません。
Chat で問い合わせたい情報を取り出す Chain を準備する
ここから先は
¥ 590
Amazonギフトカード5,000円分が当たる
この記事が気に入ったらチップで応援してみませんか?