NumPyで乱数を扱う

# 乱数を扱う
乱数と一言で言うけども、色々な種類の乱数があるので、いくつかNumPyを使って作ってみる
乱数生成だけでなくランダムチョイス等も見ていく
つまり `numpy.random` モジュールについて

# 一様乱数
特定の範囲の実数が均等な確率で発生する、まさに一様に発生する乱数
範囲の指定をしないものはデフォルトで `0以上1未満` で生成される
## １次元の一様乱数
`numpy.random.rand(要素数)`で作れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/b8d15403-6097-2e33-507f-c9fff34ec900.png)
`random.rand`となるのが若干ややこしいな

## ２次元の一様乱数
もはやパターンかなと思いきや、**タプルで指定ではなく、第１、２引数**だ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/2b448b59-2fa0-559e-d2c6-325ec868dd6a.png)

## 範囲指定の一様乱数
`numpy.random.uniform`で作れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/8b0312d7-8694-181a-6ba9-a5268dcb6cbb.png)
`uniform(3, 5, 10)` で`３以上５未満で１０個`を表す

２次元も同様に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/d89c284c-123e-d0b1-a724-8d773a520545.png)
この場合はお決まりのタプルで渡す必要があるのか、注意

# 整数乱数
名前がすべてだが、特定の範囲の整数が同じ確率で発生する乱数
一様乱数と同様の部分は端折る

## 整数乱数
`numpy.random.randint`で作れる
引数については一様乱数と同様
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/490bee18-a5db-b75b-24ad-98d9e4cc5c4b.png)

# ランダムなリスト操作

## ランダムに洗濯
洗濯じゃない選択（洗濯はランダムにしない）
`choice`を使う

- 指定回数選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/eec95464-edbd-2fe1-2686-4872c8450b6b.png)
`numpy.random.choice(targets, 4)`でtargetsリストから４つ選択（回数は問わない）

- １度だけ選択
1度だけ選択される（リスト内で重複があれば当然重複もする）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/d7d10283-d6a1-1fe2-2ac2-9d40081c5873.png)
`replace=False`で1度しか出現しなくなる

## ランダムに並び替え
長くないリストであれば、 choice(targets, 3, replace=False) で1度だけ選択するより
この並び替えを使うと良い
長いリストの場合はchoiceする方が効率は良い

- 並び替えた新しいリストを生成
`permutation`を使う
並び替えてもtargetsは変更されない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/8e0966de-b0d0-1b5f-21b6-169c8257b1e5.png)

- 元のリストを並び替え 
`shuffle`を使う（うん、わかりやすい名前）
元のリストを並び替える　つまり**破壊的メソッド**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/2d7a72bb-c73c-8170-410f-e5017fd38bed.png)
戻り値はないので targets で確認している

# その他様々な分布の乱数
## 標準正規乱数
`numpy.random.randn`で作れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/a0a5649f-d8ce-66fc-ab64-09c275c1de49.png)
デフォルトだと、平均が０　標準偏差１の正規分布になる
**標準偏差**については詳しくはWebでだが、散らばりの度合いを示したもの

## 正規乱数
`numpy.random.normal` で作れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/dcfe07bb-5f6e-2f25-bf1e-959c943b304d.png)
平均が５０　標準偏差１０　の乱数１０個
つまり正規分布？　本格的に統計学（？）、分布とかの勉強しないと理解に苦しむなぁ。。。
多次元も
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/e06e6a3c-b5de-b262-034d-7d6bf1dfa95e.png)

## ベータ乱数
`numpy.random.beta` で作れる

- ベータ分布
    - 軽く読んだけどﾏｼﾞﾑﾘ...
    - 軽くじゃダメそうなので、ちゃんとそれ用に時間を取って理解した方が良さげ
        
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/ea867d51-70dc-4619-faee-0d3aadb75de3.png)
α = 1　β = 2　のベータ乱数１０個　😢

## 二項乱数
`numpy.random.binomial` で作れる

- 二項分布　　（これはまだわかる！）
    - 成功か失敗の結果を持つ試行を`n`回繰り返した時の分布
    - 成功率`p`は一定とする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/e50f50a8-5096-536d-9a33-f87c9d210791.png)
この場合は、　成功率 p = 0.4 の試行を１０回やった時の成功回数、を　１０個

## ポアソン乱数
`numpy.random.poisson`
調べてみたけどよくわからない系の分布でした・・・
単位時間あたり平均でλ回発生する事象の発生回数の分布
どういう時に使われるかだけあげておくと、

- 交番の事故の件数
- 30分に平均2回電話がかかって来るコールセンターで、1時間に6回電話がかかって来る確率
 
だそうです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/77542aaf-7f44-4402-b9c9-941c58920399.png)
λ = 0.8 のポアソン乱数10個
↑これ何！！！

わからなすぎるので一旦保留だな

## 多次元正規乱数
`numpy.random.multivariate_normal` で作れる
正規乱数並みの難易度かと思いきや...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/2ee2211f-fbf9-abba-204c-3092f51a3d29.png)
平均が[0, 0]　共分散行列が [[1, 0.5], [0.5, 1]] の多次元正規乱数

もはや調べるのも無駄な抵抗なので、いつかちゃんとやる

# 乱数の再現性
numpyなどで生成される乱数は全て擬似乱数と言って、必ずシードを元に生成される
シードは実行環境の初回実行時の時刻等で初期化される
なので、明示的にシードの指定をしなくても乱数が発生させられる
（個人的なイメージ：　ビンゴカードのようなもの？ 初回実行時に新しいビンゴカードが配られる）
**何度実行しても同じ乱数が出ることを`再現性がある`という**

- 再現性のある乱数を発生させる方法
    - 最初にシードを指定 （同じビンゴカードを使う）
    - 状態を取得して、再現したいときに状態を設定　（状況に応じてビンゴカードの数字を変えちゃう？）

### シード指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/cbd0210a-0cba-65b5-0c6d-de1c4d31cb08.png)
`seed(0)` で固定しているので、何度実行しても同じになる

### 状態設定
`get_state/set_state` で取得、設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/6a721771-dac3-3b20-e5d0-7aa2ce1d05fd.png)
3行は常に同じだが、実行するたびに値は変わる

### ファイルに保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/cc7464e9-7620-2aa7-0e3f-7cccbdc1e7f7.png)
ファイルに保存して、それを読み込むことでも、再現性があると言える

# 感想
様々な乱数を見てきたけど、分布、統計という前提条件の壁がかなり高いことがわかってしまった
実践とまで言わずとも、自分で何かやってみようという段階になるまでには
まだまだ長い道のりになりそうだー