Python: 競技とギャンブルと温度

# 競技とギャンブルと温度
## はじめに
### 考察
　私は勝負の勝敗は競技者の「実力」の差、とゲームの「温度」によって決定すると考察する。そして、競技とギャンブルに明確な境界線はないが、この温度が「競技」と「ギャンブル」の指標になっているのではないか。
### 方策
　ここでは、「実力」を０～１の範囲で表し、「運」を温度として考えてみる。温度が低いと実力差は安定し、明確な差として勝負に現れる。温度が高いと実力差は不安定になり、運の要素が勝負に現れる。これを実際に視覚的に確認するために、[wiki(活性化関数)](https://ja.wikipedia.org/wiki/%E6%B4%BB%E6%80%A7%E5%8C%96%E9%96%A2%E6%95%B0)における、多クラス分類の活性化関数であるソフトマックス関数に注目する。二値分類でもよいが、競技者が複数いるゲームも考慮しこちらを用いる。この関数を用いて実力を確率に変換していく。その際、よく用いられる温度の概念を導入することで、ゲームの「温度」によってその確率を勝率へと補正していく。

### 準備
#### おまじない
　今回のおまじないは以下になります。

```python
import numpy as np
import matplotlib.pyplot as plt
```

#### 関数定義
　今回定義した関数は以下の`softmax`, `cal_win_rates`, `win_rate_show`の3つです。まず、[wiki(活性化関数)](https://ja.wikipedia.org/wiki/%E6%B4%BB%E6%80%A7%E5%8C%96%E9%96%A2%E6%95%B0)における、多クラス分類の活性化関数であるソフトマックス関数が`softmax`です。これが、競技者の「実力」の差を確率に変換してくれます。その際、確率を勝率に補正するためにゲームの「温度」で補正する必要があり、これが`cal_win_rates`です。今回重要なのはほぼこれだけで、これを可視化するための関数が`win_rate_show`です。

```python
# ソフトマックス関数->競技者の「実力」の差を確率に変換する
softmax = lambda x: np.exp(x) / np.sum(np.exp(x))
# 勝率を計算する関数->競技者の「実力」の差をゲームの「温度」で補正し勝率に変換する
cal_win_rates = lambda x, T: np.array([softmax(x / t) for t in T])


def win_rate_show(x, T):
    """ 競技者の実力とゲームの温度から勝率の関係を可視化

    :param x: 各自の実力
    :param T: 温度
    """

    y = cal_win_rates(x, T) # 「実力」「温度」における「勝敗確率」
    plt.figure(figsize=(10.0, 5.0))
    for i in range(len(x)):
        plt.plot(T, y[:, i] * 100, label='Player'+str(i+1))
    plt.xlabel("T", size=14)
    plt.ylabel("win rate", size=14)
    plt.legend()
    plt.show()
```

## 実験
　実験はとても簡単です。最初に
　$$勝負の勝敗は競技者の「実力」の差、とゲームの「温度」によって決定する。$$
っと言ってしまったので、実際に競技者の「実力」を`x = [1, 0]`として定義します。1がPlayer1の実力、0がPlayer2の実力です。次にゲームの「温度」ですが、これが変化した時に勝率がどのようになるか見たいので、 `T = [0.01, 0.02,..., 10]`と変化させながら定義します。あとは最初に定義した`win_rate_show`にぶち込めば結果が可視化されます。

```python
x = np.array([1, 0]) # 競技者の「実力」
T = np.linspace(0.01, 10, 1000) # ゲームの温度の変化
win_rate_show(x, T) # 描画処理
```

　以下が描画結果で、温度が低い左側ではPlayer1の勝率がほぼ100%付近になっています。これは、ゲームの温度が低いことで実力差が安定し、明確な差として勝負に現れていると言えます。一方で、温度が高い右側では、変わらすPlayer1の勝率が高いものの、ほぼ50%付近まで落ちてしまっています。これは、温度が高いと実力差は不安定になり、運の要素が勝負に現れていると言えます。そして、さらに温度を上げていくと、最終的には実力差は無視され、運だけで勝負が決まるようになるでしょう。

![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/cc471fc5-acd6-5664-dd61-832d238e54dc.png)

　次に競技者の「実力」を`x = [1, 0.9]`として定義します。つまり、Player2の実力が上がった場合です。こうすると、相変わらず温度が0の付近ではPlayer1の勝率はほぼ100%です。ですが先ほどと異なり、少しでも温度が上がると急速に50%付近に近づいていく様子がわかります。

```python
x = np.array([1, 0.9]) # 競技者の「実力」
T = np.linspace(0.01, 10, 1000) # ゲームの温度の変化
win_rate_show(x, T) # 描画処理
```

![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/0d25c4b6-0f1e-0bf3-4144-4bc419b21838.png)

　最後に競技者の数を増やしてみましょう。`x = [1, 0.5, 0.2, 0.0]`こんな感じですね。最初に二値分類ではなく、他クラス分類を見越してソフトマックス関数にしていた恩恵で、問題なくそのまま解けます。

```python
x = np.array([1, 0.5, 0.2, 0.0]) # 競技者の「実力」
T = np.linspace(0.01, 10, 1000) # ゲームの温度の変化
win_rate_show(x, T) # 描画処理
```

　描画結果です。なかなか面白い感じです。

![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/385baeba-a5cc-be1c-b422-cbaddb9cd0e7.png)

## まとめ
　ゲームの勝敗は「実力」と「温度」によって決まるのではないかと考えられます。そして、競技性が高いとは、「温度」が低いゲームの事で、ギャンブル性が高いとは「温度」が高いゲームの事だと思います。ただし、温度が高いから「悪い」とか温度が低いから「良い」とか言う話ではありません。例えば視聴者から見る「面白いゲーム」について考えると、「エンターテインメント性」も絡んでくるかと思います。私の考える「エンターテインメント性」が高いゲームとは「拮抗した勝負」且つ「運要素が少ない（より正確には、視聴者が運だと認識していない）」ゲームだと思います。ですが、温度が低すぎると「拮抗した勝負」にはならないし、温度が高すぎると「運要素が少ない」にならないのです。「運も実力の内」というように、ワクワクする競技とはある程度運要素を含むものなのかもしれません。
　また、ギャンブルについても、温度が高ければよいというわけではないかと思います。温度が高すぎると、おそらく思考する幅が無いので物足りないと感じるでしょう。ただし！一般的なギャンブルは「温度」が低いと参加者に錯覚させて、確率と還元率によって参加者が損するようにしてある。または、「温度」が高いと参加者に錯覚させて、胴元が高い勝率を維持し参加者が損するようにしてあります。その際の「実力」には、技術だけではなく、作戦や戦略、ペテンなども含まれています。皆さん注意しましょうね(´っ･ω･)っ