[1]lead_scoring_demo_shape
https://console.treasuredata.com/app/queries/editor?queryId=161457
CVに関係のありそうな変数のみを選択して使用する。
今回使うランダムフォレストというロジックでは、量的変数を前提としているため、選択と同時に整形も行う。
case
when LOWER(job_title2) LIKE '%manager%' then 1
when LOWER(job_title2) LIKE '%director%' then 1
when LOWER(job_title2) LIKE '%supervisor%' then 1
else 0
end as is_manager
職業名は、"manager","director","supervisor"が入っている人は1、そうでない人は0とした変数に変換して使用する。
case
when acquisition_channel = 'Cold Call' then 1
else 0
end as acquisition_channel_Cold_Call,
case
when acquisition_channel = 'Cold Email' then 1
else 0
end as acquisition_channel_cold_email,
case
when acquisition_channel = 'Paid Leads' then 1
else 0
end as acquisition_channel_paid_leads,
case
when acquisition_channel = 'Organic Search' then 1
else 0
end as acquisition_channel_organic_search,
リードの取得経路を表すacquisition_channelという変数はパターン数が存在するので、ダミー変数を使用する。
ダミー変数とは
No | acquisition_channel |
---|---|
01 | Cold Call |
02 | Cold Email |
03 | Paid Leads |
04 | Organic Search |
05 | Paid Search |
のような質的データを
No | Cold Call | Cold Email | Paid Leads | Organic Search |
---|---|---|---|---|
01 | 1 | 0 | 0 | 0 |
02 | 0 | 1 | 0 | 0 |
03 | 0 | 0 | 1 | 0 |
04 | 0 | 0 | 0 | 1 |
05 | 0 | 0 | 0 | 0 |
という0と1の量的データで現したものである。
会社規模を表すcompany_size、業界を表すindustryという変数も同様にダミー変数を使用する。
[2]lead_scoring_demo_feature
https://console.treasuredata.com/app/queries/editor?queryId=161511
INSERT OVERWRITE TABLE lead_scoring_featured
SELECT
rowid,
converted as label,
array(days_since_signup, completed_form,visited_pricing,registered_for_webinar,attended_webinar,is_manager,acquisition_channel_cold_call,acquisition_channel_cold_email,acquisition_channel_paid_leads,acquisition_channel_organic_search,company_size_11_50,company_size_51_100,company_size_101_250,company_size_251_1000,company_size_1000_10000,company_size_10001,industry_web_internet,industry_furniture,industry_heavy_manufacturing,industry_scandanavion_design,industry_financial_services
) as features
FROM lead_scoring2
hivemallでは、説明変数をarray型にする必要があるためその処理を行う。
[3]lead_scoring_demo_train
https://console.treasuredata.com/app/queries/editor?queryId=161576
INSERT OVERWRITE TABLE lead_scoring_trainmodel
SELECT
train_randomforest_classifier(features,label,'-trees 10') as (model_id,model_type,pred_model,var_importance,oob_errors,oob_tests)
FROM lead_scoring_featured
train_randomforest_classifierという関数を使えばよい。引数'-trees'で決定木の数を指定できる。
[4]lead_scoring_demo_predict
https://console.treasuredata.com/app/queries/editor?queryId=161604
WITH t1 AS(
SELECT
t.rowid,
tree_predict(p.model_id,p.model_type,p.pred_model,t.features,true) as predicted
FROM
lead_scoring_trainmodel as p
LEFT OUTER JOIN lead_scoring_featured as t
),
tree_predict関数を使って予測を行う。 返り値は各レコードに対する全決定木における予測結果。
t2 AS(
SELECT
rowid,
rf_ensemble(predicted) as predicted
FROM t1
GROUP BY
rowid
)
rf_ensemble関数でアンサンブルという手法を使う。 今回は決定木の数が10個なので、1データに対して10通りの予測結果がある。 それらを集計して多数決で最終的な予測ラベルを決めるのがアンサンブルである。
INSERT OVERWRITE TABLE lead_scoring_predicted
SELECT
rowid,
predicted.label, predicted.probability, predicted.probabilities
FROM
t2;
rf_ensemble関数の返り値は [予測ラベル,そのラベルである確率,[各ラベルである確率(配列)]] という形式なので分かりやすくするため分解する。
[5]lead_scoring_demo_evaluate
https://console.treasuredata.com/app/queries/editor?queryId=161636
WITH t1 AS(
SELECT
t.rowid,
t.label as actual,
p.label as predicted
FROM
lead_scoring_predicted as p
LEFT OUTER JOIN lead_scoring_featured as t ON (t.rowid = p.rowid)
)
SELECT
count(1) / 100000
FROM
t1
WHERE
actual = predicted;
ここでは単純に、予測ラベルと実際のラベルを比べて予測成功した確率を出す。
[6]lead_scoring_demo_grade
https://console.treasuredata.com/app/queries/editor?queryId=161651
WITH t1 AS(
SELECT
rowid,
if(label = 0, 1 - probability, probability) as cv_probability
FROM
lead_scoring_predicted
),
lead_scoring_predictedのprobabilityというcolumnは、予測ラベルに対する確率なのでラベル1に対する確率に統一する。
INSERT OVERWRITE TABLE lead_scoring_grade
SELECT
rowid,
case
when (cv_probability < 0.2) then 'F'
when (cv_probability < 0.4 AND cv_probability >= 0.2) then 'D'
when (cv_probability < 0.6 AND cv_probability >= 0.4) then 'C'
when (cv_probability < 0.8 AND cv_probability >= 0.6) then 'B'
else 'A'
end as grade
FROM
t1
)
応じてユーザーをA,B,C,D,Fの5段階に分類した。
[7]lead_scoring_demo_graderate
https://console.treasuredata.com/app/queries/editor?queryId=162490
WITH t1 AS(
SELECT
t.rowid,
t.label,
p.grade
FROM
lead_scoring_grade as p
LEFT OUTER JOIN lead_scoring_featured as t ON (t.rowid = p.rowid)
)
SELECT
grade,
label,
count(*)
FROM
t1
各段階のラベルごとの人数をカウントした。
grade | label | count |
---|---|---|
A | 0 | 4 |
A | 1 | 23 |
B | 0 | 158 |
B | 1 | 1594 |
C | 0 | 627 |
C | 1 | 5836 |
D | 0 | 1555 |
D | 1 | 3323 |
F | 0 | 74830 |
F | 1 | 12050 |
- データを整形:質的変数を量的変数に
- パターンの多い(決まっていない)変数 → パターンにまとめる
- パターンの決まっている変数 → ダミー変数を利用する
- データを整形:必要な変数を特徴ベクトルに
- array関数を使って配列にする
- Random Forest による学習
- train_randomforest_classifier関数を使用する
- -trees で決定木の数 など引数として色々なパラメータを与えることができる
- モデルを使った予測
- tree_predict関数と、rf_ensemble関数を使用
- 返り値は予測ラベルとその確率、全ラベルに対する確率
- リードを予測確率により段階に分類