はじめに
生成モデルとは
生成モデルとは、データの分布を学習し、そこから新しいデータを生成するモデルです。
通常の機械学習モデル(識別モデル)が「この画像は猫か犬か」を判定するのに対し、生成モデルは「猫の画像」そのものを新たに作り出します。学習済みの分布から新しいサンプルを生成できる点が最大の特徴です。
どのような応用がされているか
生成モデルは現在、多くの分野で活用されています。
- テキスト生成: ChatGPT、Claude などの大規模言語モデル(LLM)
- 画像生成: Stable Diffusion、DALL-E などの画像生成AI
- 音楽生成: 楽曲の自動作曲
- コード生成: GitHub Copilot などのコード補完ツール
問題設定
問題設定
本記事では「日本語テキストの生成」を問題として扱います。具体的には、学習用のテキスト(コーパス)を読み込み、そのスタイルや語彙を模倣した新しい文章を生成します。
使用するコーパスは夏目漱石「吾輩は猫である」の冒頭部分です。
"""
吾輩は猫である。名前はまだない。
どこで生れたか頓と見当がつかぬ。
何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。
吾輩はここで始めて人間というものを見た。
しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。
この書生というのは時々我々を捕えて煮て食うという話である。
吾輩は猫である。猫の名前は何でもいい。
猫はどこでも寝ることができる。猫は自由な生き物だ。
人間は猫を見て笑う。猫は人間を見て考える。
吾輩は考える猫である。考えることは生きることだ。
"""
何を目的にしているか
生成モデルの中で最もシンプルな実装であるマルコフ連鎖を通じて、「確率分布からのサンプリングによってテキストを生成する」という生成モデルの本質を理解することが目的です。
この仕組みはChatGPTやClaudeのような最新のLLMにも共通する考え方です。
マルコフ連鎖とは
マルコフ連鎖の概要
マルコフ連鎖とは、次の状態が直前の状態だけに依存する確率過程のモデルです。この性質を「マルコフ性」と呼びます。
テキスト生成に当てはめると、以下のように表現できます。
P(次の文字 | これまでの全文字) ≈ P(次の文字 | 直前のN文字)
すべての過去の文脈を考慮する代わりに、直前のN文字だけを見て次の文字を予測します。
マルコフ連鎖の仕組み
マルコフ連鎖によるテキスト生成は、学習と生成の2つのフェーズで構成されます。
① 学習フェーズ(遷移確率行列の構築)
コーパスを文字単位で読み込み、「ある文字の次にどの文字が来るか」をカウントして確率に変換します。
コーパス: 吾輩は猫である。吾輩は考える。
「吾」の次 → 「輩」が2回 → 確率 1.00
「輩」の次 → 「は」が2回 → 確率 1.00
「は」の次 → 「猫」が1回、「考」が1回 → 各 0.50
② 生成フェーズ(サンプリング)
確率分布に従ってランダムに次の文字を選び、これを繰り返すことで文章を生成します。
「吾」→「輩」→「は」→ サイコロ →「猫」or「考」→ ...
この「確率分布からのサンプリング」が生成モデルの本質です。LLMも同じ仕組みで文章を生成しています。
実験
実験データ
夏目漱石「吾輩は猫である」の冒頭10文(253文字)をコーパスとして使用します。
トークン化
日本語はスペースで単語が区切られないため、文字単位でトークン化します。1文字を1トークンとして扱い、コーパス全体を文字の列に変換します。
def tokenize(text):
return [ch for ch in text if ch.strip()]
# 例
tokens = ['吾', '輩', 'は', '猫', 'で', 'あ', 'る', '。', ...]
確率変換
各文字の後にどの文字が来るかをカウントし、確率に変換して遷移確率行列を構築します。
# 1階マルコフ連鎖(直前1文字を見る)
('吾',) → {'輩': 1.00}
('は',) → {'猫': 0.50, '考': 0.25, 'こ': 0.25}
# 2階マルコフ連鎖(直前2文字を見る)
('吾', '輩') → {'は': 1.00}
nを大きくするほど文脈を長く保持できますが、データが少ない場合は遷移パターンが少なくなります。
テキスト生成
構築した遷移確率行列を使い、確率に従って次の文字をサンプリングし続けることで文章を生成します。
1階マルコフ連鎖の生成例:
[1] 吾輩はここで始めて人間というものを見た。
[2] 吾輩は考える猫である。
2階マルコフ連鎖の生成例:
[1] 吾輩はここで始めて人間というものを見た。
[2] 吾輩は猫を見て笑う。
温度パラメータとは
温度パラメータ(Temperature)は、確率分布の「なだらか度」を調整するパラメータです。LLMのAPIでも同じパラメータが使われています。
temperature < 1.0: 高確率な文字がさらに選ばれやすくなる(保守的)temperature = 1.0: 元の確率分布のままtemperature > 1.0: 確率差がなだらかになる(多様・ランダム)
計算式は各確率を 1/T 乗して再正規化します。Tが小さいほど高確率な文字に集中し、Tが大きいほど全文字が均等に選ばれやすくなります。
温度パラメータごとの結果
| temperature | 傾向 |
|---|---|
| 0.3 | コーパスに忠実。同じ表現が繰り返されやすい |
| 1.0 | 学習した確率分布そのままの生成 |
| 2.0 | 多様な文章が出るが、文法的に不自然になりやすい |
以下は実際に生成した結果です(開始トークン:「吾輩」、2階マルコフ連鎖)。
temperature = 0.3(保守的)
[1] 吾輩は猫である。猫は自由な生き物だ。
[2] 吾輩は猫である。吾輩は猫である。
[3] 吾輩は猫である。猫は人間は猫である。
最も確率の高い遷移を繰り返すため、同じフレーズが反復されやすくなっています。
temperature = 1.0(標準)
[1] 吾輩は猫である。考える。
[2] 吾輩はここで始めて人間という人間を見た。
[3] 吾輩はここで始めて人間は猫である。
学習した確率分布そのままで生成されます。コーパスにある語彙を使いつつ、ある程度の多様性があります。
temperature = 2.0(創造的)
[1] 吾輩は猫であったそうだ。
[2] 吾輩はここで始めて人間という人間を見た。
[3] 吾輩はここで始めて人間は猫である。
確率の低い遷移も選ばれやすくなるため、コーパスには少ない組み合わせが出現します。ただし今回はコーパスが小さいため、temperature=1.0との差は限定的です。
まとめ
マルコフ連鎖によるテキスト生成を通じて、生成モデルの本質である「確率分布の学習とサンプリング」を確認しました。
| 項目 | 内容 |
|---|---|
| 学習 | コーパスから遷移確率行列を構築(カウントのみ) |
| 生成 | 確率分布に従ってサンプリングを繰り返す |
| 温度パラメータ | 分布のなだらか度を調整(LLMと同じ概念) |
| 限界 | 直前N文字しか参照できない・コーパス外の表現は生成不可 |
マルコフ連鎖はニューラルネットを使わない最もシンプルな生成モデルですが、その核心にある「確率分布からのサンプリング」はChatGPTやClaudeと変わりません。
終わりに
マルコフ連鎖には「直前N文字しか文脈を保持できない」という根本的な限界があります。次の記事では、この問題をニューラルネットワークで解決したRNN(リカレントニューラルネットワーク)を実装します。
RNNは隠れ状態という「記憶」を持ち、過去の全文脈を引き継ぎながらテキストを生成します。マルコフ連鎖との違いを実装レベルで確認していきます。

