pythonで正規分布の計算をする


python で 正規分布にまつわる計算を実施してみました。
結果を以下に記載します。


使用するライブラリについて

基本的に、自前実装しないを方針で、以下ライブラリを使用しました。
* random
* numpy.random.normal * scipy.stats.norm


ライブラリの基本的な使い方

random を使用する

random.gauss を使用使って、正規分布に従う乱数を生成できます。

  • 乱数生成
import random
mu = 0
sigma = 1
random.gauss(mu, sigma)
1.0903819325538264
  • 正規分布の取り得る値を持つ配列を返す
    拡張for文で、必要な数分、要素数を指定します。
import random
mu = 0
sigma = 1
[random.gauss(mu, sigma) for i in range(1000)]
[-0.0728457923715639,
 1.308944314547083,
 0.09881518928775246,
 0.7753370505388919,
 -0.8876683122583319,
 1.8481235067792638,
 -0.03154843219728535,
 -0.1610106160180886,
 0.8242394148273418]
import random
mu = 0
sigma = 1
normals = [random.gauss(mu, sigma) for i in range(1000)]

# 正規分布のグラフを描画
import matplotlib.pyplot as plt
# ヒストグラムを描画
count, bins, ignored = plt.hist(normals, 30, normed=True)
# 折れ線グラフを描画
plt.plot(bins, 1/(sigma * np.sqrt(2 * np.pi)) *
                np.exp( - (bins - mu)**2 / (2 * sigma**2) ),
          linewidth=2, color='r')
plt.show()

png

numpy.random.normal を使用する

numpy.random.normal を使って、正規分布に従う乱数を生成できます。

  • 正規分布の取り得る値を持つ配列を返す
import numpy as np
mu = 0
sigma = 1
size = 1000
# locは平均、scaleは標準偏差、sizeは返す配列の形。
normals = np.random.normal(mu ,sigma, size)
print(normals)
[  1.01033567e+00   7.16766242e-01  -1.17057842e+00  -5.20022675e-01
  -6.10770332e-01  -7.02457841e-01  -1.44408136e+00  -1.32630375e+00
   5.16906691e-01   6.44242873e-01  -4.88433030e-01  -1.69560732e-01
   4.13530423e-01   8.51932472e-01   1.46014689e+00   4.69242571e-01
  -1.95000772e+00  -8.91333035e-01   5.20799068e-01   8.56964166e-01
  -1.71879570e+00   7.24289479e-02   1.87453882e-01   1.67373464e+00
  -7.08281631e-02  -2.87953874e+00   1.50559481e+00  -3.52197611e-01
   6.68673056e-01   4.45857074e-01  -4.43909707e-01   2.40777206e-01]
  • 正規分布のグラフを描画する
import numpy as np
# 平均 1
mu = 0
# 標準偏差
sigma = 1
#  戻り値のサイズ
size = 1000
normals = np.random.normal(mu , sigma, size)

# 正規分布のグラフを描画
import matplotlib.pyplot as plt
# ヒストグラムを描画
count, bins, ignored = plt.hist(normals, 30, normed=True)
# 折れ線グラフを描画
plt.plot(bins, 1/(sigma * np.sqrt(2 * np.pi)) *
                np.exp( - (bins - mu)**2 / (2 * sigma**2) ),
          linewidth=2, color='r')
plt.show()

png

scipy.stats.norm を使用する

正規分布に関わる各種の値を取得できます。

%matplotlib inline

from scipy.stats import norm
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 1)

# 平均、分散、歪度、尖度 を取得
mean, var, skew, kurt = norm.stats(moments='mvsk')

print("平均", mean)
print("分散", var)
print("歪度", skew)
print("尖度", kurt)

x = np.linspace(norm.ppf(0.01), norm.ppf(0.99), 100)
# 折れ線グラフを描画
ax.plot(x, norm.pdf(x),'r-', lw=5, alpha=0.6, label='norm pdf')
x
rv = norm()
# 折れ線グラフを描画
ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf')

# ヒストグラムを描画
ax.hist(r, density=True, histtype='stepfilled', alpha=0.2)
ax.legend(loc='best', frameon=False)
plt.show()
平均 0.0
分散 1.0
歪度 0.0
尖度 0.0

png


正規分布の信頼区間を求める

scipy.stats.norm.interval で 信頼区間を求めることができます。

  • 平均0、標準偏差 1 の 正規分布の 95%信頼区間を求める
from scipy.stats import norm
# 信頼区間
alpha = 0.95
# 切片
loc = 0
# 標準偏差
scale = 1
a,b = norm.interval(alpha=alpha, loc=loc, scale=scale)
print(a,b)
-1.95996398454 1.95996398454
  • 平均0、標準偏差 1 の 正規分布の 99%信頼区間を求める
from scipy.stats import norm
# 信頼区間
alpha = 0.99
# 切片
loc = 0
# 標準偏差
scale = 1
a,b = norm.interval(alpha=alpha, loc=loc, scale=scale)
print(a,b)
-2.57582930355 2.57582930355
  • 平均0、標準偏差 2 の 正規分布の 68%信頼区間を求める
from scipy.stats import norm
# 信頼区間
alpha = 0.68
# 切片
loc = 0
# 標準偏差
scale = 2
a,b = norm.interval(alpha=alpha, loc=loc, scale=scale)
print(a,b)
-1.98891576642 1.98891576642

正規分布の zスコアを求める

norm.ppd で、指定した p 点に対するzスコアを求めることができます。

from scipy.stats import norm
# 95%点でのzスコア
print(norm.ppf(q=0.95, loc=0, scale=1))

# 50%点でのzスコア
print(norm.ppf(q=0.50, loc=0, scale=1))
1.64485362695
0.0

正規分布の上側確率を求める

scipy.stats.norm.sf で上側確率を求めることができます。 生存関数ともいうのかもしれません。

from scipy.stats import norm
# zスコア 2.09 に対する 上側確率
print(norm.sf(x=2.09, loc=0, scale=1.00))

# zスコア 1.64485362695 に対する 上側確率
print(norm.sf(x=1.64485362695, loc=0, scale=1.00))
0.0183088998517
0.0500000000002

参考

以下の記事が参考になりました。
* NumPyのrandomを使った配列操作・乱数生成方法まとめ - DeepAge * numpy.random.normal — NumPy v1.13 Manual * 9.6. random — 擬似乱数を生成する — Python 3.6.5 ドキュメント
* scipy.stats - scipyの統計関数群のAPI - keisukeのブログ

以上です。

コメント