ベクトルデータベース - AI時代のデータ検索基盤

18分 で読める | 2025.01.21

ベクトルデータベースとは

ベクトルデータベースは、高次元のベクトルデータを効率的に保存・検索するために設計された専用データベースです。テキスト、画像、音声などを数値ベクトル(埋め込み)に変換し、意味的な類似性に基づいて検索できます。

flowchart LR
    subgraph Input["入力データ"]
        Text["テキスト"]
        Image["画像"]
        Audio["音声"]
    end

    subgraph Embedding["埋め込みモデル"]
        Model["AI モデル<br/>(OpenAI, Cohere等)"]
    end

    subgraph VectorDB["ベクトルDB"]
        Index["インデックス"]
        Storage["ベクトル保存"]
    end

    subgraph Output["検索結果"]
        Similar["類似データ"]
    end

    Text --> Model
    Image --> Model
    Audio --> Model
    Model --> Index
    Index --> Storage
    Storage --> Similar

なぜベクトルデータベースが必要か

従来の検索 vs セマンティック検索

特徴キーワード検索ベクトル検索
検索方式完全一致・部分一致意味的類似度
「犬」で検索「犬」を含む文書「ワンちゃん」「柴犬」も発見
多言語対応言語ごとに別処理意味が同じなら言語不問
同義語辞書登録が必要自動的に理解

埋め込みベクトルの仕組み

ベクトル化の例

import { OpenAI } from 'openai';

const openai = new OpenAI();

// テキストをベクトルに変換
async function getEmbedding(text: string): Promise<number[]> {
  const response = await openai.embeddings.create({
    model: 'text-embedding-3-small',
    input: text,
  });
  return response.data[0].embedding; // 1536次元のベクトル
}

// 例: 類似度計算
function cosineSimilarity(a: number[], b: number[]): number {
  const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);
  const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
  const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
  return dotProduct / (magnitudeA * magnitudeB);
}

// 使用例
const vec1 = await getEmbedding('プログラミングを学ぶ');
const vec2 = await getEmbedding('コーディングを習得する');
const vec3 = await getEmbedding('料理のレシピ');

console.log(cosineSimilarity(vec1, vec2)); // 0.92(高い類似度)
console.log(cosineSimilarity(vec1, vec3)); // 0.21(低い類似度)

主要な類似検索アルゴリズム

1. HNSW(Hierarchical Navigable Small World)

最も広く使われるアルゴリズムで、高速かつ高精度です。

flowchart TB
    subgraph Layer2["レイヤー2(疎)"]
        A2((A)) --- B2((B))
    end

    subgraph Layer1["レイヤー1(中間)"]
        A1((A)) --- B1((B))
        B1 --- C1((C))
        A1 --- D1((D))
    end

    subgraph Layer0["レイヤー0(密)"]
        A0((A)) --- B0((B))
        B0 --- C0((C))
        C0 --- E0((E))
        A0 --- D0((D))
        D0 --- F0((F))
    end

    A2 -.-> A1
    B2 -.-> B1
    A1 -.-> A0
    B1 -.-> B0
    C1 -.-> C0
    D1 -.-> D0

2. IVF(Inverted File Index)

データをクラスタに分割し、検索範囲を絞り込みます。

# Faissでの IVF 使用例
import faiss
import numpy as np

# 100万件の1536次元ベクトル
vectors = np.random.random((1_000_000, 1536)).astype('float32')

# IVFインデックス作成(nlist=1000クラスタ)
quantizer = faiss.IndexFlatL2(1536)
index = faiss.IndexIVFFlat(quantizer, 1536, 1000)

# 学習とデータ追加
index.train(vectors)
index.add(vectors)

# 検索(nprobe=10クラスタを探索)
index.nprobe = 10
query = np.random.random((1, 1536)).astype('float32')
distances, indices = index.search(query, k=10)

アルゴリズム比較

アルゴリズム検索速度メモリ使用量精度適用場面
Flat(総当たり)遅い低い100%小規模データ
HNSW速い高い95%+汎用
IVF中程度中程度90%+大規模データ
PQ(量子化)非常に速い非常に低い80%+超大規模

主要なベクトルデータベース

1. Pinecone

import { Pinecone } from '@pinecone-database/pinecone';

const pinecone = new Pinecone({ apiKey: process.env.PINECONE_API_KEY });
const index = pinecone.Index('my-index');

// データ追加
await index.upsert([
  {
    id: 'doc1',
    values: embedding,
    metadata: { title: '記事タイトル', category: 'tech' },
  },
]);

// 検索
const results = await index.query({
  vector: queryEmbedding,
  topK: 10,
  filter: { category: { $eq: 'tech' } },
  includeMetadata: true,
});

2. Weaviate

import weaviate from 'weaviate-ts-client';

const client = weaviate.client({
  scheme: 'https',
  host: 'your-instance.weaviate.network',
});

// スキーマ定義
await client.schema.classCreator().withClass({
  class: 'Article',
  vectorizer: 'text2vec-openai',
  properties: [
    { name: 'title', dataType: ['text'] },
    { name: 'content', dataType: ['text'] },
  ],
}).do();

// セマンティック検索
const result = await client.graphql
  .get()
  .withClassName('Article')
  .withFields('title content')
  .withNearText({ concepts: ['機械学習入門'] })
  .withLimit(5)
  .do();

3. pgvector(PostgreSQL拡張)

-- 拡張を有効化
CREATE EXTENSION vector;

-- テーブル作成
CREATE TABLE documents (
  id SERIAL PRIMARY KEY,
  content TEXT,
  embedding vector(1536)
);

-- インデックス作成(HNSW)
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops);

-- 類似検索
SELECT content, 1 - (embedding <=> query_embedding) AS similarity
FROM documents
ORDER BY embedding <=> query_embedding
LIMIT 10;

RAGでの活用

RAG(Retrieval-Augmented Generation)は、ベクトルデータベースとLLMを組み合わせた手法です。

flowchart LR
    Query["ユーザー質問"] --> Embed["埋め込み変換"]
    Embed --> Search["ベクトル検索"]
    Search --> Context["関連文書取得"]
    Context --> LLM["LLM"]
    Query --> LLM
    LLM --> Answer["回答生成"]

実装例

import { OpenAI } from 'openai';
import { Pinecone } from '@pinecone-database/pinecone';

async function ragQuery(question: string): Promise<string> {
  const openai = new OpenAI();
  const pinecone = new Pinecone();
  const index = pinecone.Index('knowledge-base');

  // 1. 質問をベクトル化
  const embeddingResponse = await openai.embeddings.create({
    model: 'text-embedding-3-small',
    input: question,
  });
  const queryVector = embeddingResponse.data[0].embedding;

  // 2. 関連文書を検索
  const searchResults = await index.query({
    vector: queryVector,
    topK: 5,
    includeMetadata: true,
  });

  // 3. コンテキストを構築
  const context = searchResults.matches
    .map(match => match.metadata?.content)
    .join('\n\n');

  // 4. LLMで回答生成
  const completion = await openai.chat.completions.create({
    model: 'gpt-4',
    messages: [
      {
        role: 'system',
        content: `以下のコンテキストに基づいて質問に答えてください。\n\n${context}`,
      },
      { role: 'user', content: question },
    ],
  });

  return completion.choices[0].message.content ?? '';
}

ベストプラクティス

1. チャンキング戦略

// 適切なチャンクサイズで分割
function chunkText(text: string, chunkSize = 500, overlap = 50): string[] {
  const chunks: string[] = [];
  let start = 0;

  while (start < text.length) {
    const end = Math.min(start + chunkSize, text.length);
    chunks.push(text.slice(start, end));
    start = end - overlap;
  }

  return chunks;
}

2. メタデータの活用

// フィルタリングで検索精度向上
const results = await index.query({
  vector: queryVector,
  topK: 10,
  filter: {
    $and: [
      { category: { $eq: 'documentation' } },
      { date: { $gte: '2024-01-01' } },
      { language: { $eq: 'ja' } },
    ],
  },
});

3. ハイブリッド検索

// キーワード検索とベクトル検索を組み合わせ
const hybridResults = await weaviate.graphql
  .get()
  .withClassName('Article')
  .withHybrid({
    query: 'TypeScript 型安全',
    alpha: 0.5, // 0=キーワード, 1=ベクトル
  })
  .withLimit(10)
  .do();

関連記事

まとめ

ベクトルデータベースは、AI時代の検索基盤として不可欠な技術です。

  • 埋め込みベクトル: テキストや画像を数値表現に変換
  • 類似検索: HNSWやIVFで高速な近似最近傍探索
  • RAG: LLMと組み合わせて知識ベースを構築
  • ハイブリッド検索: キーワードとセマンティックの融合

適切なベクトルデータベースとアルゴリズムを選択し、AIアプリケーションの基盤を構築しましょう。

この技術を体系的に学びたいですか?

未来学では東証プライム上場企業のITエンジニアが24時間サポート。月額24,800円から、退会金0円のオンラインIT塾です。

LINEで無料相談する
← 一覧に戻る