UserEngagement_logoUserEngagement_logoUserEngagement_logoUserEngagement_logo
  • 記事を探す
    • ロール別ガイド
      • 管理者向け
      • マーケター向け
      • エンジニア向け
    • 用途から探す
      • 業務効率化・自動化
      • 新規顧客獲得
      • 既存顧客LTV向上
      • 企業DXの推進
    • 機能から探す
      • 顧客データ活用・施策連携
      • セキュリティ
      • データ加工、処理
      • データの可視化
      • 全機能をみる
    • 活用事例を探す
    • 全記事から探す
  • LINK
    • リリースノート
    • プロダクトドキュメント
    • Status Page(Incident情報)
    • Workflowサンプル集(英語)-TreasureBox
  • Academy
ログイン
✕

ParameterGridを使ったパラメータチューニング

  • Home
  • 表示用 Custom Scripts(ガイドページ表示用)
  • ParameterGridを使ったパラメータチューニング
Home Article howto ParameterGridを使ったパラメータチューニング
2021年10月1日
Categories
  • Custom Scripts(ガイドページ表示用)
  • howto
  • データの加工(ガイドページ表示用)
Tags
  • Custom Scripts
  • 機械学習

前回の時系列予測に続き、パフォーマンスの良いモデルのパラメータを探索する方法について紹介します。

目次
  1. パラメータチューニング
  2. 結果をTreasure Data CDPに戻すための、workflow
  3. 結果をTreasure Data CDPに戻すための、custom script
続きは会員登録およびログイン後にご覧いただけます。以下からログインしてください。

会員登録・ログイン

パラメータチューニング

大体のモデルは特に指定しない場合のパラメータはデフォルト値が設定され、良い結果になったりする場合がありますが、それよりパフォーマンスを上げたい場合はパラメータを直接変更しなければなりません。パラメータはモデルによって様々な種類が存在します。例え、3つのパラメータを10パターンずつ試し(10 x 10 x 10 : 1000パターン) 評価指標の確認・比較を繰り返すと、精神も体も疲れてしまいます。そのため、ParameterGridを使ってチューニングを行うことで、プロセスがシンプルになりパラメータ探索の効率を上げることができます。

さて、前回のProphetから調整しやすいパラメータとしてchangepoint_prior_scale(トレンドの柔軟性:0~1.0)、changepoint_range(潜在的な変化点を観測するための幅:0~1.0)がありますが、そのパラメータをParameterGridを使ったチューニングついて紹介します。

ParameterGrid()はdict型のparameterの組み合わせを設定しておくと、その一連の組み合わせが順番にマッピングされます。
例えば、5 x 5種類の組み合わせを以下のようにdict型で設定すると、

params_grid = {‘A’ : [1,2,3,4,5], ‘B’ : [0.1,0.2,0.3,0.4,0.5]}
a = ParameterGrid(params_grid)

これでaには、

A = 1, B = 0.1
A = 1, B = 0.2
…
A = 5, B = 0.5

上記のようなそれぞれの組み合わせがマッピングされます。それから、

for p in a:
  ​​model = Prophet(**p)

forでそれぞれのパターンのパラメータでモデルを作ることができます。それでは、前回のモデルを使ってチューニングができそうか試してみましょう。前回のモデルの平均絶対誤差(MAPE)は2.024%でした。以下のように12 x 7のパターンでパラメータを評価してみようと思います。

params_grid = {'growth':['linear'], 'changepoint_prior_scale':[0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6], 
               'changepoint_range': [0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9], 'seasonality_mode': ['multiplicative']}

探索を行った結果、{‘changepoint_prior_scale’: 0.6, ‘changepoint_range’: 0.9, ‘growth’: ‘linear’, ‘seasonality_mode’: ‘multiplicative’}のパラメータがbestだったため、このパラメータで結果はどうなってるか確認してみましょう。

チューニングした前後の精度

前

前

後

後



チューニングで以前より全体の平均絶対誤差が2.024%から1.976%に改善となりましたが、あくまで現時点でのテストではということは意識しておきましょう!少ない改善の場合は今後様子をみていくか、もっと多くのテストをして比較・評価してみることをおすすめします。以下はWorkflowでの実装及び、探索結果をexportするコードとなります。

結果をTreasure Data CDPに戻すための、workflow

timezone: Asia/Tokyo

# main process
+train_predict:
    docker:
        image: "digdag/digdag-python:3.9"
    _env:
        TD_API_KEY: TD apikey入力
        ENDPOINT: TD環境に合わせてhttps://api.treasuredata.co.jp or https://api.treasuredata.comを入力
        DB: DB名入力
    py>: scripts.test_py.main

結果をTreasure Data CDPに戻すための、custom script

import pandas as pd
from pytd import pandas_td as td
from fbprophet import Prophet
from sklearn import metrics
from sklearn.model_selection import ParameterGrid

# pytdの必要な情報をWorkflow側の変数からcall
con = td.Client(apikey=os.environ.get('TD_API_KEY'), endpoint=os.environ.get('ENDPOINT'))
presto = td.create_engine('presto:{}'.format(os.environ.get('DB')), con=con)
database = os.environ.get('DB')

def main():
    # MAPE測定
    def mean_absolute_percentage_error(Y_test, Y_pred): 
        Y_test, Y_pred = np.array(Y_test), np.array(Y_pred)
        return np.mean(np.abs((Y_test - Y_pred) / Y_test)) * 100
    # 対象の時系列データをload
    load_td = td.read_td_query('''
        SELECT * FROM sample_dataset
        ''', engine=presto)
    # index設定
    sample_df = load_td.set_index('date')
    # IndexをDatetime format指定 & sort
    sample_df.index = pd.DatetimeIndex(sample_df.index)
    sample_df.sort_index(inplace=True)
    
    # モデルの作成

    # 全体の旅客数を選択しtrain setの作成
    base_forecast = sample_df['2000-01':'2017-12'].iloc[:,0].reset_index()
    base_forecast.columns = ['ds','y']

    # testするためのstart_date(month)
    t_dt = '2018-01'

    # parameter探索対象
    params_grid = {'growth':['linear'], 'changepoint_prior_scale':[0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6], 
                   'changepoint_range': [0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9], 'seasonality_mode': ['multiplicative']}
    # ParameterGridでマッピング
    grid = ParameterGrid(params_grid)

    # マッピングされたパターンでモデルの評価
    #結果格納用dataframe
    result_all = pd.DataFrame()
    for p in grid:
        model = Prophet(**p)
        model.fit(base_forecast)
        future = pd.DataFrame(df['2018-01':'2018-12'].index)
        future.columns = ['ds']
        forecast = model.predict(future)

        # 中間結合用dataframe
        result_t1 = pd.DataFrame()
        result_t2 = pd.DataFrame()
        result_t3 = pd.DataFrame()
        print('test', p)
        for i in range(0,12):
            from_dt =  (pd.to_datetime(t_dt) + relativedelta(months=1*i)).strftime('%Y-%m')
            print('評価年月:', from_dt)
            print('Mean absolute percentage error:', mean_absolute_percentage_error(df.loc[from_dt:from_dt].iloc[:,0], forecast.set_index('ds')[from_dt:from_dt].yhat))
            result_t1 = pd.DataFrame([mean_absolute_percentage_error(df.loc[from_dt:from_dt].iloc[:,0],forecast.set_index('ds')[from_dt:from_dt].yhat)], columns=)
            result_t2 = pd.concat([result_t2, result_t1], axis=1)

        result_t2 = result_t2.T
        result_t2.index = future.ds
        result_t3 = pd.concat([pd.DataFrame(df.loc['2018-01':'2018-12'].iloc[:,0]), forecast.set_index('ds')['2018-01':'2018-12'].yhat.round(), result_t2], axis=1)
        result_t3['param'] = str(p)
        result_t3['mean_12months'] = result_t2.mean().values[0]
        result_all = pd.concat([result_all, result_t3])
        
    result_all.columns = ['旅客数(実績)', '旅客数(予測)', 'MAPE', 'param', 'mean_12months']
    print('Best parameter is : ', result_all.sort_values(by='mean_12months', ascending=True).iloc[0,3])
    
    # 対象DBにて予測結果を格納
    td.to_td(result_all, '{}.test_export'.format(database), con=con, if_exists='append')


最後に、今回はシンプルなパターンの例となりましたが、実際には1万パターンもしくはそれ以上の計算など大量の場合が多いため、こういった機能を使うとすごく助かると思います。それでは、ぜひ試してみてください!

Share
UserEngagement事務局
UserEngagement事務局

Related posts

2023年6月14日

トレジャーデータPSチームによるダッシュボード構築プロジェクト事例
~トレジャーデータ書籍Appendix~


Read more
2023年5月31日

ダッシュボードの普及と課題
~トレジャーデータ書籍出版記念!一部先行公開~


Read more
2023年4月25日

Cookieに依存せずに広告CV計測を支援する機能「Conversion API」


Read more

Comments are closed.


  • ホーム
  • 個人情報の取り扱いについて
  • 個人情報に関する公表文
  • インフォマティブデータの取扱いについて
  • 会員情報変更
  • 退会手続きはこちら
記事を探す
  • ロール別ガイド
  • 用途別ガイド
  • 機能別ガイド
  • 活用事例
  • 全記事一覧
Community
  • Treasure Academy
LINKS
  • リリースノート
  • プロダクトドキュメント
  • Status Page(Incident情報)
  • Workflowサンプル集(英語)-TreasureBox
Copyright 2022 Treasure Data, Inc.
    ログイン