
2025/12/14 5:19
I fed 24 years of my blog posts to a Markov model
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
## Summary この記事では、Susam Pal(2025年12月13日)によって約30行のPythonで書かれた最小限のマルコフ連鎖テキスト生成器 *Mark V. Shaney Junior* を紹介します。GitHub(github.com/susam/mvs)とCodeberg(codeberg.org/susam)にホスティングされています。このプログラムは速度よりも可読性を優先しており、トリグラム(単語のペアをキーとして、その後続する単語のリストを保持)を使用して擬似テキストを生成します。学習データは著者自身のブログ投稿約200件(約20万語)から取得されており、すべてのコメント500件(約4万語)は除外されています。 READMEにはサンプル利用例が示されており、例えば `./mvs < susam.txt` のように実行するとゴミ文字の出力が得られます。デフォルトでは1回の実行で最大100語まで生成しますが、コマンドラインフラグでキーオーダー(既定は2)を変更できます。高いオーダーになるほど文がより一貫性を持ちますが、完全に同じテキストをコピーすることもあります。著者はマルコフモデルを数式で簡潔に説明し(`P(X_{n+1}|X_n)=P(X_{n+1}|X_n,X_{n-1},…)`)、ディープラーニングを用いる大型言語モデルと対比しています。 軽量かつ理解しやすいため、このツールは大規模AIシステムのオーバヘッドなしで言語生成に挑戦したいホビイストや学生向けの迅速なプロトタイプや教育支援として活用できます。
本文
サスマ・パル著 – 2025年12月13日
昨日、github.com/susam/mvs に Mark V. Shaney Junior と呼ばれる小さなプログラムを公開しました。
これは1980年代の伝説的な Mark V. Shaney プログラムに触発された、マルコフテキスト生成器の最小実装です。
詳細は Wikipedia 記事 Mark V. Shaney をご覧ください。本稿では自作の実装を紹介し、動作原理といくつかの結果を共有します。
目次
- レクリエーションプログラミング
- ガビリッシュ(意味不明語)
- マルコフ性
- 更なるガビリッシュ
レクリエーションプログラミング
昨日公開したプログラムは Python で約30行しかなく、効率よりもシンプルさを重視しています。
マルコフモデルに未経験でも、全コードを読めば20分以内に理解でき、完全に意味が掴めます(以下で詳しく解説します)。
趣味として「探索的プログラミング」に取り組むことが多いです。特定の問題解決ではなく、アイデアやテーマを遊び心で探求する小さなスクリプトを書きます。毎回最後に新しい状態空間をエンコードした実験を作り、数百本の極小スクリプトをディスク上に保管しています。
時々その中から一つを仕上げ、Git リポジトリに README.md と CHANGES.md を添えて github.com/susam や codeberg.org/susam で共有します。昨日投稿した Mark V. Shaney Junior はまさにそのような試みの結果です。
ガビリッシュ
README にプログラムが生成するガビリッシュ(意味不明語)の例を掲載しています。
最初の数はチャールズ・ディケンズの A Christmas Carol から生成したもので、ディケンズらしい冗長な語句を多用している点でテストに適しています。ここでは抜粋しませんが、README の Gibberish セクションで確認できます。
プロジェクト公開後、ブログの全24年分(約200,000語)を入力したときに出るガビリッシュを試してみました。例:
$ ./mvs < susam.txt while a query replace operation is approved by the user. The above variable defines the build job...
…というように、200件以上の投稿(約200,000語)を消化した後に出るテキストです。ブログにはコメントもありますが(≈40,000語、500件超)、トレーニング時には除外しました。
別例:
$ ./mvs < susam.txt enjoy asking "what happens if" and then type M‑x zap-up-to-char RET b. The buffer for this specific video...
特に不条理でおかしみのあるもの:
$ ./mvs < susam.txt Then open a new Lisp source file and the exact answer could harm students' self-esteem…
リスクを示唆するような発言は意図していません。生成器は以前の投稿からフレーズをそのまま拾っただけです。
マルコフ性
デフォルトではトライグラム(3語連)を対象にします。
最初の2語がキー、3番目の単語がそのキーに付随するリストへ追加されます。このマップこそモデルであり、隣接する語対とその直後に続く語を記録しています。
生成器は次のように動きます。
- キー(語対)をランダムに選択。
- そのキーに付随するフォロワーから均等に1つ選ぶ。
- 新たに選んだ単語と前回のペアの後ろ2語で新しいペアを作り、ステップ2へ戻る。
- フォロワーが無くなるか、デフォルトの上限(100語)に達したら終了。
これだけでアルゴリズムは完結します。まさに「hello, world」のようなシンプルさです。
同じトライグラムが複数回出現すると、その3番目の単語も重複して記録されるため、頻度の高いフォロワーを自然と優先します。頻度で管理する方法もありますが、ここでは省略しています。
形式的には離散時間確率過程として [ P(X_{n+1}\mid X_n, X_{n-1}, \ldots, X_1)=P(X_{n+1}\mid X_n) ] が成り立ちます。ここで (X_n) は語対 ((w_{n-1}, w_n)) です。トレーニングデータは転移確率を推定し、マルコフ性は生成時に適用されます。
更なるガビリッシュ
2025年、LLM(大規模言語モデル)の人気が高まる中、シンプルなマルコフモデルは印象的ではありません。
LLM と違い、グローバル構造や長距離依存を捉えられず、局所的単語遷移統計にのみ頼ります。それでもその簡潔さが言語モデリングへの入り口として有用です。
コマンドラインでキーサイズ(モデルのオーダー)を変更できます。デフォルトは2ですが、3や4にすると少しまとまりのあるテキストになります:
$ ./mvs 4 < susam.txt It is also possible to search…
順序が高すぎると、生成される文章は乾燥して事実をそのまま引用するようになります。
最後に初期プロンプト付きの例です:
$ ./mvs 2 100 'Finally we' < susam.txt Finally we divide this number by a feed aggregator for Emacs‑related blogs…
これが、もし私が「ガビリッシュ」を話すとしたらそうなるでしょう。