Wizard Notes

音楽信号解析の技術録、音楽のレビューおよび分析、作曲活動に関する雑記です

マルコフ連鎖でコード進行を自動生成(Python実装)

この記事をシェアする

伝統的な自動作曲・文章生成システムで使われている代表的アルゴリズムとして、マルコフ連鎖があります。

アカデミックな研究やアプリケーションとしては常套手段なのですが、Web上には音楽での 利用例・実装例があまりないようです。

そこで、マルコフ連鎖を使ったコード進行の自動生成を作ってみたので紹介します。

マルコフ連鎖によるアルゴリズムの設計

マルコフ連鎖の概要と設計方針

マルコフ連鎖に関する説明はWeb上にたくさんあるので、要点だけ説明します。

(単純)マルコフ連鎖は、将来(次)の状態は、現在の状態のみで決まるという系列です。

コード進行で言うなら、次の和音は、現在の和音によって確率的に決まるという仮定に基づいています*1

例えば、3つの和音 {C, F, G} が以下のような確率で状態遷移するとします。

f:id:Kurene:20191109070919p:plain
和音の状態遷移の例

この状態遷移に関する遷移行列は次のように書けます。

f:id:Kurene:20191109071015p:plain
遷移行列

この遷移行列をPとすると、k番目の状態を漸化式で表すことができます。

f:id:Kurene:20191109110628p:plain
漸化式

つまり、

  • 初期状態: 最初の和音
  • 遷移行列: 各和音が、次にどの和音に進行しやすいか

を設定すれば、先ほどの漸化式を用いてコード進行を自動生成することができます

なお、遷移行列の具体的な遷移確率を設定する方法は、(1) データを集めて事前学習、(2) 人が手動で調整の2つがあります。

(1) だと、そのデータっぽい感じにコード進行を生成できますが、データの収集・処理をする必要があります*2。また、状態が多くなると、その分、多くのサンプルを集めないとアルゴリズムのパフォーマンスが出にくいです。

一方で (2) だと、データ収集・処理の必要がなくお手軽ですが、アルゴリズムのパフォーマンスをよくするためには手間暇かけて値を調整する必要があります。遷移状態が増えるとしんどいです。

データだけだと信用しきれない部分がある*3ので、突き詰めるなら (1) + (2) のハイブリッドになると思います。

Python での実装

実行結果

f:id:Kurene:20191109093709p:plain

それっぽいコードが生成されています。

また、漸化式より算出した定常分布は、遷移行列の固有値問題を解いて得た定常分布とほぼ一致しています。

なお、1万回の遷移結果を保存し、確率密度関数として正規化した行列が、遷移行列とほぼ一致していることを確認できました。 f:id:Kurene:20191111110527p:plain

デモ

和音の種類を増やしました(Cmajor Scale におけるダイアトニックコード)。

参考文献

補足

マルコフ連鎖の関連技術

Googleの強力な検索エンジンのベースアルゴリズムであった PageRankマルコフ連鎖に基づいています。

ohke.hateblo.jp

固有値問題として定常分布の導出するときの注意点

以下の記事にまとめました。

www.wizard-notes.com

Numpy.linalg.eig()とかで算出するときは、注意が必要です。

*1:より過去を参照する場合は、N階マルコフ連鎖があります。結局のところ、N階マルコフ連鎖は組み合わせによって単純マルコフ連鎖で表現できます

*2:各和音ごとに、次に進行する和音のヒストグラムを計算→正規化して確率密度関数化→Pの行ベクトル

*3:外れ値や汚れたデータへの対処