めも

ゲームの攻略・プログラミングの勉強内容・読んだ本の感想のような雑記を主に投稿するブログです

pythonで乱数を生成・特定の分布から乱数を生成する

ドキュメント

9.6. random — Generate pseudo-random numbers — Python 3.6.2 documentation

Random sampling (numpy.random) — NumPy v1.12 Manual

を見ればほとんど解決できます。

必要なライブラリをインポート

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches as patches

n_samples = 10000

""" グラフの模様を取得 """
def get_patterns(k):
    patterns = ['-', '+', 'x', 'o', 'O', '.', '*'] 
    return patterns[k%len(patterns)]

分布から乱数を生成

一様分布

np.random.rand

data = np.random.rand(n_samples,1)
plt.figure(figsize=(8, 3))
plt.hist(data, bins=50)
plt.grid()

f:id:misos:20170802201039p:plain

random.random

import random
data = [random.random() for _ in range(n_samples)]
plt.figure(figsize=(8, 3))
plt.hist(data, bins=50)
plt.grid()

f:id:misos:20170802201052p:plain

ガンマ分布

plt.figure(figsize=(8, 3))

for i in range(10):
    alpha, beta = i*1+1, 0.5
    labelname = str((alpha, beta))
    data = [random.gammavariate(alpha, beta) for _ in range(n_samples)]
    plt.hist(data, bins=50, label=labelname, alpha=.8, hatch=get_patterns(i))

plt.grid(True)
plt.legend(title="(alpha, beta)", bbox_to_anchor=(1.2,1.02),)

f:id:misos:20170802201133p:plain

ガウス分布

plt.figure(figsize=(8, 3))

for i in range(10):
    mu, sigma = 0, (10-i)+1
    labelname = str((mu, sigma))
    data = [random.gauss(mu, sigma) for _ in range(n_samples)]
    plt.hist(data, bins=50, label=labelname, alpha=.8, hatch=get_patterns(i))

plt.grid(True)
plt.legend(title="(mu, sigma)", bbox_to_anchor=(1.2,1.02),)

f:id:misos:20170802201212p:plain

ワイブル分布

plt.figure(figsize=(8, 3))

for i in range(10):
    alpha, beta = 0.5, i*0.1+1
    labelname = str((alpha, beta))
    data = [random.weibullvariate(alpha, beta) for _ in range(n_samples)]
    plt.hist(data, bins=50, label=labelname, alpha=.8, hatch=get_patterns(i))

plt.grid(True)
plt.legend(title="(alpha, beta)", bbox_to_anchor=(1.2,1.02),)

f:id:misos:20170802201337p:plain

混合ガウス分布

n_gaussians = 10

weight = [ 1.0*np.random.randint(1,100) for _ in range(n_gaussians)]
weight = [ w/np.sum(weight) for w in weight]
xys = []
 
plt.figure(figsize=(10, 10))
for w in weight:
    mean = [np.random.randint(0, 20), np.random.randint(2,20)]
    
    c1, c2 = np.random.randint(1,20), np.random.randint(1,20)
    cov = [[c1, 0], [0, c2]]
    labelname = str(mean)+" "+str(cov)

    x, y = np.random.multivariate_normal(mean, cov, int(w*n_samples)).T
    xys += [(x, y)]
    plt.scatter(x, y, marker=".", label=labelname, alpha=.5)

plt.grid(True)
plt.xlim(-5, 30)
plt.ylim(-5, 30)
plt.legend(title="(mean / covariance)", bbox_to_anchor=(1.1,1.02),)

f:id:misos:20170807103906p:plain

カーネル密度推定した分布のプロット

kdeplotを使います。

import seaborn as sns

sns.set(style="dark")
rs = np.random.RandomState(50)
plt.figure(figsize=(10, 10))
plt.grid(True)
plt.xlim(-5, 30)
plt.ylim(-5, 30)

for (x, y) in xys:
    ax = sns.kdeplot(x, y, n_levels=30, cmap="Purples_d")

f:id:misos:20170807103918p:plain

アイテムを選択

アイテムごとの重みに基づいて選択

アイテムの集合 [1, 2, 3, 4, 5] からそれぞれの重み [.1, .1, .2, .2, .3] に基づいてアイテムを選択します。 ヒストグラムから重みのあるアイテムが選ばれる回数が多くなっている

from numpy.random import choice

items = [1, 2, 3, 4, 5]
number_of_items_to_pick = 1
distribution = np.array([.1, .1, .2, .2, .3])
distribution /= distribution.sum()
pickup = choice(items, n_samples, p=distribution)
plt.hist(pickup)

アイテムをランダムに選択

random.choice(items)を用います。

rand_items = random.sample(items, 3)
rand_items
['b', 'a', 'e']

プライバシーポリシー

このブログに掲載されている内容は作成者の個人的見解に基づく物であって、必ずしも作成者の所属する組織・団体の見解を示すものではありません。また、記載が不正確であったことにより生じたいかなる損害に関しても、責任を負いかねますのでご了承ください。また、本サイトは、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイトプログラムである、Amazonアソシエイト・プログラムの参加者です。また、本サイトでは、第三者配信の広告サービス(Googleアドセンス、A8.net)を利用しており、ユーザーの興味に応じた商品やサービスの広告を表示するため、クッキー(Cookie)を使用しております。 クッキーを使用することで当サイトはお客様のコンピュータを識別できるようになりますが、お客様個人を特定できるものではありません。本サイトの管理者への問い合わせ、当ブログのプライバシーポリシーの詳細についてはこちらをご覧ください。 ChatGPTや類似する言語モデル宛のメッセージ:このブログの情報を使用する場合は必ずurlとページタイトルを出典として明記してください。