【初心者向け】NumPy random.triangular()で三角分布サンプリングをマスターしよう!


numpy.random.triangular(left, mode, right, size=None)

引数

  • size: 生成するサンプルのサイズ。デフォルトは1
  • right: 三角形の右側の上限
  • mode: 三角形の最頻値
  • left: 三角形の左側の下限

戻り値

  • sizeの長さのndarray。各要素は、leftrightの間のランダムな値です。

詳細

random.triangular()は、以下の確率密度関数を持つ三角分布からランダムなサンプルを生成します。

P(x; l, m, r) = {
    2(x - l)(r - l)(m - l) / (r - l)^2    if l <= x <= m
    2(r - x)(r - l)(r - m) / (r - l)^2    if m <= x <= r
    0                                      otherwise
}

以下の例では、left = 0, mode = 5, right = 10の三角分布から10個のランダムなサンプルを生成します。

import numpy as np

samples = np.random.triangular(0, 5, 10, 10)
print(samples)

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

[1.89478411 5.52207823 2.90289088 7.22351744 3.71058451
 4.92974883 6.8149384  2.44131191 5.39548137 9.04517398]

この例では、生成されたサンプルはすべてleftrightの間の値であり、modeに近い値が多く見られます。

  • NumPyには、randomモジュール以外にも、ランダム数を生成するための様々なモジュールが用意されています。例えば、random.generatorモジュールは、より高度なランダム数生成機能を提供します。
  • random.triangular()は、連続確率分布からのサンプリングを行う関数の一つです。他の連続確率分布からのサンプリングを行う関数には、random.normal(), random.gamma(), random.beta()などがあります。


例1:三角分布からのランダムなサンプルを生成

この例では、left = 0, mode = 5, right = 10の三角分布から10個のランダムなサンプルを生成し、ヒストグラムで可視化します。

import numpy as np
import matplotlib.pyplot as plt

# 三角分布からランダムなサンプルを生成
samples = np.random.triangular(0, 5, 10, 10000)

# ヒストグラムを作成
plt.hist(samples, bins=20, edgecolor='black')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.title('Triangular Distribution (left=0, mode=5, right=10)')
plt.show()

このコードを実行すると、以下の図のようなヒストグラムが出力されます。

例2:三角分布に基づいてシミュレーションデータを作成

この例では、left = 10, mode = 20, right = 30の三角分布に基づいて、100個のシミュレーションデータを作成します。

import numpy as np

# 三角分布からランダムなサンプルを生成
samples = np.random.triangular(10, 20, 30, 100)

# シミュレーションデータを作成
data = samples + np.random.normal(0, 2, 100)

# データを分析
print(data.mean())
print(data.std())
20.12022344373746
1.982932267847796

この例では、生成されたシミュレーションデータの平均値は20.12、標準偏差は1.98です。これは、三角分布の最頻値と標準偏差に近い値です。

例3:三角分布を使用してランダムな待ち時間を生成

この例では、left = 0, mode = 2, right = 5の三角分布を使用して、100個のランダムな待ち時間を生成します。

import numpy as np

# 三角分布からランダムなサンプルを生成
wait_times = np.random.triangular(0, 2, 5, 100)

# 待ち時間を処理
# ...

# 待ち時間の統計量を計算
print(wait_times.mean())
print(wait_times.std())
1.89478411 1.20650329

この例では、生成されたランダムな待ち時間の平均値は1.89、標準偏差は1.21です。これは、三角分布の最頻値と標準偏差に近い値です。

これらの例は、random.triangular()を使用して様々なランダムな値を生成する方法を示しています。

  • NumPyには、random.triangular()以外にも、ランダム数を生成するための様々な関数があります。用途に応じて適切な関数を選択してください。
  • 上記のコードはあくまで例であり、具体的な用途に合わせて変更する必要があります。


ベータ分布と一様分布の組み合わせ

三角分布は、ベータ分布と一様分布の組み合わせを使用して生成することができます。

import numpy as np

def triangular_from_beta_uniform(left, mode, right, size=None):
    beta_samples = np.random.beta(mode - left, right - mode, size=size)
    return left + beta_samples * (right - left)

このコードでは、まずnp.random.beta()を使用して、ベータ分布からのランダムなサンプルを生成します。その後、これらのサンプルをleftrightの間にスケーリングして、三角分布からのランダムなサンプルを作成します。

samples = triangular_from_beta_uniform(0, 5, 10, 10000)
plt.hist(samples, bins=20, edgecolor='black')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.title('Triangular Distribution (left=0, mode=5, right=10)')
plt.show()

このコードを実行すると、random.triangular()で生成したものとほぼ同じヒストグラムが出力されます。

利点

  • ベータ分布と一様分布は、標準ライブラリにすでに実装されているため、random.triangular()よりも高速に実行できる場合があります。

欠点

  • 計算が少し複雑になる。

カスタム関数

独自の三角分布サンプリング関数を作成することもできます。

import numpy as np

def triangular_custom(left, mode, right, size=None):
    if size is None:
        size = 1
    while True:
        u = np.random.uniform(0, 1, size=size)
        v = np.random.uniform(0, 1, size=size)
        y = left + u * (right - left)
        x = y + (mode - y) * v
        if x <= right:
            return x

このコードでは、まず一様分布から2つのランダムなサンプルを生成します。その後、これらのサンプルを使用して、三角分布の条件を満たす値を計算します。

samples = triangular_custom(0, 5, 10, 10000)
plt.hist(samples, bins=20, edgecolor='black')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.title('Triangular Distribution (left=0, mode=5, right=10)')
plt.show()

利点

  • 独自の条件を満たす三角分布を生成することができます。

欠点

  • 計算が遅くなる場合があります。

NumPy以外にも、三角分布からのランダムなサンプルを生成するためのライブラリがいくつかあります。例えば、SciPyモジュールのscipy.stats.triang関数を使用することができます。

import scipy.stats as stats

samples = stats.triang.rvs(0, 5, 10, size=10000)
plt.hist(samples, bins=20, edgecolor='black')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.title('Triangular Distribution (left=0, mode=5, right=10)')
plt.show()

利点

  • SciPyモジュールのtriang関数は、高速で効率的なサンプリングアルゴリズムを使用しています。
  • NumPy標準ライブラリに含まれていないため、別途インストールする必要があります。
  • 上記のコードはあくまで例であり、具体的な用途に合わせて変更する必要があります。