目次
1はじめに
2解決する課題
3実行環境・使用モデル
4データ収集と前処理
5作成したコード
6結果と考察
7実用性と今後の展望
8課題と改善点の振り返り
9おわりに
1はじめに
本ブログに興味を持っていただき、ありがとうございます。
Aidemyにて「データ分析コース」を受講しました。
Aidemyの学習カリキュラムの一環で、受講修了のため、本ブログを記載・公開しております。
前提として、講座を受ける前までは、プログラミング未経験でした。
また、受講の目的は、マーケティング調査の際にデータ分析の質を向上させることです。
以下、学習成果を基に「ガン死亡者数の将来予測モデル」の構築について記載します。
2解決する課題
今回解決したい主要な課題は、
主要な課題は、必要とされるがん対応のリソース(スタッフ数、薬、対応施設数など)が満たされていないことです。
以下の記事にもたとえば「がん患者の増加が見込まれる中、いかに効率的で高水準かつ良質なケアを提供する仕組みを作っていけるか」と課題が書かれており、具体的な数値を見ることでより現実に考えることができるかと思いました。
今回、がんの死亡者数を過去のデータを基に、将来予測することで、医療機関、政府、がん拡大防止を望む人々の参考となる情報提供を行うことで、上記のリソースがどの程度必要となるか、多少なりとでも寄与できればと思い、取り組んでみることにしました。
3実行環境・使用モデル
⚫︎今回は以下の開発環境で行いました。
・Google Colaboratory
⚫︎使用したプログラミング言語
・Pythonを使用しました。
⚫︎使用したライブラリ
データ分析には、以下のライブラリを活用しました。
・google.colab: Google Driveをマウントするために使用いたしました。これによりGoogle Drive上のファイルにアクセス処理をしています。
・pandas:データ操作と分析のためのライブラリです。主に、データ読み込み、操作、分析等に使用される有名なライブラリの1つです。
・numpy:主に、数値計算を行うためのライブラリです。行列等の数学的処理に使用されます。
・matplotlib:データをグラフ・描画等に可視化するためのライブラリです。
・datetime:Pythonプログラムで日付及び時刻を操作するためのライブラリです。ライブラリには、日付や時間の作成、比較、操作、書式設定等があります。
・statsmodels.tsa.statespace.sarimax: SARIMA(Seasonal Autoregressive Integrated Moving-Average)モデルの構築や分析を行うために使用する統計処理のためのライブラリです。
特に一番、最後のSARIMAモデルは、今回使用する将来予測において大事なポイントとなるため、以下に特に自分が理解した大事なポイントを記載します。
補足 SARIMAモデルの説明
・主に、将来予測をするのに適しているモデルです。
・具体的には、以下のデータ予測に適しています
ー経済指標(毎月の失業率、消費者支出、GDP、株価、為替相場等)
ー季節性がある販売データ
ー気象データ
ー需要予測
また、そもそも、どのような理屈のモデルか以下に説明します。
・SARIMAモデルは、ARIMA(Autoregressive Integrated Moving Average)モデルに、季節性が予測に与える影響が加味されております。
そもそも、ARIMAモデルは、の3つの主要な要素で構成されています。
①自己相関(Autoregressive)
②差分(Integrated)
③移動平均(Moving Average)
ARIMAモデルの導出には以下の記事が参考になります。
SARIMAモデルは、本モデルに季節性の要素を加えたものであるということです。
また、SARIMAモデルは、以下のパラメータで特徴づけられます:
①季節性の次数(Seasonal Order):季節性のパターンの周期性を表現します。たとえば、季節性が1年周期の場合、パラメータは通常12となります。
②AR次数(Autoregressive Order):過去の観測値が未来の値に影響を与える自己相関の次数を指定します。
③差分次数(Integrated Order):データの非定常性を除去するために行う差分の次数を指定します。定常性があるデータでは、この値は通常0です。
④MA次数(Moving Average Order):過去の誤差が未来の値に与える影響の次数を指定します。
SARIMAモデルを導出されたい方には以下のブログが適しています。
4データ収集と前処理
データ収集に必要なデータは、国立研究開発法人国立がん研究センターの以下URLから収集しました。
全国がん死亡データ(1958年~2021年)
本元データの1958〜2021年のがん患者死亡者数をCSV形式に加工して分析に使用しました。
5作成したコード
実際に、作成したコードについて以下、紹介・説明していきます。
まず、グーグルドライブにCSV形式で該当データをアップロードし当該データを読み込む手法を取りました。
本手法は「マウント」と呼ばれるものです。
詳細は以下に記載されています。
実際のコードは以下です。
#Google Drive上のファイルからデータを読み込む
from google.colab import drive
drive.mount('/content/drive')
次に
前掲3「実行環境・使用モデル」の箇所で説明した各種処理に必要なモデル及びSARIMAモデル構築のために必要なライブラリを用意するコードを記載しました。
#必要なライブラリのインポート
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.statespace.sarimax import SARIMAX
from datetime import datetime
ライブラリを準備した後は、グーグルの該当データ(1958〜2021年のがん患者死亡者数のCSV)を読み込むコードを記載しました。
#データの読み込み
file_id = '/content/drive/MyDrive/csv/cancer.csv'
data = pd.read_csv(file_id,index_col=None)
データを読み込んだ後、どのようなデータになるか実際に見える化するためのコードを記載しました。
元データが横に長いものであったため、「data=data.T」で転置処理を行なっております。
#データの確認・転置
display(data.head())
data=data.T
データ可視化の結果の一部が以下です。
年数と死亡者の前に、「0」の数値があるため、実際のグラフ化の際に「行番号」がどのようになっているか、
確認するためのコードを記載しました。
#行番号の確認
data.index
そして、この後、SARIMAモデルを用いて、2022年以降の20年間分2041年までの予測を行うコードを記載しました。
# SARIMAモデルの構築
order = (1, 1, 1) # SARIMAの次数を指定(p, d, q)
seasonal_order = (1, 1, 1, 12) # 季節性の次数を指定(P, D, Q, s)
model = SARIMAX(data, order=order, seasonal_order=seasonal_order)
results = model.fit()
# 予測を行う(20年予測)
future_years = 20
forecast = results.get_forecast(steps=future_years)
最後に予測結果を実際に、グラフ化するコードを記載しました。
その際に2021年までのデータは黒色、2022年以降のデータは赤色で表現するコードを記載しました。
# 予測結果をプロットする
plt.figure(figsize=(12, 6))
plt.plot(data_index, data, color='black', label='Observed') # 過去のデータは黒色でプロット
print(data.index)
print(forecast)
plt.plot(forecast.predicted_mean.index, forecast.predicted_mean.values, color='red', label='Forecast') # 予測データは赤色でプロット
plt.title('SARIMA Forecast')
plt.xlabel('Year')
plt.ylabel('Value')
plt.legend()
しかし、今回作成したコードでは、訓練データはあるのですが、テストを行うデータがなく、予測データ精度の高さの検証が必要であるとここで気づきました。
そして、データ精度向上のために、5年分をテストデータとするコードを追記し、以下のように変更しました。「データ確認・転置」以降の箇所に追記しています。
テストデータと訓練データの意義については、以下に説明されています。
# データの確認・転置
display(data.head())
data=data.T
# 文字列からdatetime.dateオブジェクトへの変換
data_index=list(map(lambda x : datetime.strptime(x, "%Y").date(),data.index))
# 文字列からdatetime.dateオブジェクトへの変換
train_X= data[:-5]
test_X = data[-5:]
また、訓練データの推移と実際のデータの差分を検証するために、将来予測を2017年からの25年間に変更しました。
# SARIMAモデルの構築
order = (1, 1, 1) # SARIMAの次数を指定(p, d, q)
seasonal_order = (1, 1, 1, 12) # 季節性の次数を指定(P, D, Q, s)
model = SARIMAX(train_X, order=order, seasonal_order=seasonal_order)
results = model.fit()
# 予測を行う(25年予測)
future_years = 25
forecast = results.get_forecast(steps=future_years)
グラフにおいて、増加傾向にあることはわかりましたがこれでは、実際の将来予測の数値がわからなかったため、各年ごとの訓練データによる将来予測数値(赤色折れ線箇所)を出すコードを記載しました。
forecast.predicted_mean
その結果がこちらです。
以上が実際に作成したコードになります。
また、後ほどの結果と考察の際に使用するため、1990〜2021年のテストデータ用の元データ用の数値も以下に記載しておきます。
6結果と考察
SARIMAモデルの訓練データ及びテストデータによって得られた予測結果を分析すると、明らかに経過年数と共に、がんによる死亡者数が増加傾向です。
しかしながら、テストデータと訓練データとの数値に差があり、訓練データの方がはるかに上昇トレンドを示す結果になり、テストデータでは上昇率が鈍化するという結果になっております。
先ほどの1990年頃からのデータを詳細に見ていくと、2016年までの直前の伸び率が2017年以降に比して高いため、起きている現象であると考察されました。
最も、訓練データが示しているデータは、がんになる確率が高まると言われる65歳以上人口の将来予測と比較してみると、2021年が3,640万人に対して、2040年が3,928万人※1であり、108%の伸びであることに対して、ほぼ比例する分析結果が出ておりますが、テストデータとの乖離があるため課題が残りました。
※1:出典 厚生労働省の統計
7実用性と今後の展望
今回、テストデータと訓練データの将来予測の結果は異なり、データの検証結果としての妥当性は残るものの、がんによる死亡者数は増加傾向であるという点では変わらず、訓練データについては、具体的な人数まで予測が経っておりますのので、本データを基に、医療機関の数や患者に携わるスタッフ数、薬、設備などを逆算する数値として多少は、実用性があるかと思われました。
8課題と改善点の振り返り
今回将来予測モデルを実際に組み、具体的に課題であると感じたことは以下4点です。
①テストデータ数を15年分など多くしてみて分析すると良かったと思われたこと
②月別にデータがあれば、春夏秋冬における季節要因などがあるかどうか詳細がわかり、季節ごとの医療リソースの予測がよりできるようになると思われたこと
③急に、2017〜2021年でガン死亡者数が鈍化した理由をより、検討したモデルの構築をできれば良かったこと。
具体的な観点として、当該時期には、2018年のタバコ増税(1本あたり1円、1箱あたり20円の値上げ)、2019年の消費税増税等により、タバコ購入の買い控えや辞めた人が増え、肺がんが減ったという仮説が考えられ、当該要因も元データには、がんの部位別死亡者数のデータも存在するため、分析してみると良かったことが挙げられます。
④最後に、当初、ガンと因果関係のありそうな添加物に関する数値も含めた、2つ以上の元データを基にした分析も検討しておりましたが、分析に沿う時系列のデータがなかったこと
があります。
本課題改善に向けたアクションとしては、自身で学習をより進めて、知識をつけ、
データ整形のスキルや使用するライブラリ・モデルを多く知り、今後、改善・チャレンジしたいです。
9おわりに
今回、本モデルを作成するにあたり、大変苦労しましたが、無事に将来データがグラフ・数値共に可視化された瞬間は率直に自己成長を実感できました。
多大にサポートいただきましたAidemyの皆様、参考にさせていただきましたブログ執筆者様については御礼申し上げます。
その他参考
本ブログを書く際の基本的な作法などをまとめていただいているリンクを今後の初心者の方向けの参考までに記載しておきます。見出しの付け方やプログラミング部分のみを見やすくする方法が記載されています。