Xgboost: [新機胜]ツリヌ構築における単調制玄

䜜成日 2016幎08月27日  Â·  46コメント  Â·  ゜ヌス: dmlc/xgboost

出力に関しお特定の機胜の単調制玄をサポヌトするこずに぀いお、いく぀かのリク゚ストがありたした。

぀たり、他の機胜が固定されおいる堎合、特定の指定された機胜に察しお予枬を単調に増加させたす。 この機胜に関する䞀般的な関心を確認するために、この号を開いおいたす。 これに十分な関心があれば、これを远加できたす。

ベヌタ機胜をテストし、この機胜の䜿甚に関するドキュメントずチュヌトリアルを提䟛するには、コミュニティのボランティアの助けが必芁です。 興味のある方は、問題に返信しおください

最も参考になるコメント

珟圚、この機胜はSklearnAPIにはありたせん。 あなたたたは誰かがそれを远加するのを手䌝っおくれたすか ありがずう

党おのコメント46件

実隓的なバヌゞョンはhttps://github.com/dmlc/xgboost/pull/1516で提䟛されおいたすhttps://github.com/tqchen/xgboost 、

次のオプションをオンにしたすPython、r APIを介しお可胜である可胜性がありたす

monotone_constraints = "(0,1,1,0)"

2぀の議論がありたす

  • monotone_constraintsは、特城の数の長さのリストです。1は単調な増加を瀺し、-1は枛少を意味し、0は制玄がないこずを意味したす。 フィヌチャの数より短い堎合は、0が埋め蟌たれたす。

    • 珟圚、Pythonのタプル圢匏をサポヌトしおいたす。rを䜿甚するず文字列ずしお枡すこずができたす。

確認するこず

  • [x]元のツリヌブヌスタヌの速床は遅くなりたせんコヌド構造を少し倉曎したした。理論的には、テンプレヌトの最適化によっおむンラむン化されたすが、確認する必芁がありたす
  • [x]単調回垰の速床ず正確さ
  • [x]この制玄を導入するこずによるパフォヌマンス

既知の制限

珟圚、マルチコアでのみサポヌトされおいる正確な欲匵りアルゎリズム。 分散版ではただ利甚できたせん

@tqchen今日、仕事で、他のいく぀かのモデルのパフォヌマンスず比范しおテストするために、単調な制玄を持぀いく぀かのGBMを構築するように芁求されたした。 これは、tweedieの逞脱床損倱を䌎うため、珟圚のカスタム損倱関数を䜿甚する必芁がありたす。

いずれにせよ、手助けをするず同時にいく぀かの仕事を成し遂げる良いチャンスのようです。

ここでの話に基づいお、GBMRパッケヌゞはロヌカルでのみ単調性を匷制したす。
XGBoostが単調な制玄をどのように実斜するかを明確にできたすか
XGBoostがグロヌバルな制玄を匷制できるずいいですね。

ロヌカル制玄たたはgloabl制玄の意味がわかりたせんが、詳しく説明しおいただけたすか

申し蚳ありたせんが、間違ったリンクを貌り付けたした。これが正しいリンクですリンク
各ツリヌは、関心のある機胜の特定のサブセットでのみ単調な制玄に埓う可胜性があるため、倚くのツリヌが䞀緒にアンサンブルするず、その機胜の党範囲で党䜓的な単調性の違反が発生する可胜性がありたす。

OK、私の理解では、それはグロヌバルに実斜されおいたす。 ぜひお詊しください。

単倉量回垰のコンテキストで単調性制玄のいく぀かの簡単なテストを実行したした。 コヌドずいく぀かの非垞に簡単なドキュメントはここにありたす

https://github.com/XiaoxiaoWang87/xgboost_mono_test/blob/master/xgb_monotonicity_constraint_testing1-univariate.ipynb

いく぀かの最初の芳察

  • 単䞀倉数回垰問題の堎合、単調制玄= + 1はうたく機胜するようです
  • 単䞀倉数回垰問題の堎合、私のデヌタセットでは、単調制玄= -1は単調枛少関数を生成しないようです。 むしろ、それは定数を䞎えたす。 ただし、これは、制玄を匷制する際の改善の欠劂が原因である可胜性もありたす。 確認するにはTianqiの提案に埓っお、デヌタセットを反転し、制玄を+1に蚭定しおみおください。
  • 制玄を正しく远加するず、過剰適合を防ぎ、パフォヌマンス/解釈の利点をもたらす可胜性がありたす。

制玄= -1の堎合にバグが発生するこずがわかりたした。修正をプッシュしたした。最新バヌゞョンが正垞に機胜するかどうかを確認しおください。耇数の制玄がある堎合にも機胜するかどうかを確認しおください

@tqchen枛少するバグに぀いお修正をテストしたしたが、珟圚は機胜しおいるようです。

xgboost-no-constraint
xgboost-with-constraint

䞀郚の暙準デヌタセットで元のバヌゞョンず比范しお速床が䜎䞋しおいるかどうかを確認しおから、それをマヌゞできたす

@tqchen 2぀の倉数モデルをテストしたした。1぀は制玄が増加し、もう1぀は枛少したす。

params_constrained = params.copy()
params_constrained['updater'] = "grow_monotone_colmaker,prune"
params_constrained['monotone_constraints'] = "(1,-1)"

結果は良いです

xgboost-two-vars-increasing
xgboost-two-vars-decreasing

今日の午埌、タむミングテストを行う時間を少し芋぀けようず思いたす。

モントヌンオプションの自動怜出を可胜にするために1516を曎新したした。珟圚、ナヌザヌはmonotone_constraints = "(0,1,1,0)"を枡すだけで枈みたす。それが機胜するかどうかを確認しおください。

速床テストがうたくいったらこれをマヌゞし、チュヌトリアルを远加する次の段階に進みたしょう

@madrury @ XiaoxiaoWang87

ここに倚倉量ケヌスのテストを远加したした

https://github.com/XiaoxiaoWang87/xgboost_mono_test/blob/master/xgb_monotonicity_constraint_testing2-multivariate.ipynb

  • これで、単調制玄= 1ず= -1の䞡方が期埅どおりに機胜するこずを確認したした。
  • 単調性を制限しおも、明らかな速床*の䜎䞋には぀ながりたせん
    * speed = avg [早期停止たでの時間/早期停止たでのブヌスティングの反埩回数]

no constraint: 964.9 microseconds per iteration
with constraint: 861.7 microseconds per iteration

速床テストを行うためのより良い方法がある堎合はコメントしおください

  • 非単調倉数の方向を制玄する堎合は泚意が必芁です。 これにより、パフォヌマンスが䜎䞋する可胜性がありたす。
  • さたざたなハむパヌパラメヌタを操䜜するず、 Check failed: (wleft) <= (wright)原因でコヌドがクラッシュしたす。

私はjupyterノヌトブックでいく぀かのタむミング実隓を実行したした。

最初のテストいく぀かの単玔なシミュレヌションデヌタ。 2぀の特城がありたす。1぀は増加し、もう1぀は枛少したすが、小さな正匊波が重ね合わされおいるため、各特城は真に単調ではありたせん。

X = np.random.random(size=(N, K))
y = (5*X[:, 0] + np.sin(5*2*pi*X[:, 0])
     - 5*X[:, 1] - np.cos(5*2*pi*X[:, 1])
     + np.random.normal(loc=0.0, scale=0.01, size=N))

単調制玄がある堎合ずない堎合のxgboostのタむミング結果は次のずおりです。 早期打ち切りをオフにしお、それぞれの反埩回数を増やしたした。

最初に単調な制玄なし

%%timeit -n 100
model_no_constraints = xgb.train(params, dtrain, 
                                 num_boost_round = 2500, 
                                 verbose_eval = False)

100 loops, best of 3: 246 ms per loop

そしおここに単調性の制玄がありたす

%%timeit -n 100
model_with_constraints = xgb.train(params_constrained, dtrain, 
                                 num_boost_round = 2500, 
                                 verbose_eval = False)

100 loops, best of 3: 196 ms per loop

2番目のテストsklearnからのカリフォルニアhHousingデヌタ。 制玄なし

%%timeit -n 10
model_no_constraints = xgb.train(params, dtrain, 
                                 num_boost_round = 2500, 
                                 verbose_eval = False)

10 loops, best of 3: 5.9 s per loop

これが私が䜿甚した制玄です

print(params_constrained['monotone_constraints'])

(1,1,1,0,0,1,0,0)

そしお、制玄されたモデルのタむミング

%%timeit -n 10
model_no_constraints = xgb.train(params, dtrain, 
                                 num_boost_round = 2500, 
                                 verbose_eval = False)

10 loops, best of 3: 6.08 s per loop

@ XiaoxiaoWang87私は別のPRをプッシュしお、wleftずwrightのチェックを緩めたした。それが機胜するこずを確認しおください。
@madrury制玄機胜のない以前のバヌゞョンのXGBoostず比范するこずもできたすか

@tqchenもちろんです。 比范するコミットハッシュをお勧めできたすか 単調な制玄を远加する前に、コミットを䜿甚する必芁がありたすか

はい、前のもので十分です

@tqchen曎新されたバヌゞョンを再構築するず、以前は発生しおいなかった゚ラヌが発生したす。 理由がはっきりずあなたに飛び出すこずを願っおいたす。

以前ず同じコヌドを実行しようずするず、䟋倖が発生したす。完党なトレヌスバックは次のずおりです。

XGBoostError                              Traceback (most recent call last)
<ipython-input-14-63a9f6e16c9a> in <module>()
      8    model_with_constraints = xgb.train(params, dtrain, 
      9                                        num_boost_round = 1000, evals = evallist,
---> 10                                    early_stopping_rounds = 10)  

/Users/matthewdrury/anaconda/lib/python2.7/site-packages/xgboost-0.6-py2.7.egg/xgboost/training.pyc in train(params, dtrain, num_boost_round, evals, obj, feval, maximize, early_stopping_rounds, evals_result, verbose_eval, learning_rates, xgb_model, callbacks)
    201                            evals=evals,
    202                            obj=obj, feval=feval,
--> 203                            xgb_model=xgb_model, callbacks=callbacks)
    204 
    205 

/Users/matthewdrury/anaconda/lib/python2.7/site-packages/xgboost-0.6-py2.7.egg/xgboost/training.pyc in _train_internal(params, dtrain, num_boost_round, evals, obj, feval, xgb_model, callbacks)
     72         # Skip the first update if it is a recovery step.
     73         if version % 2 == 0:
---> 74             bst.update(dtrain, i, obj)
     75             bst.save_rabit_checkpoint()
     76             version += 1

/Users/matthewdrury/anaconda/lib/python2.7/site-packages/xgboost-0.6-py2.7.egg/xgboost/core.pyc in update(self, dtrain, iteration, fobj)
    804 
    805         if fobj is None:
--> 806             _check_call(_LIB.XGBoosterUpdateOneIter(self.handle, iteration, dtrain.handle))
    807         else:
    808             pred = self.predict(dtrain)

/Users/matthewdrury/anaconda/lib/python2.7/site-packages/xgboost-0.6-py2.7.egg/xgboost/core.pyc in _check_call(ret)
    125     """
    126     if ret != 0:
--> 127         raise XGBoostError(_LIB.XGBGetLastError())
    128 
    129 

XGBoostError: [14:08:41] src/tree/tree_updater.cc:18: Unknown tree updater grow_monotone_colmaker

実装したキヌワヌド匕数のすべおを切り替えるず、゚ラヌも発生したす。

TypeError                                 Traceback (most recent call last)
<ipython-input-15-ef7671f72925> in <module>()
      8                                    monotone_constraints="(1)",
      9                                    num_boost_round = 1000, evals = evallist,
---> 10                                    early_stopping_rounds = 10)  

TypeError: train() got an unexpected keyword argument 'monotone_constraints'

アップデヌタ匕数を削陀し、パラメヌタに単調制玄匕数を保持したす。これで、単調制玄が提瀺されたずきに単調制玄アップデヌタが自動的にアクティブ化されたす。

@tqchen私の仲間の@amontzは、メッセヌゞを投皿した盎埌にそれをmonotone_constraintsを.trainぞのクワヌグずしお枡すず解釈したした。

これらの調敎で機胜したす。 ありがずう。

@madrury速床を確認できたすか

たた、 @ madruryず@ XiaoxiaoWang87は、この機胜が

ipyノヌトブックをメむンリポゞトリに盎接持ち蟌むこずはできたせん。 ただし、画像はhttps://github.com/dmlc/web-data/tree/master/xgboostにプッシュし、メむンリポゞトリにマヌクダりンするこずができたす。

たた、フロント゚ンドむンタヌフェむスの文字列倉換を倉曎しお、intタプルをバック゚ンドで受け入れられる文字列タプル圢匏に倉換できるようにする必芁がありたす。

Rの倉曎に぀いおは@ hetong007 、Juliaの堎合は@slundberg

@tqchen Juliaは珟圚XGBoostの0.4バヌゞョンに接続されおいるので、次回それを䜿甚する必芁があり、時間を取っおおく必芁がありたす。それたでに他に誰もいない堎合は、バむンディングを曎新したす。 その時点で、この倉曎も远加できたす。

これは、実装前から実装埌たでの単調な制玄のないモデル間の比范です。

コミット8cac37 単調制玄の実装前。
シミュレヌトされたデヌタ 100 loops, best of 3: 232 ms per loop
カリフォルニアデヌタ 10 loops, best of 3: 5.89 s per loop

コミットb1c224 単調制玄の実装埌。
シミュレヌトされたデヌタ 100 loops, best of 3: 231 ms per loop
カリフォルニアデヌタ 10 loops, best of 3: 5.61 s per loop

実装埌のカリフォルニアのスピヌドアップは私には疑わしいように芋えたすが、私はそれを片道2回詊したしたが、それは䞀貫しおいたす。

チュヌトリアルを曞いおみおください。 既存のドキュメントを芋お、数日䞭に䜕かをたずめたす。

これは玠晎らしいこずです。PRは正匏にマスタヌにマヌゞされたした。 チュヌトリアルを楜しみにしおいたす

@madruryに感謝したす。 それを楜しみに埅぀。 䜕ができるか教えおください。 私は確かにこのトピックに぀いおもっず研究したいず思っおいたす。

明日匷化したす。 配列ではなく文字列を介しおC ++ず通信する理由に぀いお知りたいだけです。

Rからテストしおいたす。2倉数デヌタをランダムに生成し、予枬を詊みおいたす。

しかし、私はそれを芋぀けたした

  1. xgboostは予枬を制玄したせん。
  2. パラメヌタmonotone_constraintsにより、予枬がわずかに異なりたす。

間違えた堎合はご指摘ください。

それを再珟するためのコヌド dratからではなく、最新のgithubバヌゞョンでテスト枈み

set.seed(1024)
x1 = rnorm(1000, 10)
x2 = rnorm(1000, 10)
y = -1*x1 + rnorm(1000, 0.001) + 3*sin(x2)
train = cbind(x1, x2)

bst = xgboost(data = train, label = y, max_depth = 2,
                   eta = 0.1, nthread = 2, nrounds = 10,
                   monotone_constraints = '(1,-1)')

pred = predict(bst, train)
ind = order(train[,1])
pred.ord = pred[ind]
plot(train[,1], y, main = 'with constraint')
pred.ord = pred[order(train[,1])]
lines(pred.ord)

wc

bst = xgboost(data = train, label = y, max_depth = 2,
                   eta = 0.1, nthread = 2, nrounds = 10)

pred = predict(bst, train)
ind = order(train[,1])
pred.ord = pred[ind]
plot(train[,1], y, main = 'without constraint')
pred.ord = pred[order(train[,1])]
lines(pred.ord)

woc

制玄は半順序で行われたした。 したがっお、制玄は、他の軞を固定したたた、モントヌン軞を移動する堎合にのみ適甚されたす。

@ hetong007私のプロットを䜜るために私は

  • x座暙のグリッドを含む配列を䜜成したした。その倉数をで予枬し、折れ線グラフに結合したいず思いたした。 これは、Rでseqしたす。
  • 他のすべおの倉数をトレヌニングデヌタの平均倀に等しく蚭定したす。 これは、Rのcolmeansになりたす。

䞊蚘のプロットに䜿甚したPythonコヌドは、これが同等のRコヌドに非垞に簡単に倉換できるはずです。

def plot_one_feature_effect(model, X, y, idx=1):

    x_scan = np.linspace(0, 1, 100)    
    X_scan = np.empty((100, X.shape[1]))
    X_scan[:, idx] = x_scan

    left_feature_means = np.tile(X[:, :idx].mean(axis=0), (100, 1))
    right_feature_means = np.tile(X[:, (idx+1):].mean(axis=0), (100, 1))
    X_scan[:, :idx] = left_feature_means
    X_scan[:, (idx+1):] = right_feature_means

    X_plot = xgb.DMatrix(X_scan)
    y_plot = model.predict(X_plot, ntree_limit=bst.best_ntree_limit)

    plt.plot(x_scan, y_plot, color = 'black')
    plt.plot(X[:, idx], y, 'o', alpha = 0.25)

これが私が郚分䟝存プロットを行う方法です任意のモデルに察しお

  • フィヌチャXの倀のグリッドをスキャンしたす。
  • フィヌチャヌXのグリッド倀ごずに

    • フィヌチャX列党䜓すべおの行をこの倀に蚭定したす。 その他の機胜は倉曎されおいたせん。

    • すべおの行を予枬したす。

    • 予枬の平均を取りたす。

  • 結果のX特城倀、平均予枬ペアは、X特城の郚分的な䟝存関係を瀺したす。

コヌド

def plot_partial_dependency(bst, X, y, f_id):

    X_temp = X.copy()

    x_scan = np.linspace(np.percentile(X_temp[:, f_id], 0.1), np.percentile(X_temp[:, f_id], 99.5), 50)
    y_partial = []

    for point in x_scan:

        X_temp[:, f_id] = point

        dpartial = xgb.DMatrix(X_temp[:, feature_ids])
        y_partial.append(np.average(bst.predict(dpartial)))

    y_partial = np.array(y_partial)

    # Plot partial dependence

    fig, ax = plt.subplots()
    fig.set_size_inches(5, 5)
    plt.subplots_adjust(left = 0.17, right = 0.94, bottom = 0.15, top = 0.9)

    ax.plot(x_scan, y_partial, '-', color = 'black', linewidth = 1)
    ax.plot(X[:, f_id], y, 'o', color = 'blue', alpha = 0.02)

    ax.set_xlim(min(x_scan), max(x_scan))
    ax.set_xlabel('Feature X', fontsize = 10)    
    ax.set_ylabel('Partial Dependence', fontsize = 12)

指導ありがずうございたす 私はあらすじでばかげた間違いをしたこずに気づきたした。 これが単倉量デヌタの別のテストです。プロットは問題ないようです。

set.seed(1024)
x = rnorm(1000, 10)
y = -1*x + rnorm(1000, 0.001) + 3*sin(x)
train = matrix(x, ncol = 1)

bst = xgboost(data = train, label = y, max_depth = 2,
               eta = 0.1, nthread = 2, nrounds = 100,
               monotone_constraints = '(-1)')
pred = predict(bst, train)
ind = order(train[,1])
pred.ord = pred[ind]
plot(train[,1], y, main = 'with constraint', pch=20)
lines(train[ind,1], pred.ord, col=2, lwd = 5)

rplot

bst = xgboost(data = train, label = y, max_depth = 2,
               eta = 0.1, nthread = 2, nrounds = 100)
pred = predict(bst, train)
ind = order(train[,1])
pred.ord = pred[ind]
plot(train[,1], y, main = 'without constraint', pch=20)
lines(train[ind,1], pred.ord, col=2, lwd = 5)

woc

@ hetong007したがっお、Rむンタヌフェヌスの目暙は、ナヌザヌが文字列のほかにR配列を枡せるようにするこずです。

monotone_constraints=c(1,-1)

チュヌトリアルのPR時にお知らせください

@ hetong007あなたもr-bloggerバヌゞョンを䜜るこずを歓迎したす

@tqchen申し蚳ありたせんが、私は1週間出匵したした。

単調な制玄のチュヌトリアルのために、いく぀かのプルリク゚ストを送信したした。 ご意芋をお聞かせください。批刀や批評はありがたいです。

うたくいけば、ここでこれを尋ねるのが適切です通垞のgit clone --recursive https://github.com/dmlc/xgboostを䜿甚しお曎新するず、これは機胜したすか

新しいチュヌトリアルを芋たずきに尋ねたすが、コヌド自䜓の倉曎に぀いおは䜕も新しいこずはありたせん。 皆さん、ありがずうございたした

はい、チュヌトリアルがマヌゞされる前に、新機胜がマヌゞされたす

こんにちは、

私があなたのコヌドで芋たものから、あなたがグロヌバルな単調性をうたく実装したかどうかはわかりたせんが、それはロヌカルな単調性にもっず察応しおいたす。

単調性を砎る簡単な䟋を次に瀺したす。

`
df <-data.framey = c2、rep6,100、1、rep11,100、
x1 = crep1,101、rep2,101、x2 = c1、rep2,100、1、rep2,100

ラむブラリxgboost
set.seed0
XGB <-xgboostdata = data.matrixdf [、-1]、label = df [、1]、
Objective = " reglinear "、
bag.fraction = 1、nround = 100、monotone_constraints = c1,0、
eta = 0.1

sans_corr <-data.framex1 = c1,2,1,2、x2 = c1,1,2,2

sans_corr $ prediction <-predictXGB、data.matrixsans_corr
`

あなたのコヌドず私の䟋が間違っおいないこずを理解しおください

珟圚、この機胜はSklearnAPIにはありたせん。 あなたたたは誰かがそれを远加するのを手䌝っおくれたすか ありがずう

倉数を増加させるか枛少させるかを指定せずに、倉数に䞀般的な単調性を適甚するこずは可胜ですか

@davidADSPは、目的の予枬子ずタヌゲットに察しおスピアマンの盞関チェックを実行しお、増加たたは枛少が適切かどうかを確認できたす。

'tree_method' 'hist'の堎合、この機胜は無効のようです。 @tqchen䜕か助けがありたすか 皆さんありがずう。

mloglossのようなマルチクラスの目的に察しお制玄はどのように機胜したすか マルチクラス損倱に察しお単調性制玄はサポヌトされおいたすか はいの堎合、それはどのように実斜されたすか。 各クラスには朚がありたす

XGBOOSTで実斜されおいるMonoticityAlgorithmに関するホワむトペヌパヌはありたすか グロヌバルですか、それずもロヌカルですか ロヌカルずは、特定のノヌドに固有ですが、ツリヌの他の郚分のノヌドは、党䜓的な単調性の違反を匕き起こす可胜性がありたす。 たた、 L412-417行を理解するのを手䌝っおくれる人はいたす

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡