解説 逆関数法
逆関数法とは、一様乱数を変換し、生成したい分布に従うサンプルへ変える手法のこと。
具体的には、目的の分布の累積分布関数$F$の逆関数$F^{-1}$に、$[0,1]$上の一様乱数$u$を入力すると、目的の分布に従うサンプルが得られる。
逆関数法を使う動機
何かの分布に従うデータを作り出したいとき、どのようにすれば良いだろうか。
一様分布に従う乱数であれば、様々な生成器が存在する。(有名な手法に、線形合同法やメルセンヌ・ツイスタがある。)これらの生成器は、ランダム性を向上させるために様々な研究がされてきた。
下の図は、$[0,1]$上の一様乱数を10000個生成したもののヒストグラム。
指数分布に従うデータを作り出したい場合はどうだろう。直接、指数分布を生成することは容易ではない。そこで、性能の良い一様乱数生成器の出力を変換して、指数分布に従うようにすることを試みる。
言い換えると、$[0,1]$上の一様変数$U$と、指数関数に従う確率変数$X$の対応関係を見つけることを目的とする。
累積分布関数が、値域が$[0,1]$あったことを思い出して欲しい。累積分布関数が、指数分布から$[0,1]$への対応を表すので、逆の操作を行えば$[0,1]$上の一様分布から指数分布を作り出せそうだ。この発想が実際に正しいことは下の定理で確認する。
なお、この方法を使えば、指数分布だけでなく、様々な分布に従うサンプルを作り出すことができる。
定理
$U$を$[0,1]$上の一様分布に従う確率変数とする。目的の分布の累積分布関数$F$が狭義単調増加で連続なら、$F^{-1}(U)$は目的の分布に従う。ただし、$F^{-1}$は$F$の逆関数。
証明
任意の実数$x$に対して以下の等式が成り立つ。
\begin{align}
F(x)
&= P(U \leq F(x)) \\
&= P(F^{-1}(U) \leq F^{-1}(F(x))) \\
&= P(F^{-1}(U) \leq x)
\end{align}
式の初めと終わり$F(x) = P(F^{-1}(U) \leq x)$を見ると、累積分布関数の定義より、確率変数$F^{-1}(U)$は、累積分布関数$F$に従っている。
証明の補足説明
-
$X=F^{-1}(U)$としてやれば、$X$が求めたい分布に従う確率変数となる。
-
$U$は確率分布なので、$F^{-1}(U)$も確率変数となる。
-
1行目:$F(x) = P(U \leq F(x))$が成り立つのは、一様分布の性質$x=P(U \leq x)$による。
-
狭義単調増加関数なので、逆関数は必ず存在する。
Pythonによる実装
指数分布$Exp(\lambda)$を生成する。指数分布の密度関数は以下の通りであり、逆関数が容易に求められる。
\begin{align}
F(x) &= 1 - e^{-\lambda x} \\
F^{-1}(u) &= -\frac{1}{\lambda} \log(1-u)
\end{align}
import numpy as np
import matplotlib.pyplot as plt
# 指数関数の母数lambを0.5とする.
lamb = 0.5
def F_inverse(u):
return -np.log(1-u) / lamb
rng = np.random.default_rng(seed=42)
u = rng.random(10000) # [0,1]一様分布に従う10000個の変数.
# 逆関数法により、指数分布に従う乱数xにする.
x = F_inverse(u)
# visualize
plt.hist(x, bins=30)
plt.show()
概ね指数分布に似たグラフが出力された。
逆関数法で様々な分布が再現できるが、たとえば正規分布のように累積分布関数の逆関数が簡単に表せない分布では、この方法を使うことはできない。