見出し画像

プログラミング超初心者が機械学習を使ってみた

まずはじめに

初めまして。
飲食店店長をやっていましたが、少子高齢化で70歳まで働くことを想定すると、狭い視野でしか世の中を見ていないこのままでは人生詰むのではないかということで転職を決意。
未経験転職に生かすため一年間働きながらMOSやら簿記やらAFPの勉強をし、その後退職して転職活動中の36歳のおじさんです。
MOSの勉強からVBAの存在を知り、そこからプログラミングに興味をもち、とりあえずはVBAエキスパートスタンダードをとってみたもののVBAはプログラマーに嫌われるということを知り、なぜなのか知るためにアイデミーで3か月pythonを学んでみたという次第です。
最後に成果物が必要ということで何をしようかと考えたところ、自身が転職を決意する理由となった少子高齢化について、機械学習の時系列分析をしてみようということにしました。

実行環境

実行環境
PCWindows8.1
環境:geogle colaboratory 
Python ver : 3.7.13

手順①機械学習をするためのデータ集めと資料作成

まずはデータ集めということで人口分布のデータを探し、今回はe-statを使うことにしました。
政府統計の総合窓口 (e-stat.go.jp)

使った元データー

上のようなデータが年ごとにありましたので今回は1999~2020年のデータをまずは横並びに揃えていきました。
しかし、途中でデータ単位変わったり、少子高齢化のためか高齢カテゴリがより細分化されてたりもしていて、このままのデータでは使えないということで考えた結果、すべてのデータを0~19歳(未成年)・20~70歳未満(生産年齢人口)・70歳以上(高齢者)の三つのカテゴリに分けて集計。
その後、70歳以上(高齢者)÷20~70歳未満(生産年齢人口)の結果を表に纏めました。

上スクショの枠内に纏める

しかし、横並びではDataFrameに使えないということで行/列の入れ替えをして縦並びにして資料完成としました。

縦並びにして準備完了

手順②どのモデルを使うか考える

さて問題はどのモデルを使うかです。時系列分析だとARIMAかSARIMAの二択となってきますが、まずは纏めたデータをグラフにした結果をみてみましょう。

(70歳以上人口÷20~70歳未満人口)の変化

んーーーめっちゃ伸びてるうぅぅぅというのはわかりますが、季節による変化はあまりないと判断しました。まぁ人間は寒くても暑くても営みは止めないので。ということで季節的な周期パターンは不要なのでSARIMAではなくARIMAを使うことにしました。
そこでARIMAについて改めて調べてみると、本来ARIMAは人の知見を最大限活用し求める必要がある。しかし、まだ数学的理解は甘々なので知見といわれましても……(激汗)。
しかし、ここがすごいよpython。ARIMAの予測精度を最大限に高める次数を機械学習のように自動的に決めてしまう素敵なパッケージがあるんですよ!!そりゃ使うしかない!!!その名もpmdarima!
今回はpmdarimaパッケージのauto.arima関数を使うことにしました。

手順③コードを書き始める

%matplotlib inline
from google.colab import drive
drive.mount("/content/drive") #geogleドライブのファイルに連携 
!pip install pmdarima #pmdarimaをインストール 

コードを書き始める。
geoglecolabにコードを書いていきますので、geogleドライブからデータを引っ張ってくるためにマウントするコード。
そしてpmdarimaは常備されていないようなのでインストールするためのコードを書いておかないと後でimportができません。

import warnings
import itertools
import statsmodels.api as sm
import numpy as np
import pandas as pd
import pmdarima as pm
from pmdarima import utils
from pmdarima import arima
from pmdarima import model_selection
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_percentage_error
from matplotlib import pyplot as plt
from statsmodels.tsa.statespace.sarimax import SARIMAX

沢山importしてますが、もしかしたら使っていないものもあるかもしれません。とりあえずエラーでない重視です。前でしっかりpmdarimaをインストールしていないとここでエラーがでてしまいます。

df=pd.read_excel(r"/content/drive/MyDrive/少子高齢化資料.xlsx",header=None, names=["time", "ratio"])
df.to_csv(r"C:\\Users\\yusuke\\Documents\\少子高齢化資料.csv",index=None,header=True)
df=df.set_index('time') #1列目をindexに 

print(df)

次にgeogleドライブからデータをもってきてDataFrameにします。
そして、一列目をindexにします。
出力した結果です。

               ratio
time                
1999-10-01  0.166872
1999-11-01  0.167381
1999-12-01  0.167930
2000-01-01  0.168281
2000-02-01  0.169319
...              ...
2020-06-01  0.376056
2020-07-01  0.376608
2020-08-01  0.377398
2020-09-01  0.378174
2020-10-01  0.378817

[253 rows x 1 columns]

さて次のコードからデータを分析していきます。

# グラフのスタイルとサイズ
plt.style.use('ggplot')
plt.rcParams['figure.figsize'] = [12, 9]

df.plot()
plt.title('ratio')                            #グラフタイトル
plt.ylabel('retirement/worker') #タテ軸のラベル
plt.xlabel('Year')                                #ヨコ軸のラベル
plt.show()

# 成分分解(tread・seasonal・random)
data = df.ratio.values
utils.decomposed_plot(arima.decompose(data,'additive',m=12),
                      figure_kwargs = {'figsize': (12, 12)} )   
# 階差の次数の検討
print('d =', arima.ndiffs(df))      #d2
print('D =',arima.nsdiffs(df,m=12)) #D0                   
                        
# コレログラム(自己相関と偏自己相関)
data = df.diff(1).diff(12).dropna()
utils.plot_acf(data, alpha=.05, lags=24)
utils.plot_pacf(data, alpha=.05, lags=24)

階差系列とは、先月との差を計算した時系列データです。季節階差系列とは、1周期前(昨年)との差を計算した時系列データです。このような処理は何回でも可能です。その処理を何回行うかを階差の次数の検討で調べます。今回はd=2,D=0つまり階差系列は二回行い、季節階差系列は一回も行わないということになりました。
コレログラムとはあるデータから前期間のデータとの相関関係を表しているものであり、1年周期で変化しているものだと12が伸びます。今回も下のように12が伸びました。


コレログラム

さて本番です。auto.arima関数を使いモデルを作ります。mには周期の12。d,Dには先ほど導き出したd=2,D=0を入れます。

# モデル構築(Auto ARIMA)

arima_model = pm.auto_arima(df, 
                            seasonal=True,
                            m=12,
                            d=2,
                            D=0,
                            n_jobs=-1,
                            maxiter=10)

学習したモデルを使い予測をするコードを書いてそれをグラフ化します。
n_periodsのところに予測する期間を入力します。今回は160か月としました。

# 予測
# predに予測期間での予測値を代入してください
train_pred = arima_model.predict(n_periods=160)




# グラフ化
fig, ax = plt.subplots()
ax.plot(df[24:].index, df[24:].values, label="actual(df dataset)")
ax.plot(train_pred.index, train_pred.values, label="actual(train_pred dataset)")


ax.legend()

そしてその結果のグラフが下です。縦軸が70歳以上(高齢者)÷20~70歳未満(生産年齢人口)の値。横軸が年数となっているグラフとなります。

赤線が元データ。青線が予測データ。

更にめっちゃのびてるうぅぅぅぅぅぅ。なんと2034年には70歳以上の人口が20歳~70歳未満の人口合計の半分ほどになるとのこと。
これは70歳まで働いても日本回るのだろうか…。とりあえず歳とっても現役で働ける知識と経験をつけることに邁進しようと改めて決意する理由になる結果となりました。

最後にpythonを学んでみた感想

pythonを学んでみて一番感じたことはなんでプログラマーの方々がVBAを嫌うのかよくわかりました。
なぜかってゲームで例えて表現すると、VBAはいわばプレイステーション1のFF7のボンッキュボンのポリゴンのクラウド。一生変わらない。
それに対してpythonはプレイステーション5のFF7リメイクででてくる姿も声もかっこいい超イケメンクラウド。しかもいまだ世界のどこかの天才がパッケージを作り、改良し進化し続ける。
今回使ったauto.arimaも私のような超初心者でも使えるようにと改良されたもの。pythonはなるべく簡単に誰でも読みやすく使いやすいを目指しているというのは本当なんだなと実感致しました。
これからもぜひ少しずつでも人生に生かしていきたいと思います。

今回のコードを書くにあたり参考にしたサイト。
Pythonで時系列ARIMAモデルを自動でサクッと作ろう(AutoARIMA) – セールスアナリティクス (salesanalytics.co.jp)

この記事が気に入ったらサポートをしてみませんか?