
Google ColabとOpenAI GPTを使ったRAGベクトル検索ハンズオン
はじめに
今回は、Google Colabを使って、OpenAIのGPTモデルを利用し、RAG(Retrieval-Augmented Generation)を実装してみましたのでその方法を紹介します。RAGは、情報検索と生成を組み合わせた技術で、特定の質問に対して関連する情報を検索し、その情報を基に回答を生成する手法です。
前提条件
Google ColabのセットアップとOpenAIのAPIの課金設定と以下のモデル利用設定がされていることが条件です。
text-embedding-ada-002
gpt-3.5-turbo
用語説明
Google Colab: Google Colaboratoryの略で、Googleが提供するクラウドベースのJupyterノートブック環境。Pythonコードの実行、データ分析、機械学習モデルのトレーニングなどがブラウザ上で行える。
OpenAI API: OpenAIが提供するAPIで、GPT-3やGPT-4などの高度な言語モデルを利用してテキスト生成、翻訳、要約などの自然言語処理タスクを実行できる。
RAG: Retrieval-Augmented Generationの略。情報検索と生成を組み合わせた技術で、質問に対して関連する情報を検索し、その情報を基に回答を生成する手法。
チャンク: 大きなテキストデータを扱いやすいサイズに分割したもの。RAGでは、テキストをチャンクに分割して処理することで、効率的に情報を検索・生成することができます。
embeddingモデル: テキストや単語をベクトル(数値の配列)に変換するモデル。これにより、テキストの意味や文脈を数値として表現し、機械学習モデルで扱いやすくします。
ベクトル検索: テキストデータをベクトル空間にマッピングし、クエリに対して類似度の高いベクトルを検索する手法。これにより、関連性の高い情報を効率的に見つけることができます。
必要なライブラリのインストール
まずは、OpenAIのライブラリをインストールします。
!pip install openai numpy

テキストデータの準備
次に、サンプルテキストデータを用意します。今回は、日本のバラエティ番組「オレたちひょうきん族」についてのテキストを使用します。
text = """
**「オレたちひょうきん族」について**
『オレたちひょうきん族』は、1981年5月16日から1989年10月14日までフジテレビ系列で放送されていたバラエティ番組である。土曜夜8時というゴールデンタイムに放送され、当時の日本のお笑い文化を大きく変えるほどの影響を与えた伝説的な番組として知られる。
### **概要**
それまでのバラエティ番組は、正統派の「ドリフターズ」スタイル(特に『8時だョ!全員集合』)が主流だった。しかし、『オレたちひょうきん族』は、若手芸人を中心に即興的でシュールな笑いを提供し、従来の「コント中心」から「パロディや風刺を多用した新しい笑い」へと移行した。特に、視聴者の予想を裏切る展開や、芸人同士の掛け合いが特徴だった。
### **主な出演者**
番組の主要メンバーには、ビートたけし(ツービート)や明石家さんまをはじめ、島田紳助、片岡鶴太郎、山田邦子、西川のりおなど、当時の若手から中堅芸人が多数出演した。特に、ビートたけし扮する「ひょうきん大将」と明石家さんま扮する「ひょうきん懺悔室」のコーナーは、番組の代名詞的な存在となった。
### **主なコーナー**
1. **「ひょうきん懺悔室」**
明石家さんまが神父役となり、芸人たちが「懺悔」と称して失敗談やエピソードを話し、それが面白ければ「許し」、つまらなければ「水をかぶる」という斬新なスタイルが人気を博した。
2. **「タケちゃんマン」**
ビートたけし演じるヒーロー「タケちゃんマン」と、敵役の「ブラックデビル」(片岡鶴太郎)などのキャラクターが繰り広げるコント。定番のギャグやアドリブが特徴。
3. **「ひょうきんニュース」**
政治や社会問題を風刺するニュース風コントで、当時の社会情勢をユーモアたっぷりに伝えた。
### **影響と評価**
『オレたちひょうきん族』は、お笑い番組の新たなスタイルを確立し、その後のバラエティ番組にも多大な影響を与えた。特に、若手芸人を積極的に起用し、即興性や風刺を重視するスタイルは、のちの『めちゃ²イケてるッ!』や『笑っていいとも!』にも受け継がれた。
また、当時の視聴率争いでは『8時だョ!全員集合』と競り合い、最終的に『ひょうきん族』が優勢となることで、ドリフの時代が終焉を迎えたとも言われている。
### **番組の終了とその後**
1989年に番組は終了するが、その後も『ひょうきん族』のメンバーは個々に活躍を続け、日本のバラエティ界の中心人物として君臨した。現在でも、「タケちゃんマン」や「懺悔室」などの名シーンは語り継がれており、日本のお笑い史に残る番組として評価されている。
"""
テキストの分割(チャンク作成)
長いテキストを扱うために、適切なサイズに分割します。
def chunk_text(text, chunk_size=200):
return [text[i:i+chunk_size] for i in range(0, len(text), chunk_size)]
chunks = chunk_text(text)

チャンク作成時のオーバーラップ(予備知識)
チャンク作成時のオーバーラップは、隣接するチャンク間で一部のテキストを共有することを指します。これにより、チャンク間の連続性が保たれ、文脈が途切れにくくなります。例えば、チャンクサイズが200文字でオーバーラップが50文字の場合、次のようにチャンクが作成されます:
チャンク1: 0文字目から200文字目 チャンク2: 150文字目から350文字目 チャンク3: 300文字目から500文字目 このようにすることで、各チャンクが50文字分のテキストを共有し、文脈の連続性を保ちます。
以下は、オーバーラップを考慮したチャンク作成の例です:
def chunk_text_with_overlap(text, chunk_size=200, overlap=50):
chunks = []
for i in range(0, len(text), chunk_size - overlap):
chunks.append(text[i:i + chunk_size])
return chunks
text = "長いテキスト..."
chunks = chunk_text_with_overlap(text)
この方法で、テキストの連続性を保ちながらチャンクを作成できます。
OpenAI APIの設定
OpenAIのAPIキーを使ってクライアントを設定し、利用可能なモデルを確認します。
from openai import OpenAI
client = OpenAI(api_key='YOUR_API_KEY')
# 利用可能なモデルを一覧表示
models = client.models.list()
print('Useful Models...')
for m in models.data:
print(m.id)
テキストの埋め込み生成
OpenAIのAPIでテキストチャンクごとに埋め込みを生成します。
def get_embedding(text):
response = client.embeddings.create(
model="text-embedding-ada-002",
input=text
)
return response.data[0].embedding
embeddings = [get_embedding(chunk) for chunk in chunks]
print('Embeddings...')
print(embeddings)

類似チャンクの検索
ベクトル検索による類似度計算、クエリに対して最も類似したテキストチャンクを検索します。
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
def find_similar_chunks(query, embeddings, chunks, top_n=3):
query_embedding = get_embedding(query)
similarities = cosine_similarity(
[query_embedding], embeddings
)[0]
top_indices = np.argsort(similarities)[-top_n:][::-1]
return [chunks[i] for i in top_indices]
query = "明石家さんまはひょうきん族ですか?"
similar_chunks = find_similar_chunks(query, embeddings, chunks)
print('Similar Chunks...')
print(similar_chunks)

回答の生成
GPTモデルとの連携、類似チャンクを基に、GPTモデルを使って質問に対する回答を生成します。
def generate_response(context, query):
messages = [
{"role": "system", "content": f"以下の情報を基に質問に答えてください:\n\n{context}"},
{"role": "user", "content": query},
]
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages,
)
print(response)
return response.choices[0].message.content.strip()
context = "\n\n".join(similar_chunks)
response = generate_response(context, query)
print(response)

まとめ
以上の手順で、Google ColabとOpenAI GPTを使ってRAGを実装する方法を紹介しました。これにより、特定の質問に対して関連する情報を検索し、その情報を基に回答を生成することができます。Webページをスクレイピングしてもテキストを抽出後にこのような方法でRAGを構築できます。ぜひ試してみてください。
