[Python]海釣り公園の釣果予測をやってみた

# はじめに
こんにちは。Qiita初投稿・データサイエンス勉強中の非ITエンジニアです。
学習の一環として、海釣り公園での釣果予測をやってみました。至らぬ点満載かと存じますが、暖かくご指摘・コメントいただければ幸いです。

# 目次
- 目的・背景
- 課題設定
- 取り組み内容
- データ収集
- データクレンジング
- データの考察
- 学習に使用したデータ
- 学習と精度検証
- まとめ


# 目的・背景
私は趣味として釣りをしています。釣竿やクーラーを持って行ったり釣りに行くのも一苦労なので、なるべく魚が沢山釣れる日に釣りに行きたいです。きっと多くの釣り人が同じ思いを抱いていると思います。
そこで、データサイエンスを使った釣果（何匹の魚が釣れるか）予測にチャレンジすることにしました。

# 課題設定
課題は「海釣り公園のアジの釣果予測(匹/人・日)」としました。
理由は以下の通りです。
- 釣り場　：　海釣り公園
    - トイレや手洗い場等の設備が充実している家族に人気の釣り場
    - 学習データ（釣果データ）が海釣り公園のブログから入手できる

- 対象魚：アジ
    - 小さいお子さんでも釣りやすいファミリーフィッシングに人気の魚
    - 比較多く釣れる魚であるため、他の魚よりも多くの学習データが収集できる

# 取り組み内容
1) データ収集
2) データクレンジング
3) データの考察
4) 学習
5) 性能テスト

# データ収集
スクレイピング等を実施して以下のデータを収集しました。

- 海釣り公園の釣果データ:　海釣り公園のブログ
    - 日付
    - 入場者数
    - 魚ごとの釣れた匹数
- 気候データ：　https://www.data.jma.go.jp/gmd/risk/obsdl/
    - 日付
    - 天気概況
    - 平均気温、最高気温、最低気温
    - 降水量
    - 平均風速、最大風速、風向き

- 潮汐データ：　https://www.data.jma.go.jp/gmd/kaiyou/db/tide/genbo/index.php
    - 日付
    - 満潮潮位、満潮時刻
    - 干潮潮位、干潮時刻

収集したデータをまとめた結果は以下です。
![all_data.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3088283/7707f31c-d348-55b5-febf-2e0791bf97bf.png)


# データクレンジング
降水量、風速、釣果に対してデータクレンジングを実施しました。

**1) 降水量、風速データに基づくクレンジング**

３σ法を使って外れ値除去をします。
- 降水量：　平均＋３σ ＝ 51.4mm/day 
- 風速：　平均＋３σ ＝ 6.8m/s

50mm/day以上の降水量、6m/s以上の風速では釣りには難しい環境だと言われています。厳しい環境でも釣りをしている人は少数のため、釣果(匹/人・日)の値が著しく大きくなる可能性があり、外れ値として扱うことは妥当だと推察します。

降水量データの確認結果(外れ値除去前)
<table>
<tr>
<td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3088283/19f6cc01-a7ed-ee19-3002-39281c3b3b2b.png"></td>
<td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3088283/058bc750-154a-d10a-3039-f595cad19f11.png"></td>
</tr>
</table>

平均風速データの確認結果(外れ値除去前)
<table>
<tr>
<td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3088283/05a5bcbe-a64b-49fd-7250-3d6163b7ca88.png"></td>
<td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3088283/2bf094ff-0112-2e16-2a61-b3fcf269eb31.png"></td>
</tr>
</table>


**2) 釣果データに基づくクレンジング**

３σ法を使って外れ値除去をします。

釣果(匹/人・日)：平均＋３σ ＝ 3.95(匹/人・日)

釣果データの確認結果(外れ値除去前)
<table>
<tr>
<td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3088283/b813277f-1a72-d02b-7855-80bb484bcad3.png"></td>
<td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3088283/dab071fd-0b7d-983f-aff1-9956ed483794.png"></td>
</tr>
</table>


# データの考察

1) 釣果データ
    - **数値が想定よりも小さい（最大でも８匹/人・日）**
    釣果(匹/人・日) = 「アジが釣れた数/入場者数」で計算しました。入場者の中には、釣りをしない人やアジ以外を狙っている人もいるため、入場者数で割ったことにより小さい数値になったと推測します。今回はデータ分析を一通り実践することが主目的のためこのまま進めました。
    - **データが２年分しかない**
    海釣り公園のブログが直近２年分のみでした。時系列分析としてはもう少し多くの年月のデータが欲しいところですが、役700のデータは収集できたため回帰問題として取り組みました。
    - **コロナの影響が外乱となっている**
    釣果データを見ると、釣果、入場者数が少ない時期があります。これはコロナにより海釣り公園での釣りを禁止していた時期があったためです。これも外乱要因ではありますが、今回はこのまま進めることにします。
2) 気候データ
    - 気温
    平均気温、最高気温、最低気温の間には強い相関があることを確認しました。
    そのことから、学習には平均気温のみを学習データとして使用することにしました。
    ![heatmap_temperature.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3088283/0494ab30-680f-5ab9-d812-3f603ef98079.png)
    - 風速
    同様に相関関係から、風速についても平均風速のみを学習データとして使用することにしました。
3) 潮汐データ
    - 水位
    同様に相関関係から、水位についても、満潮水位のみを学習データとして使用することにしました。
4) 日付データ
    - 釣りをした月
    釣果データの確認結果から、季節によって釣果が変わることが推測できます。そこで、日付から月を取り出し、学習データとして使用することにしました。当初は、気温データがあるため月データは不要かと思っておりましたが、月データを特徴量に加えることで精度を向上することができました。


# 学習に使用したデータ

- データの内容
    前述までのデータクレンジングと考察の結果、以下のデータを学習に使用しました。
    
    - 特徴量
    ![train.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3088283/f6819598-636e-42a6-a817-a202044ac0c9.png)
    
    - 目的変数
    ![target.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3088283/70e06e0d-352d-e932-a8c9-6f0ffe233abb.png)

- データ数
   - データクレンジング後のデータ総数 : 651
   - 訓練用データ： 585　
   - 検証用データ： 66　（データ総数の役１割）

# 学習と精度検証

k-Fold Cross Validation(交差検証)により学習を行い、精度検証を実施ました。


- 目的変数(釣果)の最大値：3.9(データクレンジ後)
- 最良のRMSE：0.99 

|モデル  |訓練データに対するRMSE  |検証データに対するRMSE  |
|---|---|---|
|SVC  |0.959  |1.353  |
|Ridge  |0.663  |0.990  |
|Lasso  |0.726  |1.059  |
|Logistic Regression |0.866  |1.218  |
|ElasticNet |0.674  |1.001  |
|LightGBM |0.657  |0.993  |


# まとめ
釣果予測を通してデータ分析の流れを一通り実践することができました。思いの外、データ収集、データ前処理にかける時間が多かったというのが実感です。精度は不十分で改良点が多くあると思いますが、今後の課題として今回の釣果予測は終了します。

[反省点・今後の改善アイデア]
- より多くの釣果データを収集する（今回は２年分のデータだった）
- 学習用釣果データの信頼性を上げる　（施設スタッフによるお客さんへのヒアリングに基づいているのでデータにバラツキがある。データを使わせてもらっているのに、こんなこと言ってすみません。）
- 回帰問題でなく分類問題として取り組む。例えば、目的変数である釣果を◎(10匹以上釣れる)、○(5匹以上釣れる)、△(1匹以上釣れる)、✖️（釣れない）に分類して扱う。
- 特徴量に「曜日」を追加する。釣り人が多いほど餌が多く海に撒かれて魚が集まりやすいという傾向があるので、入場者数に影響を与える可能性がある「曜日」を特徴量に追加する。