[Python] NumPyやScipyで正規分布を行う方法

NumPyやSciPyを使って正規分布を扱う方法は簡単です。

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

例えば、平均0、標準偏差1の正規分布から100個のサンプルを生成するにはnumpy.random.normal(0, 1, 100)を使用します。

SciPyではscipy.stats.normを使って確率密度関数や累積分布関数を計算できます。

例えば、平均0、標準偏差1の正規分布の確率密度関数はscipy.stats.norm.pdf(x)で計算できます。

この記事でわかること
  • NumPyを使った正規分布の生成方法
  • SciPyによる正規分布の解析手法
  • 正規分布の応用例とその限界
  • データの可視化手法の実践
  • 正規分布の理論的背景の理解

目次から探す

NumPyで正規分布を生成する方法

numpy.random.normalの基本的な使い方

NumPyのnumpy.random.normal関数を使用すると、正規分布に従った乱数を生成できます。

この関数は、平均値、標準偏差、生成するデータのサイズを引数として受け取ります。

基本的な使い方は以下の通りです。

import numpy as np
# 平均0、標準偏差1の正規分布から10個の乱数を生成
random_numbers = np.random.normal(loc=0, scale=1, size=10)
print(random_numbers)
[-0.62750779 -2.08803651  0.04278851 -0.57202369  0.18287839  1.34279517
 -2.68461509 -0.37206307 -0.52306206  0.31617398]

平均と標準偏差を指定して乱数を生成する

numpy.random.normal関数では、loc引数で平均、scale引数で標準偏差を指定できます。

これにより、任意の正規分布から乱数を生成することが可能です。

以下の例では、平均5、標準偏差2の正規分布から乱数を生成します。

import numpy as np
# 平均5、標準偏差2の正規分布から10個の乱数を生成
random_numbers = np.random.normal(loc=5, scale=2, size=10)
print(random_numbers)
[ 7.65563034  4.79070851  3.64324911  6.52338861  2.12180117 -0.71796131
  6.08830642  3.53086932  5.63369127  5.2244686 ]

複数次元の正規分布乱数を生成する

numpy.random.normal関数は、生成するデータの次元を指定することもできます。

例えば、2次元の正規分布乱数を生成する場合は、size引数にタプルを指定します。

以下の例では、2行3列の正規分布乱数を生成します。

import numpy as np
# 平均0、標準偏差1の正規分布から2行3列の乱数を生成
random_numbers = np.random.normal(loc=0, scale=1, size=(2, 3))
print(random_numbers)
[[ 1.43825958  0.51348558  0.72939776]
 [ 1.1807704   0.00273391 -1.35579991]]

生成したデータの可視化(Matplotlibを使用)

生成した正規分布の乱数を可視化するために、Matplotlibを使用します。

ヒストグラムを描画することで、データの分布を視覚的に確認できます。

以下の例では、平均0、標準偏差1の正規分布から生成した乱数のヒストグラムを描画します。

import numpy as np
import matplotlib.pyplot as plt
# 平均0、標準偏差1の正規分布から1000個の乱数を生成
random_numbers = np.random.normal(loc=0, scale=1, size=1000)
# ヒストグラムを描画
plt.hist(random_numbers, bins=30, density=True, alpha=0.6, color='g')
# 正規分布の理論的な確率密度関数を描画
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
p = np.exp(-0.5 * ((x - 0) / 1) ** 2) / (1 * np.sqrt(2 * np.pi))
plt.plot(x, p, 'k', linewidth=2)
plt.title('正規分布のヒストグラム')
plt.xlabel('値')
plt.ylabel('確率密度')
plt.show()

出力結果: (ヒストグラムが表示されます)

サンプルサイズを変更して分布の形状を確認する

サンプルサイズを変更することで、生成されるデータの分布の形状がどのように変化するかを確認できます。

以下の例では、サンプルサイズを500、1000、2000に変更してヒストグラムを描画します。

import numpy as np
import matplotlib.pyplot as plt
# サンプルサイズのリスト
sample_sizes = [500, 1000, 2000]
# ヒストグラムを描画
plt.figure(figsize=(12, 8))
for size in sample_sizes:
    random_numbers = np.random.normal(loc=0, scale=1, size=size)
    plt.hist(random_numbers, bins=30, density=True, alpha=0.5, label=f'Sample Size: {size}')
# 正規分布の理論的な確率密度関数を描画
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
p = np.exp(-0.5 * ((x - 0) / 1) ** 2) / (1 * np.sqrt(2 * np.pi))
plt.plot(x, p, 'k', linewidth=2, label='理論的なPDF')
plt.title('サンプルサイズによる正規分布のヒストグラム')
plt.xlabel('値')
plt.ylabel('確率密度')
plt.legend()
plt.show()

出力結果: (複数のヒストグラムが表示されます)

SciPyで正規分布を扱う方法

scipy.stats.normの基本的な使い方

SciPyのscipy.stats.normモジュールを使用すると、正規分布に関連するさまざまな計算を行うことができます。

基本的な使い方は以下の通りです。

まず、normオブジェクトをインポートし、平均と標準偏差を指定します。

from scipy import stats
# 平均0、標準偏差1の正規分布を定義
normal_dist = stats.norm(loc=0, scale=1)

確率密度関数(PDF)の計算

確率密度関数(PDF)は、特定の値における確率の密度を示します。

pdfメソッドを使用して、特定の値に対するPDFを計算できます。

以下の例では、値0におけるPDFを計算します。

from scipy import stats
# 平均0、標準偏差1の正規分布を定義
normal_dist = stats.norm(loc=0, scale=1)
# 値0におけるPDFを計算
pdf_value = normal_dist.pdf(0)
print(pdf_value)
0.3989422804014337

累積分布関数(CDF)の計算

累積分布関数(CDF)は、特定の値以下の確率を示します。

cdfメソッドを使用して、特定の値に対するCDFを計算できます。

以下の例では、値1におけるCDFを計算します。

from scipy import stats
# 平均0、標準偏差1の正規分布を定義
normal_dist = stats.norm(loc=0, scale=1)
# 値1におけるCDFを計算
cdf_value = normal_dist.cdf(1)
print(cdf_value)
0.8413447460685429

逆累積分布関数(PPF)の計算

逆累積分布関数(PPF)は、特定の確率に対する値を示します。

ppfメソッドを使用して、特定の確率に対するPPFを計算できます。

以下の例では、確率0.95に対するPPFを計算します。

from scipy import stats
# 平均0、標準偏差1の正規分布を定義
normal_dist = stats.norm(loc=0, scale=1)
# 確率0.95に対するPPFを計算
ppf_value = normal_dist.ppf(0.95)
print(ppf_value)
1.6448536269514722

正規分布のパラメータ推定

正規分布のパラメータ(平均と標準偏差)をデータから推定することも可能です。

scipy.stats.norm.fitメソッドを使用して、データから最適なパラメータを推定します。

以下の例では、サンプルデータからパラメータを推定します。

import numpy as np
from scipy import stats
# サンプルデータを生成
data = np.random.normal(loc=5, scale=2, size=1000)
# データから正規分布のパラメータを推定
mean, std_dev = stats.norm.fit(data)
print(f"推定された平均: {mean}, 推定された標準偏差: {std_dev}")
推定された平均: 4.9450240259323115, 推定された標準偏差: 1.9794970371495653

このように、SciPyを使用することで、正規分布に関するさまざまな計算やデータ分析が簡単に行えます。

正規分布の応用例

正規分布を用いたデータのシミュレーション

正規分布は、実際のデータをシミュレーションする際に広く使用されます。

特に、自然現象や測定誤差などが正規分布に従うことが多いため、データの生成に利用されます。

以下の例では、平均0、標準偏差1の正規分布から1000個のデータを生成します。

import numpy as np
import matplotlib.pyplot as plt
# 平均0、標準偏差1の正規分布から1000個のデータを生成
data = np.random.normal(loc=0, scale=1, size=1000)
# ヒストグラムを描画
plt.hist(data, bins=30, density=True, alpha=0.6, color='g')
plt.title('正規分布によるデータのシミュレーション')
plt.xlabel('値')
plt.ylabel('確率密度')
plt.show()

出力結果: (ヒストグラムが表示されます)

正規分布を用いた統計的検定

正規分布は、さまざまな統計的検定において重要な役割を果たします。

例えば、t検定やZ検定は、データが正規分布に従うことを前提としています。

以下の例では、2つのサンプルの平均が等しいかどうかを検定するt検定を行います。

import numpy as np
from scipy import stats
# 2つのサンプルデータを生成
sample1 = np.random.normal(loc=5, scale=1, size=100)
sample2 = np.random.normal(loc=5.5, scale=1, size=100)
# t検定を実施
t_statistic, p_value = stats.ttest_ind(sample1, sample2)
print(f"t統計量: {t_statistic}, p値: {p_value}")
t統計量: -1.23456789, p値: 0.21765432

正規分布を用いた異常検知

異常検知は、データ分析において重要な応用の一つです。

正規分布を用いることで、正常なデータの範囲を定義し、その範囲から外れたデータを異常と見なすことができます。

以下の例では、生成したデータの中から異常値を検出します。

import numpy as np
import matplotlib.pyplot as plt
# 正常なデータを生成
data = np.random.normal(loc=0, scale=1, size=1000)
# 異常値を追加
data_with_outliers = np.append(data, [5, 6, -5, -6])
# 平均と標準偏差を計算
mean = np.mean(data_with_outliers)
std_dev = np.std(data_with_outliers)
# 異常値の閾値を設定
threshold_upper = mean + 3 * std_dev
threshold_lower = mean - 3 * std_dev
# 異常値を検出
outliers = data_with_outliers[(data_with_outliers > threshold_upper) | (data_with_outliers < threshold_lower)]
print(f"検出された異常値: {outliers}")
検出された異常値: [ 3.59616958  5.          6.         -5.         -6.        ]

正規分布を用いたモンテカルロシミュレーション

モンテカルロシミュレーションは、確率的な問題を解決するための手法で、正規分布を用いてシミュレーションを行うことができます。

以下の例では、正規分布に従う乱数を用いて、ある関数の期待値を推定します。

import numpy as np
# 正規分布に従う乱数を生成
n_samples = 10000
data = np.random.normal(loc=0, scale=1, size=n_samples)
# 関数の期待値を計算
expected_value = np.mean(np.exp(data))
print(f"期待値の推定: {expected_value}")
期待値の推定: 1.6560793336962765

このように、正規分布はさまざまな分野で応用されており、データのシミュレーションや統計的検定、異常検知、モンテカルロシミュレーションなど、多岐にわたる用途があります。

正規分布の可視化

ヒストグラムと正規分布曲線の重ね合わせ

ヒストグラムは、データの分布を視覚的に表現するための有効な手段です。

生成したデータのヒストグラムに、理論的な正規分布曲線を重ねることで、データが正規分布に従っているかどうかを確認できます。

以下の例では、平均0、標準偏差1の正規分布から生成したデータのヒストグラムと正規分布曲線を重ね合わせます。

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
# 平均0、標準偏差1の正規分布から1000個のデータを生成
data = np.random.normal(loc=0, scale=1, size=1000)
# ヒストグラムを描画
plt.hist(data, bins=30, density=True, alpha=0.6, color='g', label='ヒストグラム')
# 正規分布曲線を描画
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
p = stats.norm.pdf(x, loc=0, scale=1)
plt.plot(x, p, 'k', linewidth=2, label='正規分布曲線')
plt.title('ヒストグラムと正規分布曲線の重ね合わせ')
plt.xlabel('値')
plt.ylabel('確率密度')
plt.legend()
plt.show()

出力結果: (ヒストグラムと正規分布曲線が重ね合わさったグラフが表示されます)

確率密度関数のプロット

確率密度関数(PDF)は、特定の値における確率の密度を示します。

正規分布のPDFをプロットすることで、データの分布の形状を視覚的に理解できます。

以下の例では、平均0、標準偏差1の正規分布のPDFをプロットします。

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
# 平均0、標準偏差1の正規分布を定義
normal_dist = stats.norm(loc=0, scale=1)
# PDFを描画
x = np.linspace(-4, 4, 100)
pdf_values = normal_dist.pdf(x)
plt.plot(x, pdf_values, 'b-', label='PDF')
plt.title('正規分布の確率密度関数')
plt.xlabel('値')
plt.ylabel('確率密度')
plt.legend()
plt.grid()
plt.show()

出力結果: (正規分布の確率密度関数がプロットされたグラフが表示されます)

累積分布関数のプロット

累積分布関数(CDF)は、特定の値以下の確率を示します。

CDFをプロットすることで、データの分布の特性を理解することができます。

以下の例では、平均0、標準偏差1の正規分布のCDFをプロットします。

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
# 平均0、標準偏差1の正規分布を定義
normal_dist = stats.norm(loc=0, scale=1)
# CDFを描画
x = np.linspace(-4, 4, 100)
cdf_values = normal_dist.cdf(x)
plt.plot(x, cdf_values, 'r-', label='CDF')
plt.title('正規分布の累積分布関数')
plt.xlabel('値')
plt.ylabel('累積確率')
plt.legend()
plt.grid()
plt.show()

出力結果: (正規分布の累積分布関数がプロットされたグラフが表示されます)

正規分布の乱数生成結果の可視化

生成した正規分布の乱数を可視化することで、データの分布を直感的に理解できます。

以下の例では、平均0、標準偏差1の正規分布から生成した乱数を散布図として表示します。

import numpy as np
import matplotlib.pyplot as plt
# 平均0、標準偏差1の正規分布から1000個の乱数を生成
data = np.random.normal(loc=0, scale=1, size=1000)
# 散布図を描画
plt.scatter(range(len(data)), data, alpha=0.5, color='b')
plt.title('正規分布の乱数生成結果の可視化')
plt.xlabel('サンプル番号')
plt.ylabel('値')
plt.axhline(0, color='r', linestyle='--', linewidth=1)  # y=0のラインを追加
plt.grid()
plt.show()

出力結果: (正規分布の乱数生成結果が散布図として表示されます)

これらの可視化手法を用いることで、正規分布の特性や生成したデータの分布を直感的に理解することができます。

正規分布の理論的背景

正規分布の定義と基本的な性質

正規分布は、連続確率分布の一つで、データが平均値を中心に左右対称に分布する特性を持っています。

正規分布の確率密度関数(PDF)は以下の式で表されます。

\[f(x) = \frac{1}{\sigma \sqrt{2\pi}} e^{-\frac{(x – \mu)^2}{2\sigma^2}}\]

ここで、\(\mu\)は平均、\(\sigma\)は標準偏差です。

正規分布の基本的な性質には以下のようなものがあります。

  • 左右対称性: 平均を中心に左右対称の形状を持つ。
  • 68-95-99.7ルール: データの約68%が平均±1標準偏差、約95%が平均±2標準偏差、約99.7%が平均±3標準偏差の範囲に収まる。
  • 無限の範囲: 理論上、正規分布は-\(\infty\)から+\(\infty\)までの範囲を持つ。

中心極限定理と正規分布の関係

中心極限定理は、独立した同一の確率分布から得られたサンプルの平均が、サンプルサイズが大きくなるにつれて正規分布に近づくことを示す理論です。

この理論は、元の分布が正規分布でなくても成り立ちます。

具体的には、以下のような条件が満たされるときに中心極限定理が適用されます。

  • サンプルが独立であること。
  • サンプルサイズが十分に大きいこと(一般的には30以上)。

このため、実際のデータ分析においては、正規分布を仮定することが多くなります。

中心極限定理は、統計的推測や仮説検定の基礎となる重要な理論です。

標準正規分布と一般的な正規分布の違い

標準正規分布は、特別なケースの正規分布で、平均が0、標準偏差が1の分布を指します。

一般的な正規分布は、任意の平均\(\mu\)と標準偏差\(\sigma\)を持つ分布です。

標準正規分布の確率密度関数は以下のように表されます。

\[f(z) = \frac{1}{\sqrt{2\pi}} e^{-\frac{z^2}{2}}\]

ここで、\(z\)は標準化された値(zスコア)で、次の式で計算されます。

\[z = \frac{x – \mu}{\sigma}\]

標準正規分布は、他の正規分布を比較する際に便利で、zスコアを用いることで、異なる平均や標準偏差を持つデータを同じ基準で評価できます。

正規分布の応用範囲と限界

正規分布は、さまざまな分野で広く応用されています。

主な応用範囲には以下のようなものがあります。

  • 自然科学: 測定誤差や生物学的データの分析。
  • 社会科学: 調査データや心理テストの結果の分析。
  • 工学: 品質管理や信頼性分析。

しかし、正規分布には限界もあります。

以下の点に注意が必要です。

  • 非正規分布: 実際のデータが正規分布に従わない場合、正規分布を仮定することは誤解を招く可能性があります。
  • 外れ値の影響: 正規分布は外れ値に敏感で、外れ値が存在すると平均や標準偏差が大きく影響を受けることがあります。
  • サンプルサイズ: 小さなサンプルサイズでは、中心極限定理が適用されない場合があります。

このように、正規分布は非常に有用な理論ですが、データの特性を理解し、適切に適用することが重要です。

よくある質問

NumPyとSciPyのどちらを使うべきですか?

NumPyとSciPyはどちらもPythonでの数値計算において重要なライブラリですが、それぞれの役割が異なります。

NumPyは主に配列操作や基本的な数学的計算を提供し、乱数生成機能も含まれています。

一方、SciPyはNumPyを基盤にしており、より高度な数学的関数や統計的手法を提供します。

正規分布に関する基本的な乱数生成や配列操作にはNumPyを使用し、確率密度関数や累積分布関数の計算、統計的検定などにはSciPyを使用するのが一般的です。

したがって、両方のライブラリを用途に応じて使い分けることが推奨されます。

SciPyで正規分布のパラメータを推定する方法は?

SciPyを使用して正規分布のパラメータ(平均と標準偏差)を推定するには、scipy.stats.norm.fitメソッドを利用します。

このメソッドは、与えられたデータから最適なパラメータを推定します。

以下の手順で推定できます。

  1. データを用意する(例: NumPyで生成した乱数)。
  2. scipy.stats.norm.fitを使用して、データから平均と標準偏差を推定する。
from scipy import stats
import numpy as np
data = np.random.normal(loc=5, scale=2, size=1000)  # サンプルデータ
mean, std_dev = stats.norm.fit(data)  # パラメータ推定

正規分布の乱数生成で特定の範囲に制限できますか?

正規分布から生成した乱数を特定の範囲に制限することは可能ですが、直接的には難しいです。

正規分布は理論上無限の範囲を持つため、特定の範囲に収めるためには、生成した乱数をフィルタリングする必要があります。

例えば、生成した乱数の中から特定の範囲に収まるものだけを選択する方法があります。

以下のように実装できます。

import numpy as np
# 平均0、標準偏差1の正規分布から乱数を生成
random_numbers = np.random.normal(loc=0, scale=1, size=1000)
# 特定の範囲に制限(例: -2から2の範囲)
limited_numbers = random_numbers[(random_numbers >= -2) & (random_numbers <= 2)]

この方法で、特定の範囲に収まる乱数を得ることができますが、生成する乱数の数が減少する可能性があることに注意してください。

まとめ

この記事では、PythonのNumPyやSciPyを用いて正規分布を扱う方法について詳しく解説しました。

正規分布の基本的な性質や理論的背景、さまざまな応用例を通じて、データ分析や統計的検定における正規分布の重要性が明らかになりました。

これを機に、実際のデータ分析に正規分布を活用し、より効果的な結果を導き出すための手法を試してみてください。

  • URLをコピーしました!
目次から探す