2017-06-24 27 views
1

私は分類問題にh2o.gbmを使用していましたが、クラス確率の計算方法についてもう少し理解したいと思っていました。出発点として、(リーフの観測値を見て)1つのツリーだけでgbmのクラス確率を再計算しようとしましたが、結果は非常に混乱します。H2o GBMクラス確率計算の再現方法

私の正のクラス変数が "買い"で、負のクラス変数 "not_buy"で、 "dt.train"というトレーニングセットと "dt.test"という別のテストセットがあるとしましょう。

通常の意思決定ツリーでは、新しいデータ行(テストデータ)に対する「購入」P(has_bought =「購入」)のクラス確率は、リーフ内のすべての観測をクラス「購入」でリーフ内の観測の総数(ツリーを成長させるために使用されるトレーニングデータに基づく)。

しかし、h2o.gbmは、「通常の」意思決定ツリー(n.treesを1に設定し、sample.ratesを1に設定)をシミュレートした場合でも、何か異なる処理を行うようです。この混乱を説明する最善の方法は、私が何を段階的に行ったかを伝えることです。

ステップ1:私はオーバーフィッティングやモデルのパフォーマンスを気にしないモデル

トレーニング。私は自分の人生をできるだけ簡単にしたいので、n.treesを1に設定し、すべてのsample.rateパラメータを設定することで、すべてのトレーニングデータ(行と列)が各ツリーと分割に使用されていることを確認します以下は、モデルを訓練するためのコードです。

base.gbm.model <- h2o.gbm(
     x = predictors, 
     y = "has_bought", 
     training_frame = dt.train, 
     model_id = "2", 
     nfolds = 0, 
     ntrees = 1, 
     learn_rate = 0.001, 
     max_depth = 15, 
     sample_rate = 1, 
     col_sample_rate = 1, 
     col_sample_rate_per_tree = 1, 
     seed = 123456, 
     keep_cross_validation_predictions = TRUE, 
     stopping_rounds = 10, 
     stopping_tolerance = 0, 
     stopping_metric = "AUC", 
     score_tree_interval = 0 
    ) 

ステップ2:訓練の葉の割り当ては、私が何をしたいのか

を設定するにあたって、モデルを訓練するために使用されているのと同じデータを使用し、理解し、彼らが終了した葉でありますH2oはこれに対応した機能を提供します。これを以下に示します。

train.leafs <- h2o.predict_leaf_node_assignment(base.gbm.model, dt.train) 

これは、トレーニングデータの行ごとにリーフノードの割り当て(例えば、「LLRRLL」)を返します。私たちは1つのツリーしか持たないので、この列は "T1.C1"と呼ばれ、 "leaf_node"という名前に変更されました。これはトレーニングデータのターゲット変数 "has_bought"で囲みます。これは以下の出力をもたらします(ここからは「train.leafs」と呼ばれます)。

table "train.leafs"

ステップ3:テストの作成予測は、テスト・セットの場合

を設定し、私は2つのことを予測したい:

  1. モデル自体P(の予測has_bought = "buy")
  2. モデルに応じたリーフノードの割り当て。

test.leafs <- h2o.predict_leaf_node_assignment(base.gbm.model, dt.test) 
test.pred <- h2o.predict(base.gbm.model, dt.test) 

これを見つけた後、私はテストセットのターゲット変数でこれら2つの予測を組み合わせるためにCBINDを使用しました。

test.total <- h2o.cbind(dt.test[, c("has_bought")], test.pred, test.leafs) 

この結果は、以下の表であり、ここから「テスト」と呼ばれます。合計が」

残念ながら、私は2つの以上のリンクを投稿するのに十分な担当者のポイントを持っていません。しかし、あなたはをクリックすると、 『ステップ5で手動 確率計算』と組み合わせ表 『test.total』、それは基本的にですコラム「manual_prob_buy」なしで同じテーブル

ステップ4:手動で理論的には、私は予測することができるはず確率

を予測今自分自身の確率。私はループを書くことでこれを行い、 "test.total"の各行にループします。各行について、リーフノードの割り当てを行います。

次に、リーフノードの割り当てを使用して "train.leafs"テーブルをフィルタリングし、陽性クラス(has_bought == 1)(posN)を持つ観測数と合計で観測数を調べます)をテスト行に関連付けられたリーフ内に格納します。

(標準)計算posN/totalNを実行し、これをtest-rowに "manual_prob_buy"という新しい列として格納します。これは、そのリーフのP(has_bought = "buy")の確率でなければなりません。したがって、この葉に含まれる各テスト行は、この確率を得るべきである。 このforループは以下のとおりです。

for(i in 1:nrow(dt.test)){ 
     leaf <- test.total[i, leaf_node] 
     totalN <- nrow(train.leafs[train.leafs$leaf_node == leaf]) 
     posN <- nrow(train.leafs[train.leafs$leaf_node == leaf & train.leafs$has_bought == "buy",]) 
     test.total[i, manual_prob_buy := posN/totalN] 
    } 

ステップ5:私は混乱し場所です確率

を比較します。以下は更新された "test.total"テーブルであり、 "buy"はモデルによる確率P(has_bought = "buy")を表し、 "manual_prob_buy"はステップ4からの手動計算された確率を表す。 、これらの確率は、私は1本のだけの木を使用して、私は手動確率計算と組み合わせる1.

表「test.total」 table "test.total" combined with manual probability calculation

質問にsample.ratesを設定している知って、同一である必要があります

この2つの確率が同じではない理由は分かりません。私が知る限り、パラメータを「通常の」分類ツリーのように設定する必要があります。

質問:なぜ私はこれらの確率の違いを見つけるのか知っていますか?

誰かが間違った仮定をしている可能性のある箇所を教えてください。私は本当に私が馬鹿なことをしたことを願っています。

ありがとうございます!

答えて

0

Rのh2o.predict()の結果を自分の手書きコードと比較するのではなく、一致するはずのH2O MOJOと比較することをお勧めします。あなたはその簡単な例を自分で実行し、独自のモデルとの予測するデータの新しい行に応じて変更することができます

http://docs.h2o.ai/h2o/latest-stable/h2o-genmodel/javadoc/overview-summary.html#quickstartmojo

は、ここで例を参照してください。

これを行うことができたら、コードを見て、Java環境でデバッグ/シングルステップして、予測がどのように計算されるかを正確に見ることができます。

現在地githubの上MOJO予測コードを見つけることができます:あなたはコメントを

https://github.com/h2oai/h2o-3/blob/master/h2o-genmodel/src/main/java/hex/genmodel/easy/EasyPredictModelWrapper.java

+0

おかげで、それが可能だった知りませんでした。それを調べます。 –