AIサービスの開発現場-PoCに求められるものは?
現在、産業や社会へのAI技術の利活用に注目が集まり、多くの企業がAIを用いた新サービスの開発に取り組んでいます。
新しいサービスを開発する際には「目的が実現できそうか」を検証するPoC(概念実証)が行われることが一般的です。PoCにおいて検証対象とする内容は目的やスコープによってさまざまですが、システム化を前提とした開発現場でのPoCでは「サービス的にどこまで実現できるか(サービス観点)」「性能的にどこまで実現できるか(技術観点)」を、プロトタイプを作成して検証・評価することになります。
PoCにおけるAIエンジニアの役割
一般的にPoCが計画・開始される時点でその検証内容は要件として定義されていますが、具体的なレベルで定義されているのは試行のライフサイクルにおける1回目までであり、2回目以降の検証内容は試行結果を見て逐次的に決めていくことが多いです。これは、1回目の施行で実現したいモノの形が見えてくることで、PoCで確認しておきたい次の具体的な検証内容が段階的に明らかになっていくためです。
ライフサイクル的に検証内容(目標)を設定する際、そのサービス実現の裏側となる実装技術や使用データの構造・特長まで把握しているAIエンジニアには、その技術的視点から提案・企画することが求められます。
前回記事の施行では、時系列データを月次で予測するモデルを作り、予測モデルの性能(予測精度)に課題があることが見えました。今回は、このモデルの予測精度を向上することに取り組むことを事例として紹介します。
時系列データの予測モデルを作成する
本記事で使用したソースコード、データは下のGitHubで公開しています。記事中では説明を省略した部分のソースコードと使用したデータがあり、実際にマシン上で動かしてみることができます。
- 使用したプログラム言語はPython3、ディープラーニング部分にはPythonパッケージのtensorflow/Kerasを使用
- 各データファイル(CSV)は、政府統計の総合窓口(e-Stat)より「住民基本台帳人口移動報告」「住民基本台帳に基づく人口、人口動態及び世帯数調査」「賃金構造基本統計調査」「工業統計調査」「商用統計調査」を加工して作成
(1)時刻ラグを利用する
前回記事では、下図1のようにデータを使用する予測モデルを作成しました。
目的変数をmig_in(転入者数)として、前月のすべてのデータを説明変数として予測するモデルです。ここで「ラグ期」とは該当とする月から何カ月前かを表す言葉で、例えば2013年3月に対して2013年2月はラグ期1となります。
モデルの表現力(目的変数を表現する力)を増して予測精度を向上する手法はさまざまですが、最も単純な手法として「説明変数の数を増やす」という方法があります。
ここでは目的変数に関係性がありそうな別のデータを持ってきて説明変数に追加したいところですが、新たにデータを用意するのはハードルが高い場合があります。幸いに今回題材としている時系列データの予測では、簡単に説明変数を増やす方法があります。その方法が下図2です。
ラグ期1の全データに、ラグ期2の全データも説明変数に加えて目的変数を予測します。これは、例えば2013年3月のmig_in(転入者数)を表現するためには、2013年2月のデータに加えて2013年1月のデータも必要、と仮説を立てていることになります。
ラグ期追加の実装
目的変数に対して説明変数を設計したラグ期に合わせてずらす処理には、pandas.DataFrame()に実装されたshift()関数を使用しています。下のコードでは、全データ(df_all)を都道府県(prefecture)ごとに、1行ずらしたデータ(df_all_lag1)と2行ずらしたデータ(df_all_lag2)を作成し、目的変数部分と作成した2つのデータの説明変数部分を結合して1つのデータ(df_all_lag)にまとめています。
### データの前処理(3):ラグデータ化 df_list1 = [] df_list2 = [] for prefecture in df_all['prefecture'].unique(): df_tmp = df_all[df_all['prefecture'] == prefecture] df_tmp1 = df_tmp.shift(1) df_list1.append(df_tmp1) df_tmp2 = df_tmp.shift(2) df_list2.append(df_tmp2) df_all_lag1 = pd.concat(df_list1) df_all_lag1.rename(columns=lambda x: x + '_lag1', inplace=True) df_all_lag = pd.concat([df_all.iloc[:, 0:3], df_all_lag1.iloc[:,2:24]], axis=1) df_all_lag2 = pd.concat(df_list2) df_all_lag2.rename(columns=lambda x: x + '_lag2', inplace=True) df_all_lag = pd.concat([df_all_lag, df_all_lag2.iloc[:,2:24]], axis=1) df_all_lag.dropna(inplace=True) df_all_lag.reset_index(drop=True, inplace=True)
ラグ期追加の結果確認
ディープラーニングを実行して作成したモデルにより出力される予測結果を見てみます。まずは前回記事での結果の振り返りです。以下は前回モデル(ラグ期1のみ使用)での鹿児島県の例です。実際の転入者数(mig_in)とモデルが予測した転入者数(mig_in_pred)を出力しています。
実績値のピーク値(最大値:6488)に予測値のピーク値(最大値:5263)が追従できていない、また、実績値のピークが発生する時期(毎年4月)に対して予測値のピークが発生する時期(毎年5月)が遅れている、という問題がありました。
では、今回のモデルではどうなったでしょう。以下は今回モデル(ラグ期2を追加)での鹿児島県の例です。
実績値のピーク値に予測値のピーク値(最大値:5102)が追従できていない問題はあまり改善が見られません。一方、実績値のピークが発生する時期に対して予測値のピークが発生する時期(毎年4月)は同期しており、改善が見られました。
これは、月次データにおける年間での周期的な特徴(鹿児島では4月に転入者数が多いという特徴)は、時間軸で1点のデータより2点のデータを用いた方が特徴を捉えやすい、と考えることができます。