Pythonでnumpyを使って正規分布を実装する方法

スポンサーリンク

統計学の分野でなくとも、「正規分布」という言葉を目にしたことがあるはずです。

確率分布とは、ある確率変数が取りうる値を得る可能性を記述した統計関数です。

つまり、あるパラメータからランダムに値を拾ったときに、どのような値を取り得るかということです。

確率分布には、離散的なものと連続的なものがある。

ある都市で、20〜30歳の成人の身長が4.5フィートから7フィートの範囲にあるとします。

もし、無作為に1人の大人を選んで、その人の(性別は身長に影響しないと仮定して)身長はいくらか、と尋ねられたらどうでしょう?身長がどうなるかなんて、わかるわけがない。

しかし、その街の大人の身長の分布がわかれば、最も確率の高い結果に賭けることができる。

スポンサーリンク

正規分布とは

正規分布は、ガウス分布、あるいは有名なベル曲線とも呼ばれています。

どちらの言葉も同じように使われますが、意味は同じです。

正規分布は、連続した確率分布です。

正規分布の確率密度関数(pdf)です。

# Importing required libraries
 
import numpy as np
import matplotlib.pyplot as plt
 
# Creating a series of data of in range of 1-50.
x = np.linspace(1,50,200)
 
#Creating a Function.
def normal_dist(x , mean , sd):
    prob_density = (np.pi*sd) * np.exp(-0.5*((x-mean)/sd)**2)
    return prob_density
 
#Calculate mean and Standard deviation.
mean = np.mean(x)
sd = np.std(x)
 
#Apply function to the data.
pdf = normal_dist(x,mean,sd)
 
#Plotting the Results
plt.plot(x,pdf , color = 'red')
plt.xlabel('Data points')
plt.ylabel('Probability Density')

ここで、μ = 平均、σ = 標準偏差、x = 入力値。

用語説明

  • 平均値 – 通常の平均値。平均 – 総ポイントの合計を総ポイント数で割ったもの。
  • 標準偏差 – 標準偏差は、データがどのように “分散 “されていることを教えてくれます。標準偏差は、観測された各値が平均値からどの程度離れているかを示す尺度です。

難しそうに見えますね?でも、とても簡単なことなのです。

1. 正規分布の実装例

以下のコードを見てみましょう。

このデモでは、numpy と matplotlib を使用します。

# import required libraries
from scipy.stats import norm
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sb
 
# Creating the distribution
data = np.arange(1,10,0.01)
pdf = norm.pdf(data , loc = 5.3 , scale = 1 )
 
#Visualizing the distribution
 
sb.set_style('whitegrid')
sb.lineplot(data, pdf , color = 'black')
plt.xlabel('Heights')
plt.ylabel('Probability Density')
norm(loc = 5.3 , scale = 1).cdf(4.5)

2. 正規分布の性質

正規分布の密度関数は、データ点と平均値、標準偏差を受け取り、確率密度と呼ぶ値を投げるだけです。

平均と標準偏差を変えることで、ベル曲線の形状を変えることができます。

平均値を変更すると、曲線はその平均値に向かって移動します。

つまり、曲線の形状はそのままに、平均値を変更することで曲線の位置を変えることができるのです。

曲線の形状は、標準偏差の値で制御することができます

標準偏差が小さいと、曲線は密接に結ばれ、値が大きいと、曲線はより広がります。

正規分布のいくつかの優れた特性。

  • 平均値、最頻値、中央値はすべて等しい。
  • 曲線下の総面積は 1 に等しい。
  • 曲線は平均を中心に対称です。
cdf_upper_limit = norm(loc = 5.3 , scale = 1).cdf(6.5)
cdf_lower_limit = norm(loc = 5.3 , scale = 1).cdf(4.5)
 
prob = cdf_upper_limit - cdf_lower_limit
print(prob)

経験則では、以下のようになります。

  • データの68%は平均値から1標準偏差の範囲にある。
  • データの95%は平均の2標準偏差の範囲内にある。
  • データの99.7%は平均値から3つの標準偏差の範囲内にある。

統計学で最も重要な分布の1つです。

自然界に存在するほとんどの現象が正規分布に従うので、正規分布は魔法のような存在です。

例えば、血圧、IQ値、身長などは正規分布に従います。

正規分布による確率の計算

正規分布のある範囲にある値が発生する確率を求めるには、その範囲の曲線下面積を求めればよい。

つまり、密度関数を積分すればよい。

正規分布は連続分布なので、曲線の下の面積が確率を表します。

まず、詳細に入る前に、標準正規分布とは何かを知っておきましょう。

標準正規分布は、平均=0、標準偏差=1の正規分布と同じようなものです。

Z = (x-μ)/ σ` です。

上のz値は、zスコアとも呼ばれます。

z スコアは、あるデータポイントが平均からどの程度離れているかを示すものです。

もし私たちが手動で確率を計算するつもりなら、累積パーセント値を見るためにz-tableで私たちのz値を調べる必要があります。

Pythonはこの作業を行うためのモジュールを提供してくれます。

さっそく使ってみましょう。

1. 正規曲線の作成

ここでは、正規分布から確率を計算するために scipy.norm クラス関数を使用します。

ある町の成人の身長のデータがあり、そのデータが正規分布に従うとすると、平均が5.3、標準偏差が1という十分なサンプルサイズがあるとします。

この情報は,正規曲線を作成するのに十分です。

cdf_value = norm(loc = 5.3 , scale = 1).cdf(6.5)
prob = 1- cdf_value
print(prob)
# import required libraries
from scipy.stats import norm
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sb
 
# Creating the distribution
data = np.arange(1,10,0.01)
pdf = norm.pdf(data , loc = 5.3 , scale = 1 )
 
#Probability of height to be under 4.5 ft.
prob_1 = norm(loc = 5.3 , scale = 1).cdf(4.5)
print(prob_1)
 
#probability that the height of the person will be between 6.5 and 4.5 ft.
 
cdf_upper_limit = norm(loc = 5.3 , scale = 1).cdf(6.5)
cdf_lower_limit = norm(loc = 5.3 , scale = 1).cdf(4.5)
 
prob_2 = cdf_upper_limit - cdf_lower_limit
print(prob_2)
 
#probability that the height of a person chosen randomly will be above 6.5ft
 
cdf_value = norm(loc = 5.3 , scale = 1).cdf(6.5)
prob_3 = 1- cdf_value
print(prob_3)

norm.pdf( )クラスメソッドは、データと共にlocscaleを入力引数として必要とし、確率密度値を与えます。

loc は平均値、 scale はデータの標準偏差です。

コードは前のセクションで作成したものと似ていますが、より短くなっています。

2. 特定のデータが発生する確率を計算する

さて、この分布からランダムに1人を選ぶとしたら、その人の身長が4.5フィートより小さくなる確率はどのくらいでしょうか?

Probability Density Function Of Normal Distribution
Probability Density Function Of Normal Distribution

上の図のような曲線の下の面積が、分布からランダムに選んだ場合に、その人の身長が4.5フィートより小さくなる確率になります。

pythonでどのように計算するか見てみましょう。

曲線の下の面積は、-∞から4.5までの密度関数の積分です。

Normal Curve
Normal Curve
0.211855 or 21.185 %

上の1行のコードは、平均5.3、標準偏差1の正規分布からランダムに人を選んだ場合、その人の身長が4.5フィート以下になる確率が21.18%であることを求めます。

平均と標準偏差で norm クラスのオブジェクトを初期化し、 .cdf( ) メソッドを使用して、累積確率値を求める必要がある値まで渡します。

累積分布関数 (CDF) は、与えられた x 値に対する累積確率を計算します。

累積確率の値は、-∞から∞までは1に等しくなります。

ここで、もう一度、この分布からランダムに一人を選ぶように言われたとすると、その人の身長が 6.5 から 4.5 フィートの間になる確率はどのくらいでしょうか。

Percentage Distribution of Data Around Mean
Percentage Distribution of Data Around Mean
Heights Distribution
Heights Distribution
0.673074 or 67.30 %

上記のコードでは、まず-∞から6.5までの累積確率値を計算し、次に-∞から4.5までの累積確率値を計算しました。

6.5のcdfから4.5のcdfを引くと、6.5と4.5の間の曲線下面積が得られます。

さて、ランダムに選んだ人の身長が6.5ft以上になる確率を聞かれたらどうでしょうか?

Area Under The Curve As Probability
Area Under The Curve As Probability

単純なことです。

曲線下の面積の合計が1になることが分かっているので、-∞から6.5までの累積確率の値を計算して1から引くと、ランダムに選んだ人の身長が6.5ft以上になる確率が算出されるのです。

Area Under The Curve as a probability calculation
Area Under The Curve Between 4.5 And 6.5 Ft
0.115069 or 11.50 %.

ということで、pythonを使った実装とともに、この本質的な考え方を練習しておいてください。

上記実装のコード一式

Area Under The Curve Between a value And Infinity
Area Under The Curve Between 6.5ft and Infinity

まとめ

この記事では、正規分布について、正規曲線がどのようなものか、そして最も重要なPythonでの実装について、いくつかのアイデアを得ることができました。

それでは、よい学習を

タイトルとURLをコピーしました