見出し画像

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 を準備する

ここから先は

2,025字 / 2ファイル

¥ 590

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