100日後にエンジニアになるキミ - 63日目 - プログラミング - 確率について1

昨日までのはこちら

[100日後にエンジニアになるキミ - 59日目 - プログラミング - アルゴリズムについて](https://qiita.com/otupy/items/f1a5e81633b868f3b5ed)

[100日後にエンジニアになるキミ - 53日目 - Git - Gitについて](https://qiita.com/otupy/items/0abaad82a7f3fea73f1f)

[100日後にエンジニアになるキミ - 42日目 - クラウド - クラウドサービスについて](https://qiita.com/otupy/items/d1765f1541a104ed6133)

[100日後にエンジニアになるキミ - 36日目 - データベース - データベースについて](https://qiita.com/otupy/items/7af17635d576677606dc)

[100日後にエンジニアになるキミ - 24日目 - Python - Python言語の基礎1](https://qiita.com/otupy/items/6d1e5453f530e07b7aec)

[100日後にエンジニアになるキミ - 18日目 - Javascript - JavaScriptの基礎1](https://qiita.com/otupy/items/2f71d5f9c754b29d9555)

[100日後にエンジニアになるキミ - 14日目 - CSS - CSSの基礎1](https://qiita.com/otupy/items/61a97863f6df14171994)

[100日後にエンジニアになるキミ - 6日目 - HTML - HTMLの基礎1](https://qiita.com/otupy/items/cd2315dcb38671cfded0)

## 確率について

辞書で引くと`現象全てに対する割合`の事のようです。

プログラミングではこの確率の計算も良く出てきます。

また、確率とともに統計というのも扱う分野の一つであるので
プログラマーとしてやっていくなら用語や計算方法については
抑えておいた方が良いかなと思います。

## 確率の用語

抑えておきたい確率の用語をピックアップしました。

| 用語 | 英語 | 意味 |
|:--|:--|:--|
| 確率 | Probability | 事象が起こる割合 |
| 順列 | Permutation | 異なるn個からr個を取り出した順に1列に並べること |
| 組み合わせ | Combination | 異なるn個のものからr個を取り出すこと |
| 階乗 | Factorial | ある正の整数から1までの整数の積 |
| 独立 |  | お互いの結果が影響しあうことがないこと |
| 試行 |  | 確率を求めるために試しにやってみる行為のこと |
| 反復試行 |  | 条件を変えずに、同じ行為を繰り返すような試行 |
| 期待値 | Expected value | 1回の試行で得られる値の平均値 |
| 事象 | Event | 起こること |
| 積事象 |  | 2つの事象AとBのうちAとBが同時に起こる事象 |
| 全事象 |  | 起こる結果全てをまとめたもの |
| 根元事象 | Atomic event | それ以上細かく分けることが出来ない事象のこと |
| 余事象 |  | ある場合以外の事象 |
| 排反事象 |  | 同時に起こらない」事象のこと |
| 空事象 |  | 存在しない事象のこと |
| ベン図 |  | 複数の集合の関係や、集合の範囲を視覚的に図式化したもの |
| オッズ | odds | 確率論で確率を示す数値 |
| 確率分布 | probability distribution | 確率変数に対して、各々の値をとる確率を表した |
| 確率変数 | random variable | 起こりうることがらに割り当てている値 |
| 離散型(確率変数) | Discrete | とびとびの数になる確率変数 |
| 連続型(確率変数) | Continuous | 幾らでも細かく刻むことができる確率変数 |



## 確率の計算

Pythonでは確率計算をするのに役立つライブラリがあり
比較的楽に確率の計算をすることができます。

### 階乗(factorial)

`階乗`は`math`ライブラリなどの`factorial`メソッドで計算ができます。

計算方法はある正の整数から1までの整数の積になるので
4の階乗であれば`4*3*2*1 (4!)`となり`24`になります。

```python
import math

print(math.factorial(4))
print(math.factorial(10))
```
24
3628800

### 順列

`順列`とは`異なるn個のものからr個選んで一列に並べる場合の数`です。

リスト(配列)などから順列を生成して列挙することができます。
`itertools`ライブラリの`permutations`で求められます。

`itertools.permutations(リスト値,選ぶ個数)`

この場合返却される値そのものはリストではないので
値を見たければリストに変換が必要です。

以下は3個の中から2つを選んで並べた際の順列です。

```python
import itertools

l = ['A', 'B', 'C']

p = itertools.permutations(l, 2)
print(list(p))
```
[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]


### 順列の総数

数が少ない場合は列挙する事ができますが、順列の個数が多すぎると表示はできないので
総数だけを求めるのであれば`math.factorial`を使って計算できます。

計算式は`n! / (n - r)!`となるので`7`個から`5`個を選ぶ順列の総数は

```python
n , r = 7 , 5
math.factorial(n) // math.factorial(n - r)
```
2520

これで求める事ができます。

### 組み合わせ

`組み合わせ`は異なる`n`個のものから`r`個選ぶ場合の数で順列のように順番を考慮しません。

リスト(配列)などから順列を生成して列挙することができます。
`itertools`ライブラリの`combinations`で求められます。

`itertools.combinations(リスト値,選ぶ個数)`

5個の中から2個を選ぶ組み合わせの列挙は以下のようになります。

```python
l = ['a', 'b', 'c', 'd','e']
c = itertools.combinations(l, 2)
print(list(c))
```
[('a', 'b'), ('a', 'c'), ('a', 'd'), ('a', 'e'), ('b', 'c'), ('b', 'd'), ('b', 'e'), ('c', 'd'), ('c', 'e'), ('d', 'e')]

この場合は要素同士の重複はありません。

要素同士の重複も加味して組み合わせを作るには
`combinations_with_replacement`を用います。

`itertools.combinations_with_replacement(リスト値,選ぶ個数)`

```python
l = ['a', 'b', 'c']
c = itertools.combinations_with_replacement(l, 2)
print(list(c))
```
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')]

### 組み合わせの総数
総数だけを求めるのであれば`math.factorial`を使って計算できます。

計算式は`n! / (r! * (n - r)!)`となるので`7`個から`3`個を選ぶ組み合わせの総数は
次のようになります。

```python
n , r = 7 , 3
math.factorial(n) // (math.factorial(n - r) * math.factorial(r))
```
35

### デカルト積(複数のリストの直積)

`複数のリストの直積`を作成するには`itertools`ライブラリの`product`を用います。

`itertools.product(リスト値,リスト値)`

```python
l1 = ['a', 'b', 'c']
l2 = ['X', 'Y']
p = itertools.product(l1, l2)
print(list(p))
```
[('a', 'X'), ('a', 'Y'), ('b', 'X'), ('b', 'Y'), ('c', 'X'), ('c', 'Y')]

引数`repeat`に繰り返しの回数を指定すると、イテラブルオブジェクトを繰り返し使用して
直積を生成できます。

`itertools.product(リスト値,repeat=回数)`

```python
l1 = ['a', 'b', 'c']
p = itertools.product(l1, repeat=2)
print(list(p))
```
('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')]


## まとめ

確率について触れていきますが、まずは用語とかを覚えてみましょう。
明日は期待値の計算についてです。

君がエンジニアになるまであと37日

## 作者の情報
乙pyのHP：
http://www.otupy.net/

Youtube：
https://www.youtube.com/channel/UCaT7xpeq8n1G_HcJKKSOXMw

Twitter：
https://twitter.com/otupython