Gemini 埋め込みモデル（gemini-embedding-exp-03-07）を試す

このノートブックでは、2025年3月7日にリリースされた新しい実験的なGemini埋め込みテキストモデル（gemini-embedding-exp-03-07）の使い方を紹介します。このモデルは、Geminiモデル自体からトレーニングされ、Geminiの言語理解と微妙なコンテキスト理解能力を継承しています。

https://x.com/hAru_mAki_ch/status/1899497588996690168

## 特徴

- **MTEB（多言語）リーダーボードでトップランク**を獲得
- **8Kトークン**の入力制限
- **3K次元**の出力
- **マトリョーシカ表現学習（MRL）**をサポート
- **100以上の言語**に対応
- **統一モデル**：以前のタスク特化型の多言語、英語のみ、コード特化型モデルの品質を上回る

## 1. セットアップ

まず必要なライブラリをインストールしましょう。

```python
!pip install -q google-genai
```

## 2. APIキーの設定

Gemini APIキーを設定します。APIキーは[Google AI Studio](https://ai.google.dev/)から取得できます。

```python
from google import genai
from google.colab import userdata

# APIキーを設定
GOOGLE_API_KEY = userdata.get('GEMINI_API_KEY')
client = genai.Client(api_key=GOOGLE_API_KEY)
```

## 3. 基本的な埋め込み生成

テキストの埋め込みを生成する基本的な例を見てみましょう。

```python
# 単一のテキストから埋め込みを生成
result = client.models.embed_content(
    model="gemini-embedding-exp-03-07",
    contents="How does alphafold work?",
)

# 結果の埋め込みベクトルを表示（最初の10要素のみ）
print(f"埋め込みベクトルの次元数: {len(result.embeddings[0].values)}")
print(f"最初の10要素: {result.embeddings[0].values[:10]}")
```

## 4. 複数のテキストの埋め込み

複数のテキストから埋め込みを生成する方法を見てみましょう。

```python
# 複数のテキストサンプル
texts = [
    "タンパク質構造予測のためのAIモデル",
    "AlphaFoldの仕組みについて",
    "DNAとRNAの違い",
    "機械学習を使った創薬研究"
]

# 複数のテキストから埋め込みを生成
results = client.models.embed_content(
    model="gemini-embedding-exp-03-07",
    contents=texts,
)

# 各テキストの埋め込みの最初の5要素を表示
for i, embedding in enumerate(results.embeddings):
    print(f"テキスト {i+1}: {texts[i]}")
    print(f"埋め込みベクトル（最初の5要素）: {embedding.values[:5]}")
    print("-" * 50)
```

## 5. 埋め込みの類似性計算

生成された埋め込みを使用して、テキスト間の類似性を計算します。

```python
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

# テキストサンプル
query = "AlphaFoldはタンパク質構造をどのように予測しますか？"
documents = [
    "AlphaFoldは深層学習を使用してタンパク質の3D構造を予測します。",
    "タンパク質構造予測は創薬研究において重要な役割を果たします。",
    "気候変動は地球温暖化によって引き起こされる現象です。",
    "AlphaFoldはDeepMindによって開発されたAIシステムです。"
]

# クエリと文書の埋め込みを生成
query_result = client.models.embed_content(
    model="gemini-embedding-exp-03-07",
    contents=query,
)
query_embedding = np.array(query_result.embeddings[0].values).reshape(1, -1)

doc_result = client.models.embed_content(
    model="gemini-embedding-exp-03-07",
    contents=documents,
)
doc_embeddings = np.array([embedding.values for embedding in doc_result.embeddings])

# コサイン類似度を計算
similarities = cosine_similarity(query_embedding, doc_embeddings).flatten()

# 結果を表示
print(f"クエリ: {query}\n")
for i, (doc, sim) in enumerate(zip(documents, similarities)):
    print(f"文書 {i+1}: {doc}")
    print(f"類似度: {sim:.4f}")
    print("-" * 50)

# 最も類似度の高い文書を特定
most_similar_idx = np.argmax(similarities)
print(f"最も関連性の高い文書: {documents[most_similar_idx]}")
print(f"類似度スコア: {similarities[most_similar_idx]:.4f}")
```

## 6. 簡易検索システムの実装

埋め込みを使用した簡単な検索システムを実装してみましょう。

```python
def create_document_embeddings(documents, model="gemini-embedding-exp-03-07"):
    """文書のリストから埋め込みを生成する関数"""
    result = client.models.embed_content(
        model=model,
        contents=documents,
    )
    return np.array([embedding.values for embedding in result.embeddings])

def search_documents(query, documents, embeddings, top_k=3):
    """クエリに基づいて文書を検索する関数"""
    # クエリの埋め込みを生成
    query_result = client.models.embed_content(
        model="gemini-embedding-exp-03-07",
        contents=query,
    )
    query_embedding = np.array(query_result.embeddings[0].values).reshape(1, -1)

    # 類似度を計算
    similarities = cosine_similarity(query_embedding, embeddings).flatten()

    # 上位k件の結果を取得
    top_indices = similarities.argsort()[-top_k:][::-1]

    results = []
    for idx in top_indices:
        results.append({
            "document": documents[idx],
            "similarity": similarities[idx]
        })

    return results

# サンプル文書
documents = [
    "Gemini埋め込みモデルはMTEB（多言語）リーダーボードでトップランクを獲得しました。",
    # "埋め込みは、意味と文脈を数値表現でキャプチャします。類似した意味を持つデータは、より近い埋め込みを持ちます。",
    "Retrieval-Augmented Generation（RAG）は、生成されるテキストの品質と関連性を向上させます。",
    # "Gemini埋め込みモデルは8Kトークンの入力制限と3K次元の出力をサポートしています。",
    "マトリョーシカ表現学習（MRL）により、元の3K次元を切り詰めてストレージコストを削減できます。",
    # "Gemini埋め込みモデルは100以上の言語をサポートし、以前のモデルよりも2倍の言語に対応しています。",
    # "統一モデルはタスク特化型の多言語、英語のみ、およびコード特化型モデルの品質を上回ります。"
]

# 文書の埋め込みを生成
document_embeddings = create_document_embeddings(documents)

# 検索クエリ
search_query = "RAGとは何ですか？"

# 検索を実行
search_results = search_documents(search_query, documents, document_embeddings, top_k=3)

# 結果を表示
print(f"クエリ: {search_query}\n")
print("検索結果:")
for i, result in enumerate(search_results):
    print(f"{i+1}. {result['document']}")
    print(f"   類似度: {result['similarity']:.4f}")
```

## 7. マトリョーシカ表現学習（MRL）の活用

Gemini埋め込みモデルはMRLをサポートしているため、3K次元の埋め込みを小さな次元に削減できます。

```python
def truncate_embeddings(embeddings, target_dim):
    """埋め込みをターゲットの次元に切り詰める関数"""
    if target_dim > embeddings.shape[1]:
        raise ValueError("ターゲット次元は元の次元よりも小さくする必要があります")

    return embeddings[:, :target_dim]

# 元の埋め込み
original_embeddings = create_document_embeddings(documents)
print(f"元の埋め込み次元: {original_embeddings.shape[1]}")

# 次元を削減
target_dimensions = [256, 512, 1024]
for dim in target_dimensions:
    truncated = truncate_embeddings(original_embeddings, dim)
    print(f"{dim}次元に切り詰めた埋め込み形状: {truncated.shape}")
```

## 8. 実際のユースケース: 簡易RAGシステム

埋め込みを使用した簡単なRAG（Retrieval-Augmented Generation）システムを実装してみましょう。

```python
def rag_system(query, documents, model="gemini-1.5-flash"):
    """RAGシステムの実装"""
    # 文書の埋め込みを生成
    document_embeddings = create_document_embeddings(documents)

    # 関連文書を検索
    search_results = search_documents(query, documents, document_embeddings, top_k=2)
    retrieved_docs = [result["document"] for result in search_results]

    # コンテキストを構築
    context = "\n".join(retrieved_docs)

    # Geminiモデルを使用して回答を生成
    prompt = f"""
    以下の情報に基づいて、質問に答えてください:

    情報:
    {context}

    質問: {query}
    """

    response = client.models.generate_content(model="gemini-2.0-flash", contents=[prompt])

    return {
        "query": query,
        "retrieved_documents": retrieved_docs,
        "response": response.text
    }

# RAGシステムを試す
query = "マトリョーシカ表現学習の利点は何ですか？"
result = rag_system(query, documents)

print(f"質問: {result['query']}\n")
print("検索された文書:")
for i, doc in enumerate(result['retrieved_documents']):
    print(f"{i+1}. {doc}")
print("\n回答:")
print(result['response'])
```

## まとめ

このノートブックでは、新しいGemini埋め込みモデル（gemini-embedding-exp-03-07）の基本的な使い方を紹介しました。このモデルは、テキスト検索、分類、RAGシステムなど、多くのアプリケーションで活用できます。

主な特徴：
- MTEB（多言語）リーダーボードでトップランク
- 8Kトークンの入力制限
- 3K次元の出力
- マトリョーシカ表現学習（MRL）のサポート
- 100以上の言語に対応
- 統一モデル

現在は実験的なフェーズで容量が限られていますが、今後数ヶ月でより安定した一般提供版がリリースされる予定です。