【プログラミング初心者】海水温からサンマ漁獲量を予測するモデルを作成

<font color="Red">このブログはAidemy Premiumのカリキュラムの一環で、受講修了条件を満たすために公開しています</font>

# 目次
[**1.はじめに**](**#1-はじめに**)
[**2.分析テーマと問題意識**](**#2.-分析テーマと問題意識**)
[**3.分析の流れ**](#3-分析の流れ)
[3-1.データの入手と整形](###3-1-データの入手と整形)
[3-2.学習用データと検証データを設定](###3-2-学習用データと検証データを設定)
[**4.分析結果・考察**](#4-分析結果・考察)
[**5.おわりに**](#5-おわりに)

# **1.はじめに**
プログラミング初心者が、半年間学んだ成果としてPythonによる機械学習を用いた分析に挑戦した
### 開発環境
Python
Windows
Chrome
Google Colaboratory

# **2.分析テーマと問題意識**
　2023年、日本の夏の平均気温は1898年の統計開始以来、最も高くなった。地球温暖化は世界規模で影響をもたらし、国連のアントニオ・グテーレス事務総長は「地球温暖化の時代は終わり、**地球沸騰**の時代が来た」と警鐘を鳴らしている。そうした中、機械学習について学んだことを実践する際に、<font color="Red">**温暖化**</font>がもたらす何らかの影響を分析できればと考えた。

 　地球温暖化が影響する分野のうち主要なものとして、気候が生産や収穫に大きく関連する一次産業が挙げられる。今回着目したのは、環境省がホームページで公表している、<font color="Red">**「温暖化による海水温上昇が、サンマの漁獲高減少につながる一因となっている」**</font>という論考である。
  当該ホームページリンク：[**【秋冬の味覚に危機？地球温暖化の影響と“地産地消”という選択】**](https://ondankataisaku.env.go.jp/coolchoice/weather/article03.html)

これによると、
・15～20℃の水温を好み、主に太平洋に生息するサンマは、秋になると千島列島から日本列島の東岸にごく近い位置を移動していた。
・ところが、2010年以降、サンマの好漁場である常磐沖に暖かい水の塊が発生し、釧路沖で停滞。さらに日本列島近海の水温上昇などの影響から、低温を好むサンマの親魚がより沖合を移動するようになった。
・2019年に暖水塊はなくなったが、沿岸には高い水温を好むマイワシやマサバが増えてサンマと餌を奪い合ったなどの理由で。サンマの来遊は少ないままとなっている。
<font color="LightSeaGreen">**【説明図＝環境省のホームページを基に作成】**</font>
![サンマ回遊ルート.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662910/bd52398c-c486-22e0-c80a-c2e6db0ca601.jpeg)

そこで、
・<font color="Red">**気象庁の公開している海水温データ**</font>を**説明変数**に、
・<font color="Blue">**農林水産省の公開しているサンマの漁獲量データ**</font>を**目的変数**として
予測する機械学習モデルを作成する。

# **3.分析の流れ**
### **3-1.データの入手と整形**
#### <font color="Red">**【海水温データ】**</font>
　説明変数となる海水温データは、気象庁のホームページから入手した。
 当該ホームページリンク：[**【海面水温の長期変化傾向(日本近海)のデータ】**](https://www.data.jma.go.jp/kaiyou/data/shindan/a_1/japan_warm/japan_warm_data.html)
　海水温データは海域ごとに分かれている。上の図と対照すると、サンマの回遊に影響がある水域は北から<font color="Red">**「釧路沖」「三陸沖」「関東の東」**</font>の３水域と考えられる。
　また、各海域には、1900年以降の海水温が「年」「冬(1-3月)」「	春(4-6月)」「	夏(7-9月)」	「秋(10-12月)」ごとに分かれて公開されているが、サンマの回遊が毎秋であることから、秋のデータを抽出する。データはtxt形式のためcsv形式に変換する。

**〈釧路沖の秋の海水温データをグラフ化すると、海水温が上下を繰り返しながら緩やかに上昇していることが分かる。なお1962年までの数値には欠損が含まれる。三陸沖、関東の東の海域でも同様の傾向が見られる〉**
![釧路沖グラフ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662910/4abc8555-4aa9-71b4-2044-bf2d78d4b5be.jpeg)


***必要なライブラリをインポート***
```
from google.colab import drive
drive.mount('/content/drive')
import pandas as pd
```
**csvデータを確認し、1900年のデータが始まる行から読み込み**
```
kushiro_df = pd.read_csv("/content/drive/MyDrive/成果物/areaJ_SST.csv",header=5)
sanriku_df = pd.read_csv("/content/drive/MyDrive/成果物/areaK_SST.csv",header=5)
kantoeast_df = pd.read_csv("/content/drive/MyDrive/成果物/areaL_SST.csv",header=5)
```
**各データにカラムを付与**
```
kushiro_df.columns = ["Year", "Annual", "Winter", "Spring", "Summer", "kushiro_Autumn"]
sanriku_df.columns = ["Year", "Annual", "Winter", "Spring", "Summer", "sanirku_Autumn"]
kantoeast_df.columns = ["Year", "Annual", "Winter", "Spring", "Summer", "kantoeast_Autumn"]
```
**いったん確認のため表示**
```
print(kushiro_df)
print(sanriku_df)
print(kantoeast_df)

Mounted at /content/drive
     Year  Annual  Winter  Spring  Summer kushiro_Autumn
0    1900  NoData  NoData  NoData  NoData         NoData
1    1901  NoData  NoData  NoData  NoData         NoData
2    1902  NoData  NoData  NoData  NoData         NoData
3    1903  NoData  NoData  NoData  NoData         NoData
4    1904  NoData  NoData  NoData  NoData         NoData
..    ...     ...     ...     ...     ...            ...
118  2018    0.96    0.77    1.67    0.05           1.36
119  2019    0.71   -0.44    0.70    1.45           1.13
120  2020    1.52    2.04    2.06    1.29           0.70
121  2021    0.94    0.33    1.43    0.30           1.72
122  2022    1.82   -0.55    1.89    3.55           2.38

[123 rows x 6 columns]
     Year  Annual  Winter  Spring  Summer sanirku_Autumn
0    1900  NoData  NoData  NoData  NoData         NoData
1    1901  NoData  NoData  NoData  NoData         NoData
2    1902  NoData  NoData  NoData  NoData         NoData
3    1903  NoData  NoData  NoData  NoData         NoData
4    1904  NoData  NoData  NoData  NoData         NoData
..    ...     ...     ...     ...     ...            ...
118  2018    0.93    1.23    1.22    0.17           1.11
119  2019    0.46    0.69    0.50    0.62           0.04
120  2020    0.71    2.07    1.21    0.19          -0.63
121  2021    1.03    0.31    2.60    0.56           0.63
122  2022    0.88   -0.83    0.53    1.72           2.11

[123 rows x 6 columns]
     Year  Annual  Winter  Spring  Summer kantoeast_Autumn
0    1900  NoData  NoData  NoData  NoData           NoData
1    1901  NoData  NoData  NoData  NoData            -2.60
2    1902  NoData  NoData  NoData   -2.59           NoData
3    1903  NoData  NoData   -3.46  NoData           NoData
4    1904  NoData  NoData  NoData  NoData           NoData
..    ...     ...     ...     ...     ...              ...
118  2018    0.46   -0.71    1.08    0.99             0.47
119  2019    1.29    1.94    1.69    0.66             0.87
120  2020    1.17    1.59    1.18    1.07             0.85
121  2021    1.82    3.18    2.01    1.23             0.85
122  2022    1.04   -0.02    0.89    1.07             2.23

[123 rows x 6 columns]
```

**「年」「冬」「春」「夏」のカラムは分析に使わないので削除し、サンマ漁獲量データが1956年からなので、期間を会わせて1955年以前のデータを削除**
```
kushiro_df = kushiro_df.drop(["Winter","Spring","Summer","Annual"],axis=1)
sanriku_df = sanriku_df.drop(["Winter","Spring","Summer","Annual"],axis=1)
kantoeast_df = kantoeast_df.drop(["Winter","Spring","Summer","Annual"],axis=1)
kushiro_df = kushiro_df.drop(range(0,56))
sanriku_df = sanriku_df.drop(range(0,56))
kantoeast_df = kantoeast_df.drop(range(0,56))
```
**釧路沖のデータに欠損が残っているため、後のデータで補充**
```
kushiro_df = kushiro_df.replace('NoData', np.nan)
kushiro_df = kushiro_df.bfill()
```
**年のカラム'Year'をキーに海水温データを結合**
```
merged_df = pd.merge(kushiro_df,sanriku_df, on = "Year")
all_df = pd.merge(merged_df,kantoeast_df, on = "Year")
```
**サンマ漁獲量データは2021年までなので、2022年の行を削除**
```
all_df = all_df.drop(66)
```
**結合後のデータはこのようになる**
```
 Year kushiro_Autumn sanirku_Autumn kantoeast_Autumn
0   1956          -0.97           0.85             0.97
1   1957          -0.97          -0.24             1.13
2   1958           0.03          -1.09            -0.25
3   1959           0.03          -0.99             0.42
4   1960           0.07           0.17             0.75
..   ...            ...            ...              ...
61  2017          -0.02           0.12            -0.92
62  2018           1.36           1.11             0.47
63  2019           1.13           0.04             0.87
64  2020           0.70          -0.63             0.85
65  2021           1.72           0.63             0.85

[66 rows x 4 columns]
```
#### <font color="Blue">**【サンマ漁獲量データ】**</font>
　目的変数となるサンマ漁獲量データは、政府統計の総合窓口e-Statから入手した。
　統計開始から最新までのサンマの漁獲量のデータは、1956~2015年の **「長期暦年」** と、2015~2021年の **「確報 令和３年漁業・養殖業生産統計」** に分かれているため、両データを統合する。
 ホームページリンク：[**【海面漁業生産統計調査 / 長期累年】**](https://www.e-stat.go.jp/stat-search/files?page=1&layout=datalist&toukei=00500216&tstat=000001015174&cycle=0&tclass1=000001034726&stat_infid=000031605790&tclass2val=0)

 ホームページリンク：[**【海面漁業生産統計調査 / 確報 令和３年漁業・養殖業生産統計】**](https://www.e-stat.go.jp/stat-search/files?page=1&layout=datalist&toukei=00500216&tstat=000001015174&cycle=7&tclass1=000001015175&tclass2=000001201760&stat_infid=000040024142&tclass3val=0)

**〈両データを統合してデータをグラフ化すると、急激に減少しているのが見て取れる〉**
![サンマ漁獲量グラフ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662910/298d6d73-60a5-de27-679e-90a21f299068.jpeg)

**「長期暦年」のサンマ漁獲量データをドライブから、必要な行から読み込み**
```
df1 = pd.read_excel("/content/drive/MyDrive/成果物/c001c-003-000-000-001.xls",skiprows = 3)
```
**サンマ以外の魚種のカラム、注記の行は不要なので削除**
```
df2 = df1.drop(df1.columns[range(1, 33)], axis=1)
df3 = df2.drop(df2.columns[range(2, 78)], axis=1)
rangedf1 = df3.drop(range(0,4))
rangedf2 = rangedf1.drop(range(64,93))
```
**カラムの付与**

**処理後のデータはこのようになる**
```
           年次     サンマ
4  昭.31(1956)  327813
5  昭.32(1957)  421530
6  昭.33(1958)  575087
7  昭.34(1959)  522567
8  昭.35(1960)  287071
```
**元号と西暦が交ぜ書きになっているため、1956~2015年までのリストを作成・挿入し、元の年次カラムを削除**
```
rangedf2.columns = ["年次", "サンマ"]
rangedf2.insert(loc = 0, column= 'Year', value= list(range(1956,2016,1)))
ran```gedf3 = rangedf2.drop("年次",axis=1)
```
**「確報 令和３年漁業・養殖業生産統計」のデータをドライブから、必要な行から読み込み**
```
sanma_df1 = pd.read_excel("/content/drive/MyDrive/成果物/c001-r3-004 (2).xlsx",skiprows = 7)
```
**サンマ以外の魚種のカラムは不要なので削除、2015年までは重複しているため必要な行を抽出**
```
sanma_df2 = sanma_df1.drop(sanma_df1.columns[range(2, 34)], axis=1)
sanma_df3 = sanma_df2.drop(sanma_df2.columns[range(3, 57)], axis=1)
sanma_range_df3 = sanma_df3[6:12]
```
**サンマ漁獲量データの結合のために表記を統一
年を西暦に置換
元号のカラムを削除**
```
sanma_range_df3.columns = ["元号","Year", "サンマ"]
sanma_range_df3.replace({'28': 2016, '29': 2017,'30': 2018,'元': 2019,'２': 2020,'３': 2021}, inplace=True)
sanma_range_df3 = sanma_range_df3.drop("元号",axis=1)
```

**年のカラム'Year'をキーに漁獲量データを連結**
```
all_sanma_df = pd.concat([rangedf3, sanma_range_df3], axis=0) 
```
**結合後のデータはこのようになる**
```
    Year       サンマ
4   1956    327813
5   1957    421530
6   1958    575087
7   1959    522567
8   1960    287071
..   ...       ...
7   2017   83803.0
8   2018  128929.0
9   2019   45778.0
10  2020   29675.0
11  2021   19513.0
```
### **3-2.学習用データと検証データを設定**
**「サンマ」を目標値に、３水域の海水温の値を入力値とする**
**入力値をXに、目標値をyに代入し、scikit-learnのtrain_test_splitメソッドを使い学習用データと検証データ（全体の30%を指定）に分割**
```
from sklearn.model_selection import train_test_split
y = all_sanma_df["サンマ"].values
X = all_df.drop(["Year"], axis=1)
train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.3, random_state=0)
```
### **3-3.モデルの学習**
**線形単回帰、ラッソ回帰、リッジ回帰の3種類の手法で分析**
```
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso

model = LinearRegression()
model.fit(train_X, train_y)
print(model.score(test_X, test_y))

model = Ridge()
model.fit(train_X, train_y)
print(model.score(test_X, test_y))

model = Lasso()
model.fit(train_X, train_y)
print(model.score(test_X, test_y))
```
# **4.分析結果・考察**
**各モデルの精度は以下のようになった**
```
線形単回帰　0.004126051915495088
リッジ回帰　0.006096521170063318
ラッソ回帰　0.004133026972000353
```
残念ながら、極めて精度の低い結果となった。このことについて、データに内在する要因と外的要因から考察を試みた。
### **内在的要因と考えられるもの**
・説明変数とした海水温の上昇は4℃程度であったのに対し、目的変数としたサンマ漁獲量の減少は約60万トンから2万トンの減少であり、差が大きすぎた
・日本近海の特定海域のみの温度上昇を説明変数としたことが、実態に即していない
・分析対象としたデータ範囲は1956~2921年の66行と十分な量ではなかった

### **外的要因と考えられるもの**
・目的変数としたサンマ漁獲量は、日本籍の漁船による漁獲量データである。昨今、近隣諸国と漁業資源を巡って競合する中で、日本の漁獲高が減少しているという指摘もある。東洋経済オンラインで1月13日に公開された記事はこの点について詳述しており、海水温の上昇が実態としてどの程度、漁獲高減少の要因となっているのか、さらなるデータ分析が必要であると思われる。

東洋経済オンライン1月13日記事：[**魚が獲れないのを海水温のせいにする人の盲点
｢サンマが豊漁に戻った｣と思う人が知らない真実**](https://toyokeizai.net/articles/-/726914)

# **5.おわりに**
今回の分析で、最も手こずったのは年次の部分である。漁獲量の長期暦年データでは「元号の頭一文字.＋元号年＋(西暦)」となっており、令和３年漁業・養殖業生産統計では「元号」＋「半角または全角表記の元号年」となっていた。セルの結合も多く、機械学習などで分析されることを前提としていないデータという印象を受けた。昨今、官公庁のオープンデータが多く利用できるようになっているが、こうした課題があることを改めて感じると共に、いっそうの技術向上に取り組みたいと思う。