本ページでは、 生成 AI を統合的に解説します。 大規模言語モデル (LLM)・拡散モデル・GAN・VAE・プロンプトエンジニアリング・RAG / エージェント・評価・倫理を一気通貫で扱います。
「識別 AI(分類・予測)」と異なり、 生成 AI は新しいデータを作る。 2022 年の ChatGPT・Stable Diffusion で大衆化し、 現在も急速に進化中です。
論文記事から各用語のリンクをクリックすると、 該当箇所が開きます:
データ分布 $p(\mathbf{x})$ を学習し、 そこから新たなサンプルを生成するモデル群。
| 識別モデル | 生成モデル |
|---|---|
| $p(y|\mathbf{x})$ を学習 | $p(\mathbf{x})$ や $p(\mathbf{x}|y)$ を学習 |
| 分類・回帰 | 画像・テキスト・音声生成 |
| ロジスティック・SVM・MLP | VAE・GAN・拡散モデル・LLM |
Kingma & Welling。 「潜在変数 $\mathbf{z}$ → デコーダ → データ $\mathbf{x}$」の生成過程を学習。
$$\mathcal{L} = \mathbb{E}_{q(\mathbf{z}|\mathbf{x})}[\log p(\mathbf{x}|\mathbf{z})] - D_{\mathrm{KL}}(q(\mathbf{z}|\mathbf{x}) \| p(\mathbf{z}))$$
再構築誤差 + 事前との KL ダイバージェンス。 reparameterization trick で勾配伝播。
Goodfellow ら。 Generator $G$ と Discriminator $D$ がミニマックスゲーム:
$$\min_G \max_D \mathbb{E}_{\mathbf{x}\sim p_{\text{data}}}[\log D(\mathbf{x})] + \mathbb{E}_{\mathbf{z}\sim p_z}[\log(1 - D(G(\mathbf{z})))]$$
2020 年以降は拡散モデルに主役を譲りつつあるが、 リアルタイム生成では今も有用。
Sohl-Dickstein 2015、 Ho ら 2020 (DDPM)。 「ノイズを徐々に加える順過程 ⇔ ノイズを徐々に除く逆過程」を学習。
$$q(\mathbf{x}_t | \mathbf{x}_{t-1}) = \mathcal{N}(\mathbf{x}_t; \sqrt{1-\beta_t}\mathbf{x}_{t-1}, \beta_t \mathbf{I})$$
$$p_\theta(\mathbf{x}_{t-1}|\mathbf{x}_t) = \mathcal{N}(\mathbf{x}_{t-1}; \boldsymbol{\mu}_\theta(\mathbf{x}_t, t), \Sigma_\theta)$$
NN $\boldsymbol{\mu}_\theta$ がノイズを予測 → 段階的に除去。 通常 50-1000 ステップ。
Stability AI。 潜在空間で拡散(Latent Diffusion, LDM)→ 計算量削減。 OSS で誰でも使える点が革命的。
Transformer Decoder を大規模テキストで事前学習。 次トークン予測:
$$\mathcal{L} = -\sum_t \log p_\theta(x_t | x_{ OpenAI。 GPT-1 (2018)→GPT-2 (2019)→GPT-3 (2020)→GPT-4 (2023)→GPT-4o, o1, o3 (2024-)。 $$p_i = \frac{\exp(z_i/T)}{\sum_j \exp(z_j/T)}$$ $T=1$ で標準、 $T \to 0$ で greedy に近づく、 $T > 1$ で多様性増。5.1 ChatGPT / GPT 系
5.2 主要モデル
5.3 生成サンプリング
5.4 温度パラメータ
「ステップごとに考えなさい」と促すと推論精度が大幅向上(Wei ら 2022)。
1 2 3 4 5 6 7 8 9 | from langchain.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import FAISS loader = PyPDFLoader('ssdse_doc.pdf') docs = RecursiveCharacterTextSplitter(chunk_size=500).split_documents(loader.load()) emb = HuggingFaceEmbeddings(model_name='intfloat/multilingual-e5-base') db = FAISS.from_documents(docs, emb) # query → db.similarity_search → LLM へ注入 |
"a beautiful landscape of Hokkaido in winter" 等のプロンプトで生成し、 学習データの偏り・現実との乖離を検討。
「ChatGPT に聞いたら○○と答えました。」
「Claude 4.5 Sonnet(API 経由、 temperature=0.2)に SSDSE-B 上位 10 県の所得データを与え、 特徴を要約させた。 出力 5 点について、 e-Stat の元データと一致 5/5、 ハルシネーション 0、 ただし 2010 年代の知識で記述された点は注釈を追加。 同じ質問を GPT-4o でも実行し結果を比較(一致率 4/5)。 重要な数値は必ず元データと突合した。」
| 用途 | パッケージ |
|---|---|
| LLM API | openai, anthropic, google-genai |
| OSS LLM | transformers, vllm, llama.cpp, ollama |
| フレームワーク | langchain, llamaindex, dspy, haystack |
| エージェント | langgraph, autogen, crewai |
| ベクトルDB | faiss, chromadb, qdrant, weaviate, milvus |
| 埋め込み | sentence-transformers, openai embeddings, voyage-ai |
| 画像生成 | diffusers (HuggingFace), comfyui |
| 音声 | whisper, coqui-tts, bark |
| Fine-tune | peft, trl, axolotl, unsloth |
| 評価 | lm-evaluation-harness, ragas, deepeval |
| UI | gradio, streamlit, chainlit, open-webui |
A. タスクとコストで変わります。 一般推論:GPT-4 / Claude 4 同等。 長文・倫理・分析:Claude が強い傾向。 速度・コスト:GPT-4o mini や Claude Haiku。 タスクごとに比較を。
A. (1) データの社外流出、 (2) 著作権、 (3) ハルシネーション、 (4) 監査ログ、 (5) 利用者教育、 (6) コスト管理、 (7) 退役計画。
A. (1) 機密データ、 (2) 大量推論で API コストが問題、 (3) オフライン要件、 (4) カスタマイズ要件。 LLaMA・Qwen・Gemma 等が候補。
A. 基礎理論(統計・線形代数・確率)、 評価設計、 ドメイン知識、 倫理判断、 ステークホルダーとのコミュニケーション。 「コードを書く」より「問題を定義する」「結果を批判する」力が重要に。
1 2 3 4 5 6 7 8 9 10 11 | from diffusers import StableDiffusionPipeline import torch pipe = StableDiffusionPipeline.from_pretrained( "stabilityai/stable-diffusion-2-1", torch_dtype=torch.float16, ).to("cuda") prompt = "a beautiful landscape of Mt. Fuji at sunset, photorealistic, 8k" image = pipe(prompt, num_inference_steps=50, guidance_scale=7.5).images[0] image.save("output.png") |
線画・深度マップ・ポーズ等の条件で生成を制御。
1 2 3 4 5 | from diffusers import StableDiffusionControlNetPipeline, ControlNetModel controlnet = ControlNetModel.from_pretrained("lllyasviel/sd-controlnet-canny") pipe = StableDiffusionControlNetPipeline.from_pretrained( "runwayml/stable-diffusion-v1-5", controlnet=controlnet, ).to("cuda") |
少数画像(10〜30 枚)でモデルの好みをカスタマイズ。 個人スタイル・キャラクター学習に使われる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import openai import json tools = [{ "type": "function", "function": { "name": "get_weather", "parameters": { "type": "object", "properties": { "city": {"type": "string"}, "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}, }, }, }, }] res = openai.ChatCompletion.create( model="gpt-4o", messages=[{"role": "user", "content": "東京の天気は?"}], tools=tools, ) call = res.choices[0].message.tool_calls[0] args = json.loads(call.function.arguments) |
1 2 3 4 5 | stream = openai.ChatCompletion.create( model="gpt-4o", messages=[...], stream=True ) for chunk in stream: print(chunk.choices[0].delta.content, end="", flush=True) |
OpenAI Batch API・Anthropic Message Batches で大量推論をコスト半分で実行(24時間以内)。
1 2 3 4 5 6 7 8 9 10 11 12 | # Ollama で簡単起動 # $ ollama pull llama3.2 # $ ollama run llama3.2 # Python から呼び出す import requests res = requests.post('http://localhost:11434/api/generate', json={ 'model': 'llama3.2', 'prompt': '東京について教えて', 'stream': False, }) print(res.json()['response']) |
2026 年時点の参考値(実際は頻繁に変動):
| モデル | 価格目安($/1M tokens) | 用途 |
|---|---|---|
| GPT-4o | 入力 $2.5、 出力 $10 | 高品質汎用 |
| GPT-4o mini | 入力 $0.15、 出力 $0.6 | 大量・低コスト |
| Claude 4 Sonnet | 入力 $3、 出力 $15 | 長文・分析 |
| Claude Haiku | 入力 $0.25、 出力 $1.25 | 速度・コスト |
| Gemini 2.5 Pro | 入力 $1.25、 出力 $5 | 長コンテキスト |
| OSS(自前運用) | GPU コストのみ | 機密データ |
2024 年 9 月 OpenAI o1 発表以降の新潮流。 学習時に「考える時間」を取り入れる。
数学・コード・科学領域で従来 LLM を大幅に超える。 代償として推論コスト増。
SSDSE-B のメタデータを LLM に読み込ませて Q&A できる簡易ボットの構成例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | """SSDSE-B Q&A ボット(最小例)""" import pandas as pd from sentence_transformers import SentenceTransformer import numpy as np # データ準備 df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1) # 各都道府県を「文書」化 docs = [] for _, row in df.iterrows(): text = f"{row['都道府県']}:人口密度 {row['人口密度']:.0f}、 一人当たり県民所得 {row['一人当たり県民所得']:.0f}万円、 高齢化率 {row['高齢化率']:.1f}%、 持ち家比率 {row['持ち家比率']:.1f}%" docs.append(text) # 埋め込み embedder = SentenceTransformer('intfloat/multilingual-e5-base') doc_embs = embedder.encode([f'passage: {d}' for d in docs]) doc_embs = doc_embs / np.linalg.norm(doc_embs, axis=1, keepdims=True) def answer(query, llm_call): """LLM API 呼び出しは別途実装""" q_emb = embedder.encode([f'query: {query}']) q_emb = q_emb / np.linalg.norm(q_emb, axis=1, keepdims=True) sims = q_emb @ doc_embs.T top5 = sims[0].argsort()[-5:][::-1] context = chr(10).join([docs[i] for i in top5]) prompt = f"""以下のデータを参考に質問に答えてください。 数値は必ずデータに基づいて答えてください。 データ: {context} 質問: {query} """ return llm_call(prompt) # 使用例 # print(answer("人口密度が高い県は?", openai_call)) |
SSDSE-B(都道府県・年次パネル、ID-2003〜2020)は、 47都道府県 × 18年 = 846行 × 約100列の中規模データ。 生成AI を活用すると、 探索的分析の高速化とレポート生成の自動化が可能。 ここでは「人口10万人当たり医師数(医療指標)」を題材に LLM・RAG・コード生成の3活用パターンを紹介します。
入力プロンプト:「SSDSE-B.csv を読み込み、 2020年(最新年)の 医師数_人口10万対 上位5県と下位5県を抽出するコードを書いて」
期待される LLM 出力:
1 2 3 4 5 6 7 8 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2023.csv', encoding='shift_jis', header=[0,1]) df.columns = ['_'.join(c).strip() for c in df.columns] df_2020 = df[df['年度_Year'] == 2020] top5 = df_2020.nlargest(5, '医師数_人口10万対')[['都道府県_Prefecture', '医師数_人口10万対']] bottom5 = df_2020.nsmallest(5, '医師数_人口10万対')[['都道府県_Prefecture', '医師数_人口10万対']] print('上位5県:'); print(top5) print('下位5県:'); print(bottom5) |
典型的な結果(2020年):上位 = 京都・徳島・高知・福岡・東京(300〜350人)、 下位 = 埼玉・茨城・千葉・福島・新潟(180〜200人)。 「西高東低」の傾向がここから見えてきます。
SSDSE-B の列定義書(README.pdf)を chunk 化して埋め込みベクトル化し、 ベクトルDB(FAISS/Chroma)に格納。 「医師数の定義は?」と質問すると、 README 該当ページを検索 → LLM が回答を整形。
典型回答:「医師数_人口10万対 は、 各都道府県の医療施設に従事する医師の総数を、 当該都道府県の人口10万人で割った値です。 出典:厚生労働省『医師・歯科医師・薬剤師統計』。 隔年集計のため、 2018年・2020年などの偶数年に値があります」のように、 幻覚(hallucination)を抑えつつ原典に基づく回答が得られる。
分析結果(数値表)を LLM に渡し、 「以下の結果から3つの考察を、 因果と相関を区別しつつ書いて」と依頼。
LLM 出力例:「(1) 医師数上位は西日本に集中。 これは医学部の歴史的配置(旧帝大・私立医大)と関連する可能性。 (2) 関東圏(埼玉・千葉)は医師数が少なく、 人口集中による分母効果が考えられる。 (3) ただしこれは相関的観察であり、 医療アクセスの実態(病床数・救急体制)まで踏み込まないと因果は語れない」。 下書きとして有用だが、 必ず人間が事実確認・出典追加を行う。
⚠️ 注意:LLM はもっともらしい数値を捏造する(hallucination)。 「2020年の埼玉県の医師数は190人」と LLM が答えても、 必ず元の CSV で検算する。 数値・出典・年度は必ず人間が確認。
生成AI 周辺のタスクは LLM API 一択ではなく、 用途によっては「軽量な scikit-learn / scipy」で十分な場面も多い。 ここでは「文書の類似度計算」「クラスタリング」「埋め込み(embedding)」「分類」の4タスクで、 ライブラリの使い分けを示します。
「RAG の前にまず古典的手法で十分か検証」したい時、 scikit-learn の TF-IDF が最速。
1 2 3 4 5 6 7 8 | from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity docs = ['都道府県の医師数を分析する', '医療体制の地域差を考察する', 'GDP の年次推移を見る'] vec = TfidfVectorizer() X = vec.fit_transform(docs) sim = cosine_similarity(X[0:1], X) print(sim) # [[1.0, 0.45, 0.0]] のように類似度行列が得られる |
TF-IDF は語の表層一致のみ。 意味的類似度を扱うには Sentence-BERT。
1 2 3 4 5 6 | from sentence_transformers import SentenceTransformer model = SentenceTransformer('intfloat/multilingual-e5-small') emb = model.encode(docs) # (3, 384) ndarray # scipy で距離計算 from scipy.spatial.distance import cosine print(1 - cosine(emb[0], emb[1])) # 0.7-0.9 程度 |
埋め込みを取得した後の文書クラスタリングは、 古典的な KMeans で十分。
1 2 3 4 | from sklearn.cluster import KMeans km = KMeans(n_clusters=5, random_state=42, n_init=10) labels = km.fit_predict(emb) print(labels) # 各文書がどのクラスタに属するか |
API コストを抑えたい・データを外部送信したくない場合は、 OSS LLM(Llama 3、Qwen、Gemma 等)をローカルで。
1 2 3 4 | from transformers import pipeline pipe = pipeline('text-generation', model='google/gemma-2-2b-it', device_map='auto') out = pipe('日本の医療体制の特徴を3点挙げてください', max_new_tokens=200) print(out[0]['generated_text']) |
LLM 出力の品質を統計的に比較するには scipy が便利。 例:BLEU スコアの分布比較を Wilcoxon 検定で。
1 2 3 4 5 | from scipy.stats import wilcoxon bleu_model_a = [0.45, 0.52, 0.48, 0.41, 0.55] bleu_model_b = [0.50, 0.58, 0.53, 0.47, 0.60] stat, p = wilcoxon(bleu_model_a, bleu_model_b) print(f'p = {p:.4f}') # 有意なら Model B が優位と結論 |