Saya mendapat beberapa permintaan untuk mendukung kendala monoton pada fitur tertentu sehubungan dengan output,
yaitu ketika fitur lain diperbaiki, memaksa prediksi menjadi monoton meningkat sehubungan dengan fitur tertentu yang ditentukan. Saya membuka edisi ini untuk melihat minat umum pada fitur ini. Saya dapat menambahkan ini jika ada cukup minat pada ini,
Saya membutuhkan bantuan dari sukarelawan dari komunitas untuk menguji fitur beta dan menyumbangkan dokumen dan tutorial tentang penggunaan fitur ini. Harap balas masalah ini jika Anda tertarik
Versi eksperimental disediakan di https://github.com/dmlc/xgboost/pull/1516. Untuk menggunakan ini sebelum digabungkan, klon repo https://github.com/tqchen/xgboost ,
Aktifkan opsi berikut (kemungkinan mungkin melalui python, r API)
monotone_constraints = "(0,1,1,0)"
Ada dua argumen
monotone_constraints
adalah daftar panjang jumlah fitur, 1 menunjukkan peningkatan monoton, - 1 berarti menurun, 0 berarti tidak ada kendala. Jika lebih pendek dari jumlah fitur, 0 akan diisi.Saat ini hanya mendukung algoritma serakah yang tepat pada multi-core. Belum tersedia dalam versi terdistribusi
@tqchen Saya mendapat permintaan di tempat kerja hari ini untuk membangun beberapa GBM dengan kendala monoton untuk menguji vs. kinerja beberapa model lain. Ini akan dengan kerugian penyimpangan tweedie, jadi saya harus pergi dengan fungsi kerugian kustom seperti berdiri hari ini.
Bagaimanapun, sepertinya ini kesempatan bagus untuk membantu dan menyelesaikan beberapa pekerjaan pada saat yang bersamaan.
Berdasarkan pembicaraan di sini , GBM(R Package) hanya memberlakukan monotonisitas secara lokal.
Bisakah Anda mengklarifikasi bagaimana XGBoost menegakkan batasan monoton?
Akan sangat bagus jika XGBoost dapat menerapkan batasan global.
Saya tidak mengerti apa yang Anda maksud dengan batasan lokal atau gloabl, dapatkah Anda menjelaskannya?
Maaf, saya menempelkan tautan yang salah, ini yang benar (Tautan)
Setiap pohon hanya dapat mengikuti kendala monoton di subset tertentu dari fitur yang menarik, sehingga banyak pohon yang bergabung bersama dapat menciptakan pelanggaran monotonisitas keseluruhan pada seluruh rentang fitur tersebut.
Oke, menurut pemahaman saya, ini diberlakukan secara global. Anda dipersilakan untuk mencobanya.
Baru saja melakukan beberapa tes sederhana kendala monotonisitas dalam konteks regresi univariat. Anda dapat menemukan kode dan beberapa dokumentasi yang sangat singkat di sini:
Beberapa pengamatan awal:
Ternyata saya memperkenalkan bug dalam kasus kendala = -1. Saya mendorong perbaikan, harap lihat apakah versi terbaru berfungsi dengan baik. Harap periksa juga apakah itu berfungsi ketika ada banyak kendala
@tqchen Saya menguji perbaikan Anda untuk bug yang berkurang, sepertinya itu berfungsi sekarang.
Mari kita konfirmasi jika ada penurunan kecepatan vs versi asli pada beberapa dataset standar, maka kita dapat menggabungkannya
@tqchen Saya menguji dua model variabel, satu dengan kendala yang meningkat dan satu lagi dengan penurunan:
params_constrained = params.copy()
params_constrained['updater'] = "grow_monotone_colmaker,prune"
params_constrained['monotone_constraints'] = "(1,-1)"
Hasilnya bagus
Saya akan mencoba mencari sedikit waktu untuk melakukan beberapa tes waktu sore ini.
Saya membuat pembaruan ke #1516 untuk memungkinkan deteksi otomatis opsi montone, sekarang pengguna hanya perlu memasukkan monotone_constraints = "(0,1,1,0)"
, silakan periksa apakah itu berfungsi.
Saya akan menggabungkan ini jika tes kecepatan berjalan dengan baik, dan mari kita lanjutkan ke tahap berikutnya untuk menambahkan tutorial
@madrury @XiaoxiaoWang87
Menambahkan tes untuk kasus multivariat di sini:
no constraint: 964.9 microseconds per iteration
with constraint: 861.7 microseconds per iteration
(silakan komentar jika Anda memiliki cara yang lebih baik untuk melakukan tes kecepatan)
Check failed: (wleft) <= (wright)
saat bermain di sekitar parameter hiper yang berbeda.Saya menjalankan beberapa percobaan waktu di notebook jupyter.
Tes pertama: beberapa data simulasi sederhana. Ada dua fitur, satu meningkat dan satu menurun, tetapi dengan gelombang sinusoidal kecil yang ditumpangkan sehingga setiap fitur tidak benar-benar monoton
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))
Berikut adalah hasil pengaturan waktu dari xgboosts dengan dan tanpa kendala monoton. Saya mematikan penghentian awal dan meningkatkan sejumlah iterasi untuk masing-masing.
Pertama tanpa kendala monoton:
%%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
Dan di sini dengan kendala monoton
%%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
Tes kedua: Data perumahan California dari sklearn. Tanpa kendala
%%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
Berikut adalah batasan yang saya gunakan
print(params_constrained['monotone_constraints'])
(1,1,1,0,0,1,0,0)
Dan waktu untuk model yang dibatasi
%%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 Saya telah mendorong PR lain untuk kehilangan centang pada wleft dan wright, harap lihat itu berfungsi.
@madrury Bisakah Anda juga membandingkan dengan versi XGBoost sebelumnya tanpa fitur kendala?
@tqchen Tentu. Bisakah Anda merekomendasikan hash komit untuk dibandingkan? Haruskah saya menggunakan komit sebelum penambahan batasan monoton Anda?
Ya yang sebelumnya akan dilakukan
@tqchen Saat membangun kembali versi yang diperbarui, saya mendapatkan beberapa kesalahan yang tidak saya alami sebelumnya. Saya berharap alasannya melompat keluar pada Anda dengan jelas.
Jika saya mencoba menjalankan kode yang sama seperti sebelumnya, saya mendapatkan pengecualian, berikut traceback lengkapnya:
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
Jika saya mengganti semuanya untuk argumen kata kunci yang Anda terapkan, saya juga mendapatkan kesalahan:
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'
hapus argumen pembaru dan pertahankan argumen kendala monoton dalam parameter, sekarang pembaruan kendala monoton diaktifkan secara otomatis saat kendala monoton disajikan
@tqchen Teman saya @amontz membantu saya mengetahuinya segera setelah saya memposting pesan. Saya telah menafsirkan komentar Anda sebagai meneruskan monotone_constraints
sebagai kwarg ke .train
.
Ia bekerja dengan penyesuaian itu. Terima kasih.
@madrury dapatkah Anda mengkonfirmasi kecepatannya?
Juga @madrury dan @XiaoxiaoWang87 karena fitur ini sekarang hampir digabungkan, alangkah baiknya jika Anda dapat berkoordinasi untuk membuat tutorial yang memperkenalkan fitur ini kepada pengguna.
Kami tidak dapat langsung membawa ipy notebook ke repo utama. tetapi gambar dapat didorong ke https://github.com/dmlc/web-data/tree/master/xgboost dan penurunan harga ke repo utama.
Kita juga perlu mengubah konversi string antarmuka front-end, sehingga tupel int dapat diubah menjadi format tupel string yang dapat diterima oleh backend.
@hetong007 untuk perubahan di R dan @slundberg untuk Julia
@tqchen Julia saat ini terpasang ke XGBoost versi 0,4 jadi lain kali saya perlu menggunakannya dan punya waktu, saya akan memperbarui binding jika tidak ada orang lain yang memilikinya saat itu. Pada saat itu perubahan ini juga bisa ditambahkan.
Berikut perbandingan antara model _tanpa_ kendala monoton dari sebelum implementasi hingga sesudahnya.
Komit 8cac37 : Sebelum penerapan kendala monoton.'
Data Simulasi : 100 loops, best of 3: 232 ms per loop
Data California : 10 loops, best of 3: 5.89 s per loop
Komit b1c224 : Setelah penerapan kendala monoton.
Data Simulasi : 100 loops, best of 3: 231 ms per loop
Data California : 10 loops, best of 3: 5.61 s per loop
Percepatan untuk california setelah implementasi terlihat mencurigakan bagi saya, tetapi saya mencobanya dua kali setiap jalan, dan itu konsisten.
Saya akan senang untuk mencoba menulis tutorial. Saya akan melihat-lihat dokumentasi yang ada dan mengumpulkan sesuatu dalam beberapa hari ke depan.
Ini bagus, PR sekarang resmi bergabung dengan master. Nantikan tutorialnya
Terima kasih @madrury. Nantikan itu. Beri tahu saya apa yang bisa saya bantu. Saya pasti akan bersedia untuk mempelajari lebih lanjut tentang topik ini.
Saya akan meningkatkannya besok. Saya hanya ingin tahu tentang alasan berkomunikasi dengan C++ melalui string alih-alih array.
Saya menguji dari R. Saya secara acak menghasilkan data dua variabel dan mencoba membuat prediksi.
Namun, saya menemukan bahwa
monotone_constraints
membuat prediksi sedikit berbeda.Tolong tunjukkan jika saya membuat kesalahan.
Kode untuk mereproduksinya (diuji pada versi github terbaru , bukan dari drat
):
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)
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)
Pembatasan dilakukan pada urutan parsial. Jadi kendala hanya berlaku jika kita menggerakkan sumbu montone, menjaga sumbu lainnya tetap
@hetong007 Untuk membuat plot saya, saya
seq
di R.colmeans
di R.Inilah kode python yang saya gunakan untuk plot yang saya sertakan di atas, seharusnya cukup mudah dikonversi ke kode R yang setara.
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)
Inilah cara saya melakukan plot ketergantungan parsial (untuk model arbitrer):
Kode:
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)
Terima kasih atas bimbingannya! Saya menyadari bahwa saya membuat kesalahan konyol dalam plot. Inilah tes lain pada data univariat, plotnya tampak baik-baik saja:
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)
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)
@hetong007 Jadi tujuan dalam antarmuka R adalah untuk memungkinkan pengguna meneruskan array R selain string
monotone_constraints=c(1,-1)
Tolong beri tahu kami ketika Anda PR tutorialnya
@hetong007 Anda juga sangat disambut untuk membuat versi r-blogger
@tqchen Maaf teman-teman, saya sedang dalam perjalanan kerja selama seminggu.
Saya mengirim beberapa permintaan tarik dengan tutorial kendala monoton. Tolong beri tahu saya apa yang Anda pikirkan, saya senang dengan kritik atau kritik apa pun.
Semoga pantas untuk menanyakan ini di sini: apakah ini akan berfungsi jika kita memperbarui menggunakan git clone --recursive https://github.com/dmlc/xgboost
?
Saya bertanya ketika saya melihat tutorial baru tetapi tidak ada yang baru tentang perubahan pada kode itu sendiri. Terima kasih semua!
ya, fitur baru digabungkan sebelum tutorial digabungkan
Halo,
Saya tidak yakin Anda berhasil menerapkan montonisitas global, dari apa yang saya lihat dalam kode Anda, itu lebih sesuai dengan monotonisitas lokal.
Berikut adalah contoh sederhana memecahkan monotonisitas:
`
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)))
perpustakaan (xgboost)
set.seed(0)
XGB <- xgboost(data=data.matrix(df[,-1]),label=df[,1],
objektif=" reg:linier ",
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$prediksi <- prediksi(XGB,data.matrix(sans_corr))
`
Semoga pemahaman saya tentang kode Anda dan contoh saya tidak salah
Saat ini fitur ini tidak ada di api Sklearn. Bisakah Anda atau seseorang tolong bantu menambahkannya? Terima kasih!
Dimungkinkan untuk memaksakan monotonisitas umum pada suatu variabel, tanpa menentukan apakah itu harus meningkat atau menurun?
@davidADSP Anda dapat melakukan pemeriksaan korelasi spearman pada prediktor dan target yang diinginkan untuk melihat apakah peningkatan atau penurunan itu tepat.
Fitur ini tampaknya tidak valid ketika 'tree_method':'hist'. @tqchen ada bantuan? Terima kasih semuanya.
Bagaimana cara kerja kendala untuk tujuan multikelas seperti mlogloss? Apakah kendala monotonisitas didukung untuk kerugian multikelas? Jika ya, bagaimana penegakannya. (Adapun setiap kelas ada pohon)
Apakah ada whitepaper tentang Algoritma Monotisitas yang diterapkan di XGBOOST? Apakah Global atau Lokal? Lokal berarti khusus untuk node tertentu tetapi node di bagian lain dari pohon mungkin membuat pelanggaran monotonisitas keseluruhan. Juga adakah yang bisa membantu saya dalam memahami baris L412-417 . Mengapa "w" dibatasi- atas dan bawah. Bagaimana ini membantu untuk mempertahankan Monotonisitas. Baris 457 - Mengapa "pertengahan" digunakan?
Komentar yang paling membantu
Saat ini fitur ini tidak ada di api Sklearn. Bisakah Anda atau seseorang tolong bantu menambahkannya? Terima kasih!