【その3】DeepLearningを使って気象画像から天気予報をする


#前回まで
前回までは以下

[DeepLearningを使って気象画像から天気予報をする1](http://qiita.com/wbh/items/1984b582071ef60c92f3)
[DeepLearningを使って気象画像から天気予報をする2](http://qiita.com/wbh/items/9f5f542be4876e4748fc#_reference-8cc006f1adb3cc73bb7a)

まとめておくと、

* 気象画像(衛星写真)から画像処理を行い、畳み込みニューラルネットワークを用いて次の日の天気を予想します。
* 教師データには「晴」「雨」の二値を用いました。
* 画像は日本付近のRGB画像とし、2015年を学習データ、2016年をテストデータとして評価を行いました。
* 結果、平均AUCで0.70、FScoreで0.72となり実際の確率と詳細な天気をみると、大雨や快晴などの明らかなものは当てているものの、「曇」や「一時雨」等での精度はイマイチでした。
* 統計量の詳細は以下でした。

|天気|Precision|Recall|F-Score|
|--:|--:|--:|--:|
|雨|0.54|0.67|0.6|
|晴|0.83|0.74|0.78|
|平均|0.74|0.72|0.72|

#今回の話
今回はモデルの改良・教師データ・説明変数の改良を行って精度を上げていきたいと思います。

具体的には

* 三値(晴、曇、雨)分類
* Epochの増加
* 説明変数(画像)処理の追加
* 画像を変えてみる

あたりになります。

#分析
## 三値分類
今までは「晴」と「雨」の二値分類としていました。しかし、この中には「曇」が多量に含まれるため、これが精度を落とす一つの要因となっていました。
ですので、素朴に「曇」も含めた三値分類としてみます。

教師データ生成の条件は以下のようになります。

```python
flag = []
for tk in tenki_list:
	if "雨" in tk:
		flag.append(0)
	elif "晴" in tk:
		flag.append(2)
	else:
		flag.append(1)
```

雨を最も優先する形で、次に晴、最後に残ったものが曇とします。

テスト結果が以下のようになります。各確率は天気での平均確率になります。
雨確率の降順でソートしています。

| 天気                       | 雨確率 | 曇確率 | 晴確率 |
|----------------------------|-------:|-------:|-------:|
| 大雨後時々晴、みぞれを伴う |    98% |     0% |     2% |
| 雨後曇、あられを伴う       |    97% |     0% |     3% |
| 雨                         |    96% |     1% |     3% |
| 大雨                       |    95% |     1% |     4% |
| 晴一時雨                   |    95% |     0% |     5% |
| 曇一時雨後時々晴           |    91% |     1% |     8% |
| 曇後時々晴                 |    90% |     3% |     6% |
| 雨時々晴一時霧雨           |    89% |     2% |    10% |
| 大雨後一時曇               |    80% |     3% |    17% |
| 曇時々雨一時晴             |    77% |     4% |    19% |
| 曇時々晴後一時雨、雷を伴う |    74% |     5% |    21% |
| 雨後一時曇                 |    72% |     6% |    22% |
| 雨後晴                     |    72% |     4% |    24% |
| 曇一時雨                   |    71% |     5% |    24% |
| 雨後曇                     |    71% |     3% |    26% |
| 曇時々雨                   |    70% |     5% |    25% |
| 雨後時々曇                 |    67% |     3% |    29% |
| 雨一時曇                   |    63% |     7% |    30% |
| 晴後曇                     |    63% |     4% |    33% |
| 雨時々曇一時晴             |    62% |     8% |    30% |
| 雨時々曇                   |    61% |     4% |    35% |
| 晴時々薄曇                 |    60% |     3% |    37% |
| 曇時々晴                   |    59% |     5% |    36% |
| 曇後雨                     |    57% |     7% |    36% |
| 晴後一時雨、雷を伴う       |    52% |    11% |    36% |
| 曇後一時晴                 |    51% |     6% |    44% |
| 雨一時みぞれ後時々曇       |    50% |     7% |    44% |
| 曇後一時雨                 |    49% |    10% |    41% |
| 曇                         |    45% |     8% |    47% |
| 薄曇                       |    42% |     7% |    52% |
| 薄曇一時晴                 |    38% |    10% |    52% |
| 晴一時薄曇                 |    38% |     8% |    55% |
| 薄曇後時々晴               |    38% |    11% |    52% |
| 晴後一時薄曇               |    34% |     9% |    57% |
| 薄曇時々晴                 |    34% |     8% |    58% |
| 曇一時晴                   |    33% |     7% |    60% |
| 晴時々曇                   |    33% |     9% |    58% |
| 曇一時雨後一時晴           |    31% |    13% |    56% |
| 晴                         |    30% |     9% |    61% |
| 晴一時曇                   |    30% |     8% |    62% |
| 晴後薄曇                   |    28% |    11% |    61% |
| 晴後時々曇                 |    27% |     8% |    65% |
| 快晴                       |    25% |     7% |    68% |
| 曇後晴                     |    22% |    10% |    68% |
| 曇後時々雨                 |    20% |     8% |    72% |
| 曇一時雨後晴               |    20% |    11% |    70% |
| 曇時々晴後一時雨           |    18% |    10% |    73% |
| 晴後雨時々曇               |     4% |     5% |    91% |

結果としては、曇はまったく予測されていません。(まじか)

さきの条件式での教師データが以下のようになっているため、曇を非常に推定しにくい感じにしているんだと思います。

| 天気 | 割合 |
|------|------|
| 雨   | 33%  |
| 曇   | 7%   |
| 晴   | 59%  |

これだと明らかな「曇」だけを弾く感じになっています。
ただ、例えば「曇が含まれる」という条件を先に持ってくると、今度は雨と晴の数が減りすぎてだめになります。んー難しい。

ただ、「雨」と「晴」だけで平均AUCを計算すると0.720となり、この二つの精度は上がっているようです。雨と晴の統計量は以下のようになりました。

|  天気| precision | recall | f1-score |
|------|----------:|-------:|---------:|
| 雨   |      0.60 |   0.76 |     0.67 |
| 晴   |      0.69 |   0.71 |     0.70 |
| 平均 |      0.65 |   0.74 |     0.69 |

どうやら「雨」の推定精度が上がっているようです。

## Epochの増加
前回はEpoch=50でやっていましたが、今回Epochを100にしてみます。
教師データは前回と同様で「雨」「晴」の二値分類です。

平均AUCは0.724となり、前回および三値分類よりも精度が上がりました。
(Epoch大事)

統計量は以下のとおり。

| 天気 | precision | recall | f1-score |
|------|----------:|-------:|---------:|
| 雨   |      0.53 |   0.77 |     0.63 |
| 晴   |      0.86 |   0.68 |     0.76 |
| 平均 |      0.76 |   0.71 |     0.72 |

Precisionが上がっている感じです。

## 説明変数(画像)処理の追加
ここまで説明変数を3チャネルの前日の画像データとしていました。
ただ、元になる地図画像のデータというのはどの時点でも共通で分類に意味を持たない情報になります。ですので、前日との差分をとることで「変化」した情報を組み入れることを考えます。

コードで書くと以下のようになります。

```python
    """差分系列に変換する"""
    img_mat_new = np.zeros((img_mat.shape[0],3*2,img_mat.shape[2],img_mat.shape[3]),dtype=np.float32)
    img_mat_new = img_mat_new[0:-1] #一つ減らす
    for l in range(1,len(img_mat)):
        """差分"""
        img_mat_new[l-1,0,:,:] = img_mat[l-1,0,:,:] - img_mat[l,0,:,:]
        img_mat_new[l-1,1,:,:] = img_mat[l-1,1,:,:] - img_mat[l,1,:,:]
        img_mat_new[l-1,2,:,:] = img_mat[l-1,2,:,:] - img_mat[l,2,:,:]
        """その日"""
        img_mat_new[l-1,3,:,:] = img_mat[l,0,:,:]
        img_mat_new[l-1,4,:,:] = img_mat[l,1,:,:]
        img_mat_new[l-1,5,:,:] = img_mat[l,2,:,:]
```

教師データを1日分減らすのを忘れない。

この状態でinput channelを6としてモデルに導入します。

すると、平均AUCは0.658と下がります。(あれれー)

統計量は以下のようになります。

| 天気 | precision | recall | f1-score |
|------|----------:|-------:|---------:|
| 雨   |      0.57 |   0.48 |     0.52 |
| 晴   |      0.78 |   0.83 |      0.8 |
| 平均 |      0.71 |   0.72 |     0.71 |

晴の精度は上がっていますが、雨がだめですね。うーん難しい。

##画像データを変えてみる
画像データを別の種類のものにかえたらどうなるか。
今まで640x480の解像度でしたが、3000x3000の高解像度の画像に変えてみます。
ただ、問題なのは **可視**画像です。(つまり太陽の光、季節の影響を受ける)

以下のような画像になります。

![jpn.14123117.jpg](https://qiita-image-store.s3.amazonaws.com/0/54539/f11b481b-f49a-32b9-ef6d-6e5bcd57eb6b.jpeg "jpn.14123117.jpg")

出典: 高知大学・東京大学・気象庁提供

うわー黒いとこある。。。

まぁものは試しだ。

平均AUCで0.675と従来のものよりも下がります。

統計量は以下のようになります。

| 天気 | precision | recall | f1-score |
|------|----------:|-------:|---------:|
| 雨   |      0.69 |   0.45 |     0.54 |
| 晴   |      0.77 |    0.9 |     0.83 |
| 平均 |      0.75 |   0.76 |     0.74 |

FScoreで見ると精度が上がっています。晴AUCで0.79でているので、晴の精度が上がったものの、雨の精度が若干落ちたようです。

#結果
いろいろと試しましたが、

* 三値分類では「曇」の扱いをどうするか、がやはり問題であるものの、雨の精度は上がった。
* Epochを増加させると効果がありそう。
* 差分系列を導入すると、むしろ精度が落ちる。導入の仕方が悪い可能性がある。純粋な画像データと差分系列だとスケールが異なるので、6チャネルとしてはダメかも？
* 可視画像にすると意外に晴の精度は上がる。(RGBに変換するから暗いところはあまり問題にならない？)

のようになりました。

Epochを増加させて、三値分類にして(雨精度を上げたい)、可視画像にする(晴精度を上げたい)とするパターンがいいのかな？

とりあえずAUC0.8を目指したい。

時系列的な要素があるのでRNNとかに拡張したほうが精度でるのかな？(勉強しないと)