Python で対数正規分布を操る:random.lognormal() 関数を超えた世界


対数正規分布とは?

対数正規分布は、正規分布の変数を対数変換した分布です。つまり、元々の変数が正規分布に従う場合、その対数値は対数正規分布に従います。

対数正規分布は、自然界において様々な現象に現れます。例えば、生物の個体数、経済指標、物理現象の測定値などが対数正規分布に従うことが知られています。

random.lognormal() 関数の詳細

random.lognormal() 関数は、以下の引数を取ります。

  • size: 生成する乱数の個数
  • sigma: 対数正規分布の標準偏差を表す形状パラメータ
  • mean: 対数正規分布の平均値を表すスケーリングパラメータ

この関数は、上記のパラメータに基づいて、対数正規分布に従う乱数を生成します。

import numpy as np

# 平均値と標準偏差を設定
mean = 1.0
sigma = 0.5

# 10個の乱数を生成
samples = np.random.lognormal(mean, sigma, 10)

# 乱数を表示
print(samples)

このコードを実行すると、以下のような出力が出力されます。

[1.64912691 0.67186094 1.40309942 2.07982892 0.78903344
 1.20536903 0.88079032 1.7481299  1.01090524 0.54939122]

この例では、平均値1.0、標準偏差0.5の対数正規分布に従う10個の乱数が生成されています。



特定の範囲の乱数生成

random.lognormal() 関数は、デフォルトでは 0 以上の乱数を生成します。しかし、特定の範囲の乱数が必要な場合もあります。以下は、1 から 10 までの範囲の対数正規分布に従う乱数を生成する例です。

import numpy as np

# 平均値、標準偏差、生成する乱数の個数を設定
mean = 2.0
sigma = 0.5
size = 10

# 乱数を生成
samples = np.random.lognormal(mean, sigma, size) * 10

# 乱数を表示
print(samples)

このコードでは、生成された乱数に 10 を乗算することで、1 から 10 までの範囲に変換しています。

対数変換の確認

対数正規分布は、正規分布の変数を対数変換した分布であることを説明しました。以下は、生成された対数正規分布の乱数を対数変換し、正規分布に従うかどうかを確認する例です。

import numpy as np
import matplotlib.pyplot as plt

# 平均値、標準偏差、生成する乱数の個数を設定
mean = 1.0
sigma = 0.5
size = 1000

# 乱数を生成
samples = np.random.lognormal(mean, sigma, size)

# 対数変換
log_samples = np.log(samples)

# 正規分布の乱数を生成
normal_samples = np.random.normal(mean, sigma, size)

# ヒストグラムを表示
plt.hist(log_samples, bins=20, label='Lognormal')
plt.hist(normal_samples, bins=20, label='Normal')
plt.legend()
plt.show()

このコードを実行すると、2つのヒストグラムが生成されます。対数正規分布の乱数を対数変換したヒストグラムと、正規分布の乱数のヒストグラムが重なり合うことが確認できます。これは、対数正規分布が正規分布の変数を対数変換した分布であることを示しています。

箱ひげ図は、データの分散、中央値、外れ値などを視覚的に表現するのに役立ちます。以下は、対数正規分布の乱数の箱ひげ図を作成する例です。

import numpy as np
import seaborn as sns

# 平均値、標準偏差、生成する乱数の個数を設定
mean = 2.0
sigma = 0.5
size = 1000

# 乱数を生成
samples = np.random.lognormal(mean, sigma, size)

# 箱ひげ図を表示
sns.boxplot(samples)
plt.show()


以下に、random.lognormal() の代替方法として検討すべきいくつかのオプションを紹介します。

正規分布とガンマ分布の組み合わせ

対数正規分布は、正規分布の変数を対数変換した分布であると説明しました。このことを利用して、正規分布とガンマ分布を組み合わせることで、random.lognormal() 関数の代替方法を作ることができます。

以下のコードは、この方法で対数正規分布に従う乱数を生成する例です。

import numpy as np

# 平均値、標準偏差、生成する乱数の個数を設定
mean = 1.0
sigma = 0.5
size = 10

# 正規分布の乱数を生成
z = np.random.normal(mean, sigma, size)

# ガンマ分布の乱数を生成
alpha = sigma**2
scale = mean * np.exp(z)
gamma_samples = np.random.gamma(alpha, scale=scale)

# 乱数を表示
print(gamma_samples)

このコードは、まず正規分布の乱数を生成し、次にガンマ分布の乱数を生成します。そして、ガンマ分布の乱数を正規分布の乱数でスケーリングすることで、対数正規分布に従う乱数を生成します。

カスタム関数

特定のニーズに合致する random.lognormal() の代替方法が必要な場合は、カスタム関数を作成することができます。

以下のコードは、カスタム関数で対数正規分布に従う乱数を生成する例です。

import numpy as np

def lognormal_gen(mean, sigma, size):
    # 正規分布の乱数を生成
    z = np.random.normal(mean, sigma, size)

    # 乱数を計算
    samples = np.exp(z)

    return samples

# 平均値、標準偏差、生成する乱数の個数を設定
mean = 1.0
sigma = 0.5
size = 10

# 乱数を生成
samples = lognormal_gen(mean, sigma, size)

# 乱数を表示
print(samples)

このコードは、まず正規分布の乱数を生成し、次に指数関数を使って乱数を計算します。

NumPy 以外にも、対数正規分布に従う乱数を生成できるライブラリがいくつかあります。例えば、SciPy や statsmodels などのライブラリが挙げられます。

これらのライブラリは、NumPy よりも高度な機能を提供している場合があるため、特定の状況ではより適している場合があります。