より良いモデルを目指して#

より良いモデルを目指して、改善できるところを紹介していく。

presets は変更できないことに注意#

精度を上げようと思った時にまず考えられるのが精度優先度をしているする presets の部分であるが、元の AutoGluon では以下の5段階の選択肢がある一方で、

  1. best_quality

  2. best_quality_with_high_quality_refit

  3. high_quality_fast_inference_only_refit

  4. medium_quality_faster_train

  5. optimize_for_deployment

本 Notebook はこの presets3. high_quality_fast_inference_only_refit の固定値となっていることに注意しよう。

time_limit を長く取ろう#

time_limit オプション(デフォルトは60分)は、学習にかける時間、とりわけモデル選定の過程における時間のソフトリミットを指定する。この値を長くすることによって、モデルの多層スタックアンサンブルが行われ、よりよいモデルを得られる可能性を高めることになる。学習フェーズは毎日のように実行するケースは少ないと思われるので、週や月に一度、時間をかけて学習をさせることに問題は出にくいはずだ。

eval_metric を変えてみよう#

モデルの評価指標を変えることで、より良い選ばれるモデルが選ばれる可能性がある。(フルオプションリストeval_metric 一覧を記載している)

例えば、分類問題のデフォルトは roc_auc であるが、log_loss は、観測値と予測値の乖離が大きければ大きなペナルティーを与える指標であり、少数の誤ったラベル付けに対しても罰則を多く取る。log_loss を指標にすることで Yes/No のラベルが極端に偏っているケースにうまく対応できるかもしれない。

特徴量を増やそう#

1. 行動データの集計値を特徴量として利用しよう#

モデルの精度を上げる最も有効的な手段は特徴量を増やすことである。そもそも、予測に影響を与える特徴量が学習に使われなければ、どんなに頑張っても良いモデルを得ることはできない。

AutoGluon における学習のインプットテーブルはいわゆる attribute_table(1人1行のテーブル)となるため、アクセスログや購買履歴といった behavior_table の情報は入っていない可能性がある。そもそも考えてみてほしい、”Churn するか否か” や “売上” といった予測をしたい場合、その目的変数に対して有効な説明変数(特徴量)は、性別や年齢といった attribute 情報ではなく、何回アクセスしたか、どのカテゴリをいくら購入したか、といった behavior 情報の方ではないだろうか。

behavior_table の情報を活用するためには前処理が必要である。なぜなら behavior_table は1人1行のテーブルになっていないからだ。特定の期間(直近3ヶ月、1年など)において様々なカラムに対して集計(pv, uu, frequency, recency, etc…)を行って初めて活用できるものになる。

以下のクエリ例はアクセスログである pageview テーブルに対して、td_client_id ごとの直近のアクセス日から遡って90日間の集計を行なっているものである。

DROP TABLE IF EXISTS website_90days_summary;
CREATE TABLE website_90days_summary AS
WITH tbl_last_access AS
(
  SELECT 
    td_client_id
    ,MIN(time) AS first_access
    ,MAX(time) AS last_access
    ,CEIL((MAX(time)-MIN(time))/(60*60*24*1.0) ) AS term
  FROM pageview
  GROUP BY td_client_id
)
, tbl_website_each_90days AS
(
  SELECT p.*, first_access, last_access, term
  FROM pageview p
  LEFT OUTER JOIN tbl_last_access l
  ON p.td_client_id = l.td_client_id
  WHERE TD_TIME_RANGE(time, TD_TIME_ADD(last_access,'-90d'), last_access)
)

SELECT 
  td_client_id
  ,MAX(TD_TIME_FORMAT(first_access,'yyyy-MM-dd')) AS first_access
  ,MAX(TD_TIME_FORMAT(last_access,'yyyy-MM-dd'))  AS last_access
  ,MAX(term) AS term
  ,COUNT(1)  AS pv
  ,COUNT(DISTINCT TD_TIME_FORMAT(time,'yyyy-MM-dd')) AS num_access_days
  ,COUNT(DISTINCT td_title) AS num_uniq_td_title
  ,COUNT(DISTINCT td_app)   AS num_uniq_td_app
  ,CONCAT_WS(' ', ARRAY_REMOVE(ARRAY_DISTINCT(ARRAY_AGG(COALESCE(td_category,''))),'')) AS ary_td_category
  ,CONCAT_WS(' ', ARRAY_REMOVE(ARRAY_DISTINCT(ARRAY_AGG(COALESCE(td_title,''))),'')) AS ary_td_title
FROM tbl_website_each_90days
GROUP BY td_client_id
ORDER BY term DESC

td_client_id

first_access

last_access

term

pv

num_access_days

num_uniq_td_title

num_uniq_td_app

ary_td_category

ary_td_title

b38b5a58-d95a-424a-8be4-8e0108a4a0ac

2021-09-03

2023-02-17

532

1

1

0

0

a5c0c04b-5530-4a6f-a81d-a26aa08b6c8e

2020-03-17

2021-04-14

394

5

1

2

0

Location – Treasure Bikes Treasure Bikes

d50be0f3-8047-4db2-ac27-4e291915b37e

2020-05-07

2021-05-04

362

29

8

2

0

Treasure Bikes Location – Treasure Bikes

e3b724f7-1696-4222-8743-4cdf91eb5628

2020-09-01

2021-08-11

345

1

1

1

0

Treasure Bikes

45e26f03-5adf-4f48-8611-5799ff6ccc9c

2020-04-02

2021-02-04

309

24

1

6

0

bicycles helmets

Treasure Bikes Bicycles Treasure Bikes Helmets

このテーブルを学習の inpute_table に td_client_id で JOIN したものを新たに学習に使っていくことを考える。

2. データエンリッチメントを行おう#

Audience Studio では、特定の項目があった場合に自動的にデータエンリッチメントを行なってくれる。これと類似のことを行うことによって特徴量を増やすことができる。

例えば IP アドレスを特徴量として持っている場合、そこから country_name や city_name を類推して付与してくれる。

配列型のカラムを変換しよう#

特徴量エンジニアリングで見たように、配列型のカラムは特徴量として使うことができない。単語が列挙された配列、例えば「興味カテゴリ」や「購入品目」が列挙された配列は特徴量として有効かもしれない。CONCAT_WS 関数によって配列型を Text 型に変換することによって、特徴量として扱ってくれる。

td_client_id

td_affinity_categories

660a2ad9-41b7-47ff-93ed-9955d11d79a0

[“Careers”, “Food & Drink”, “Health & Fitness”, “Home & Garden”, “Personal Finance”, “Shopping”, “Travel”]

dd8d50a1-7ca8-470f-a5fb-6d20796c6433

[“Food & Drink”, “Health & Fitness”, “Home & Garden”, “Personal Finance”, “Technology & Computing”]

68d400ec-538d-4ed1-b949-693901881b7e

[“Arts & Entertainment”, “Health & Fitness”, “Science”, “Travel”]

例えば td_affinity_categories という、興味カテゴリが列挙されたカラムを持っているならば、

SELECT td_client_id, CONCAT_WS(' ', ARRAY_AGG(word)) AS td_affinity_categories_str
FROM
(
  SELECT td_client_id, REGEXP_REPLACE(elm,'\s','_') AS word
  FROM customers
  CROSS JOIN UNNEST (td_affinity_categories) AS t(elm)
)
GROUP BY 1

を実行することで、以下のような半角スペース で区切られた文字列に変換することができる。(配列の要素ごとにあるスペースは事前にアンダースコア_に変換している)

td_client_id

td_affinity_categories_str

660a2ad9-41b7-47ff-93ed-9955d11d79a0

Careers Food_&Drink Health&Fitness Home&_Garden Personal_Finance Shopping Travel

dd8d50a1-7ca8-470f-a5fb-6d20796c6433

Food_&Drink Health&Fitness Home&Garden Personal_Finance Technology&_Computing

68d400ec-538d-4ed1-b949-693901881b7e

Arts_&Entertainment Health&_Fitness Science Travel

Text 型のカラムは、特徴量エンジニアリングで紹介したように、半角スペースごとに分割され、それぞれの単語の頻度を持ったカラムが新しく生成され、特徴量として活用されることになる。

追加の特徴量エンジニアリングを行おう#

AutoGluon の特徴量エンジニアリングで行なっていないエンジニアリングは世の中にたくさんある。自身で事前に追加の特徴量エンジニアリングを行うことで、より良いモデルを目指すことができる。