ヒストグラムと確率密度関数を重ねて描写したいと思ったときに最初きれいに重ねることができなかったのでそのときの解決策をメモとして残す。
原因
numpy.randomで生成される乱数は生成数によってはヒストグラムの面積が1よりも大きくなってしまうこと。
解決策
- ヒストグラムを標準化
- 確率密度関数の面積をヒストグラムに合わせる
ヒストグラムを標準化
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
n = 2000 #データ数
data = np.random.randn(n)
plt.hist(data, range=(-3, 3), bins=60, alpha=0.5, density=True)
#階級幅0.1 総データ数2000, 縦軸を相対度数密度としたヒストグラム
x = np.linspace(-3, 3, 61)
#0.1刻みの数列を生成
plt.plot(x, norm.pdf(x), c='r')
縦軸を度数ではなく相対度数密度とすることで面積を1にした。
階級幅w, 階級n, 度数D_nとした元の面積S\\
S=\sum_{n}D_nw\\
相対度数は\\D_n^R=\frac{D_n}{\sum_{n}D_n}\\
相対密度度数は\\
\begin{aligned}
D_n^{'}&=\frac{D_n^R}{w}\\
&={\frac{D_n}{\sum_{n}D_n}} \times {\frac{1}{w}}\\
&=\frac{D_n}{S}\\
\end{aligned}\\
相対密度度数を用いたヒストグラムの面積S^{'}\\
\begin{aligned}
S^{'}&=D_n^{'}\\
&=\frac{\sum_{n}D_n}{S}\\
&=\frac{S}{S}\\
&=1
\end{aligned}
確率密度関数の面積をヒストグラムに合わせる
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
n = 2000 #データ数
data = np.random.randn(n)
plt.hist(data, range=(-3, 3), bins=60, alpha=0.5)
#階級幅0.1 総データ数2000, 縦軸を相対度数密度としたヒストグラム
x = np.linspace(-3, 3, 61)
#0.1刻みの数列を生成
plt.plot(x, n*0.1*norm.pdf(x), c='r')
#0.1は階級幅
確率密度関数をヒストグラムの面積倍することで面積を合わせた。
確率密度関数f(x), ヒストグラムの総データ数n,階級幅wとする。\\
f(x)は以下の式を満たす\\
\begin{aligned}
\int f(x) dx = 1
\end{aligned}\\
両辺にn\times wをかけることでヒストグラムの面積n\times wにすることができる。\\
よって変換後の確率密度関数f^{'}(x)は\\
f^{'}(x)=n\times w \times f(x)