平均-分散モデルによる燃料輸入のポートフォリオ分析


### ポートフォリオ分析とは
価格特性の異なる複数の商品の組み合わせを```ポートフォリオ```と呼ぶ
その最適な組み合わせを求める分析法を```ポートフォリオ分析```という
今回はポートフォリオ分析の最も基本的な手法である```平均-分散モデル```を用いる

### 安価と安定を定義
安価→燃料価格の平均値が低い
安定→燃料価格の分散（あるいは標準偏差）が低い


燃料資源を持たないJ国がA・Bの２国から化石燃料を輸入している。両国が輸出する化石燃料の性質は全く同じだと仮定する。下表は両国が輸出する燃料価格の1年間の推移<br>

| | 1 | 2 | 3 | 4 | 5 | 6| 7 | 8 | 9 | 10 | 11 | 12 |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
|A国|4.3|4.9|5.5|6.0|4.7|4.4|5.7|5.9|6.2|4.9|5.1|5.5|
|B国|3.8|2.7|2.4|2.2|7.4|7.5|4.3|3.7|3.1|5.8|5.9|5.8|






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


```python
# 燃料価格の推移データ（月別）
fuel_prices= np.array([(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12),(4.3, 4.9, 5.5, 6.0, 4.7, 4.4, 5.7, 5.9, 6.2, 4.9, 5.1, 5.5),  (3.8, 2.7, 2.4, 2.2, 7.4, 7.5, 4.3, 3.7, 3.1, 5.8, 5.9, 5.8)])
fuel_prices.shape
```




    (3, 12)




```python
plt.bar(fuel_prices[0],fuel_prices[1], alpha=0.5, label = "country_A")
plt.bar(fuel_prices[0],fuel_prices[2], alpha=0.5,  label = "country_B")
plt.legend() 
plt.title("Changes in fuel prices")
plt.xlabel("Month")
plt.ylabel("Fuel prices")
plt.show()
```


![output_3_0.png](https://qiita-image-store.s3.amazonaws.com/0/154863/2e9d99a2-07d5-2fff-2b01-76fa3865d914.png "output_3_0.png")



## 両国における燃料価格の平均と標準偏差


```python
# 平均と標準偏差
ave_A = np.average(fuel_prices[1]) 
ave_B = np.average(fuel_prices[2])
std_A = np.std(fuel_prices[1])
std_B = np.std(fuel_prices[2])
print('A国 平均:{0:.2f} 標準偏差:{1:.2f}'.format(ave_A, std_A))
print('B国 平均:{0:.2f} 標準偏差:{1:.2f}'.format(ave_B, std_B))
```

    A国 平均:5.26 標準偏差:0.61
    B国 平均:4.55 標準偏差:1.80


上記の結果よりA国の燃料価格は高価だが安定しており、B国は安価だが不安定であることがわかる。

## A国:B国の輸入比率が40%:60%の時のポートフォリオ平均とポートフォリオ標準偏差


```python
weighted_ave = [x*0.4 + y*0.6 for (x, y) in zip(fuel_prices[1], fuel_prices[2])]
plt.bar(fuel_prices[0], weighted_ave, label = "weighted average")
plt.title("weighted average")
plt.xlabel("Month")
plt.ylabel("Fuel prices")
plt.show()
```

![output_8_0.png](https://qiita-image-store.s3.amazonaws.com/0/154863/5b986746-546a-707f-d9dd-d95c95e5c3a3.png "output_8_0.png")





```python
ave_wa = np.average(weighted_ave)
std_wa = np.std(weighted_ave)
print('ポートフォリオ 平均: {0:.2f} 標準偏差:{1:.2f}'.format(ave_wa,std_wa))
```

    ポートフォリオ 平均: 0.75 標準偏差:2.16


## ポートフォリオの標準偏差を最小値化する輸入比率
1~100:100~1の間で加重値を変え、平均値と標準偏差の関係を調べる。


```python
ave_list = []
std_list = []
for i in range(0,100):
    weighted_ave = [x*(i/100) + y*((100-i)/100) for (x, y) in zip(fuel_prices[1], fuel_prices[2])]
    ave_list.append(np.average(weighted_ave))
    std_list.append(np.std(weighted_ave))

plt.plot(ave_list,std_list)
```




    [<matplotlib.lines.Line2D at 0x109b5bda0>]




![output_11_1.png](https://qiita-image-store.s3.amazonaws.com/0/154863/91a5d2c2-e5db-8d18-31d9-52745baa9aa0.png "output_11_1.png")



上記グラフより平均と標準偏差の関係は下に凸であることがわかる。


```python
# 共分散行列
sig = np.cov(fuel_prices[1], fuel_prices[2])
print(sig)
```

    [[ 0.40083333 -0.67136364]
     [-0.67136364  3.52636364]]



```python
x_1 = (sig[1][1]-sig[0][1])/(sig[0][0]-2*sig[0][1]+sig[1][1])
x_2 = (sig[0][0]-sig[0][1])/(sig[0][0]-2*sig[0][1]+sig[1][1])
print('厳密解 x1:{0:.3f} x2: {1:.3f}'.format(x_1,x_2))

weighted_ave_ture = [x*x_1 + y*x_2 for (x, y) in zip(fuel_prices[1], fuel_prices[2])]
ave = np.average(weighted_ave_ture) 
std = np.std(weighted_ave_ture)
print('平均:{0:.2f} 標準偏差:{1:.2f}'.format(ave, std))

plt.bar(fuel_prices[0], weighted_ave_ture, label = "weighted average ture")
plt.title("weighted average ture")
plt.xlabel("Month")
plt.ylabel("Fuel prices")
plt.show()
```

    厳密解 x1:0.797 x2: 0.203
    平均:5.11 標準偏差:0.41



![output_14_1.png](https://qiita-image-store.s3.amazonaws.com/0/154863/a9ca256d-39c6-fa9d-2a9b-b74138e7e337.png "output_14_1.png")



従って79.7%:20.3%の時に最も安定した輸入を行うことができると考えられる。

twitterでも機械学習に関する情報・オススメ記事などつぶやいているので、フォローお待ちしています。
[@bam6o0](https://twitter.com/bam6o0)