データ分析の強力なツール:NumPyのrandom.Generator.exponential()で実現するランダムサンプリング


この関数の詳細

  • 返り値
    • 生成された乱数の入ったndarray
  • 引数
    • scale (float, optional): スケールパラメータ。平均待ち時間はこの値に反比例します。デフォルトは1です。
    • size (int or tuple, optional): 生成する乱数の個数または形状。デフォルトは1です。
    • generator (random.Generator, optional): 乱数生成器オブジェクト。デフォルトはnp.random.default_rng()で生成されたオブジェクトです。
  • 用途
    指数分布に従う乱数の生成

使い方

import numpy as np

# 乱数生成器を生成
rng = np.random.default_rng()

# 平均待ち時間が5秒の指数分布から10個の乱数を生成
random_numbers = rng.exponential(scale=5, size=10)

print(random_numbers)

このコードを実行すると、平均5秒の指数分布に従う10個の乱数が生成され、random_numbers に格納されます。

  • random.Generator.exponential() 関数は、様々なシミュレーションや確率モデリングにおいて役立ちます。
  • スケールパラメータscale は、分布の形状を決定します。値が大きくなるほど、ランダムな値が小さくなる傾向があります。
  • 指数分布は、連続確率分布の一種です。


平均待ち時間が 5 秒の指数分布から 10 個の乱数を生成

import numpy as np

rng = np.random.default_rng()
random_numbers = rng.exponential(scale=5, size=10)
print(random_numbers)

このコードは、random.Generator.exponential() 関数を使用して、平均待ち時間が 5 秒の指数分布から 10 個の乱数を生成します。生成された乱数は random_numbers 配列に格納されます。

シード値を設定して乱数を生成

import numpy as np

seed = 12345
rng = np.random.default_rng(seed)
random_numbers = rng.exponential(scale=5, size=10)
print(random_numbers)

このコードは、seed というシード値を設定して random.Generator.exponential() 関数を実行します。シード値を設定することで、同じコードを実行しても毎回同じ乱数が生成されます。これは、再現性の高いシミュレーションを行う際に役立ちます。

スケールパラメータを変えて乱数を生成

import numpy as np

scales = [1, 2, 5, 10]

for scale in scales:
  rng = np.random.default_rng()
  random_numbers = rng.exponential(scale=scale, size=10)
  print(f"scale = {scale}:", random_numbers)

このコードは、scale パラメータを異なる値に設定して random.Generator.exponential() 関数を実行します。scale パラメータの値が大きくなるほど、生成される乱数の値が小さくなる傾向があることがわかります。

import numpy as np

class MyCustomGenerator(np.random.Generator):
  def __init__(self, seed):
    super().__init__(seed)

  def exponential(self, *args, **kwargs):
    # オリジナルの `exponential` 関数をカスタマイズ
    random_numbers = super().exponential(*args, **kwargs)
    # 生成された乱数に対してカスタム処理を行う
    random_numbers = random_numbers * 2
    return random_numbers

rng = MyCustomGenerator(seed=12345)
random_numbers = rng.exponential(scale=5, size=10)
print(random_numbers)


ガンマ分布からのサンプリング

ガンマ分布は、指数分布を一般化したものであり、形状パラメータ k と尺度パラメータ θ を用いて表現されます。k = 1 の場合、ガンマ分布は指数分布になります。

利点:

  • 指数分布以外にも、様々な確率分布を生成できる
  • スケールパラメータだけでなく、形状パラメータも制御できるため、より柔軟な乱数生成が可能

欠点:

  • random.Generator.exponential() 関数よりも計算コストがかかる場合がある
import numpy as np

# ガンマ分布からサンプリング
k = 1  # 形状パラメータ
theta = 5  # 尺度パラメータ
random_numbers = np.random.gamma(k=k, scale=theta, size=10)
print(random_numbers)

逆変換法

逆変換法は、累積分布関数の逆関数を使って乱数を生成する方法です。指数分布の場合、累積分布関数は以下の式で表されます。

F(x) = 1 - exp(-x / θ)
  • 比較的シンプルな方法
  • 数値的に不安定になる場合がある
import numpy as np

# 逆変換法による指数分布からのサンプリング
theta = 5
random_numbers = -theta * np.log(np.random.rand(10))
print(random_numbers)

専用ライブラリの使用

SciPy や Statsmodels などのライブラリには、指数分布をはじめとする様々な確率分布を生成するための関数やクラスが用意されています。これらのライブラリは、NumPy の標準ライブラリよりも高機能な場合があり、複雑な確率モデリングを行う際に役立ちます。

  • 複雑な確率モデリングに役立つ
  • 高機能な機能
  • NumPy 標準ライブラリよりも習得コストがかかる

ハードウェア乱数生成器の使用

高精度な乱数が必要な場合は、ハードウェア乱数生成器を使用することができます。ハードウェア乱数生成器は、ソフトウェアよりも高速で高精度な乱数を生成することができます。

  • 高速な処理
  • 高精度な乱数
  • コストがかかる
  • 専用のハードウェアが必要

どの代替方法が最適かは、状況によって異なります。上記の利点と欠点を考慮し、要件に合った方法を選択してください。

  • 上記以外にも、指数分布からのサンプリング方法として、畳み込み法やモンテカルロ法などがあります。