気色の写真を用いて周辺気温の予測

以下の写真はレインボーブリッジだが、撮影当時の周辺気温は何度だろうか。
![レインボーブリッジ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1978095/640cd7cd-18c5-5381-5c06-085c2cc4d679.png)
予測するために気温に影響与える要素を考えてみましょう。一番目の要素は撮影時刻で、早朝の写真なら気温低くて夕焼けなら高いと思われる。また、季節や場所も気温に大きな影響を与え、このような複数の要素を考えて予測する必要がある。確かに人間だとなかなか難しいタスクである。ちなみに、写真当時の気温は5.4度だった。
#### 目的
この記事ではレインボーブリッジの写真から当時の周辺気温を予測できる機械学習モデルを開発したい。
#### 手法
写真から気温を予測するには畳み込みニューラルネットワーク(Convolutional Neural Network・CNN)を使用する。CNNは物体検出や顔認識のような分類問題によく応用される。だが、今回のタスクの目的変数である「気温」は連続型の変数であり、問題は回帰問題となる。
![レインボーブリッジ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1978095/e0c19c3f-d727-8f90-9db4-9a5b14e1bd41.jpeg)
#### データ収集
モデルを開発するにあたって、気色の写真とその写真当時の周辺気温の２つのデータが必要となる。このため、YoutubeのAPIを通じての[お台場ライブ配信](https://www.youtube.com/watch?v=n3B8fp-Henc)に50秒に一回繋がり、ビデオのスクリーンショットを撮る。これと同時に「OpenWeatherMap API」に繋がり、レインボーブリッジ周辺の気温を記録する。一回で入手した二つのデータ（画像・気温）にあとで紐づけられるようにタイムスタンプもつける。これを繰り返し２日間ぐらい実施し、２千個以上のデータポイントを入手する。
#### データ処理
OpenWeatherMapのAPIにて、経度・緯度を設定し、特定のところの天気情報をリアルタイムで得られる。APIにRequestすると、その座標の最寄り観測ステーションから情報が提供される。しかし、少し遠くとも最新情報持っている他のステーションがあったらそのステーションから情報が提供される場合もある。レインボーブリッジの場合はRequestの時間によって三田や品川ステーションから情報が提供される。情報の非連続さを避けるため、このモデルで三田ステーションから提供される情報のみを使用する。この処理を経て1,902ののデータポイントが残る。画像のFilepathとその時の天気情報を一つのCSVファイルに集計し、画像と合わせてGoogle Driveにアップロードする。Google Driveのファイルを参照し、Google ColabのGPU環境ででモデルを学習させる。
![レインボーブリッジ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1978095/f19e3c00-0d22-ed30-41ae-5ecbb048e02b.jpeg)
#### モデル
レインボーブリッジの1,902枚の画像のデータセットをトレーニング（70%)とテスト(30%)に分ける。トレーニングデータセットの一部分が過剰適合を防ぐようearly stoppingのために使用する。
このモデルのニューラルネットワークは以下の階層から成り立つ：
* 1つの入力階層
* 2つの畳み込み＋Max Pool階層
* 1つのGlobal Average Pool階層
* 3つのDense階層
* 1つの出力階層

畳み込み階層は画像の左上から右下まで小さな枠（2x２Pixelのような）を流し、画像から重要そうな要素を洗い出す。畳み込み階層から出る結果のサイズを縮めるため、結果にMax Pool関数を適用する。この組み合わせを２回実施し、結果のサイズをもっと縮小するためにGlobal Average Pool関数を適用する。これから出る結果を単純ニューラルネットワークで使われる３枚のDense Layerを通じて一つの出力（気温）に変換する。
画像処理では写真のPixelを一つずつ扱われるためCPUに大きな負担かかり、学習は長い時間かかる。学習を加速させるためにGoogle Colabにモデルをアップロードする。最初にEpoch（学習ステップ）はデータをGPUに運ぶため長い時間かかるがその後のEpochは早く実施され10分以内で学習が終わる。
![レインボーブリッジ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1978095/3f2081f4-27cc-892f-3f41-0c43fb316af7.jpeg)
#### 結果
モデルを学習させ、テスト画像の気温を予測してみる。Root Mean Squared Error（平均二乗誤差の平方根）は 1.2°C、R-squaredは0.79である。画像のみが説明変数をして使用されたのに、モデルは意外と高い精度を得られる。
#### 終わりに
この記事ではレインボーブリッジ周辺の写真を用いて気温を予測するために畳み込みニューラルネットワく（CNN）の機械学習モデル開発した。2日間にわたってYoutubeから写真、OpenWeatherMapから気温情報を入手し、1,902枚の写真と関連気温データを用いてモデルを学習させ、高い精度が得られた。（R-squared: 0.79, RMSE: 1.2°C）気温の変動が激しい日の入りや日の出の時にモデルの精度が低くなるが、時間帯を説明変数を入れたら精度が改善することが期待できる。また、2日間のみならず、1年間などの長期的なデータを使用し、よりgeneralizable（一般化可能な）モデルも開発できるのも考えられる。
#### 自分で試してみて！
このプロジェクトの[Website](https://weather-prediction.vercel.app/)にて自分が持っている画像の気温を予測できる。画像はブラウザのみで扱われ、データベースなどに発信されないので安心してモデルを試してみてください。
![Website](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1978095/142a2b0c-239d-f1da-df74-e46b3df60287.png)
#### 参考
* [プロジェクトのサイト](https://weather-prediction.vercel.app/)
* [機械学習コード](https://colab.research.google.com/drive/1cFlGTV0bDZgda3qLoO5cGHvcbFrHE0J5?usp=sharing)
* [データ収集コード](https://colab.research.google.com/drive/11DMV4It_DxDvq1TaojlOROhVncjtp306?usp=sharing)
* [データ](https://drive.google.com/drive/folders/19egAgOXflnckYDF9DzvC261R47jqwV_u)