前回の記事も書きましたが、 Golangのrandパッケージでは、 一次元正規分布の乱数生成が可能です。 今回は、多次元正規分布から乱数を生成する方法についてまとめます。
どうやって生成するか
まずPRMLから引用します。
平均
,共分散
を持つ多変量ガウス分布に従うベクトル値の変数を生成するには,
の形を取るコレスキー分解(Cholesky decomposition)を用いればよい(Press et al., 1992). このとき, もし
がベクトル値の確率変数であり, その各要素が独立で, 平均0, 分散1のガウス分布に従うとすれば,
は平均
, 共分散
のガウス分布に従う.
rand.NormFloat64()
は、まさに平均0、分散1の一次元正規分布の乱数を生成してくれるので、
与えられたをコレスキー分解すれば多次元正規分布からの乱数生成ができます。
gonumのmatパッケージでは、Cholesky
型のFactorize
メソッドでコレスキー分解ができるので、こちらを使って多次元正規分布からの乱数を生成します。
コード
実装は以下です。MultiNorm
関数として実装しています。
散布図を描くコードも含んでいるので、少し長いです。。。
gist3609a47a7f572bd8e479ef120dae3f0e
実行結果
References
- Package rand - The Go Programming Language
- Package mat - Godoc
- Bishop, C. M. "パターン認識と機械学習." パターン認識と機械学習 (2008).
- 多次元正規分布の発生 - frontier45
- Golangで正規乱数 - 逆さまにした