より良いモデルを目指して#
Contents
より良いモデルを目指して、改善できるところを紹介していく。
presets は変更できないことに注意#
精度を上げようと思った時にまず考えられるのが精度優先度をしているする presets
の部分であるが、元の AutoGluon では以下の5段階の選択肢がある一方で、
best_quality
best_quality_with_high_quality_refit
high_quality_fast_inference_only_refit
medium_quality_faster_train
optimize_for_deployment
本 Notebook はこの presets
は 3. 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 の特徴量エンジニアリングで行なっていないエンジニアリングは世の中にたくさんある。自身で事前に追加の特徴量エンジニアリングを行うことで、より良いモデルを目指すことができる。