Xgboost: [R] يتم تجاهل أفضل فهرس تكرار من الإيقاف المبكر عند حفظ النموذج على القرص

تم إنشاؤها على ١٥ يناير ٢٠٢٠  ·  33تعليقات  ·  مصدر: dmlc/xgboost

يتم توقع هذه القيم بعد xgboost::xgb.train :
247367.2 258693.3 149572.2 201675.8 250493.9 292349.2 414828.0 296503.2 260851.9 190413.3

يتم توقع هذه القيم بعد xgboost::xgb.save و xgboost::xgb.load للنموذج السابق:
247508.8 258658.2 149252.1 201692.6 250458.1 292313.4 414787.2 296462.5 260879.0 190430.1

هم قريبون ، لكن ليس نفس الشيء. تتراوح الاختلافات بين هذين التنبؤين من -1317.094 إلى 1088.859 على مجموعة من 25 ألف عينة. عند المقارنة مع الملصقات الحقيقية ، فإن MAE / RMSE لهذين التنبؤين لا يختلف كثيرًا.

لذلك أظن أن هذا له علاقة بأخطاء التقريب أثناء التحميل / الحفظ لأن MAE / RMSE لا يختلفان كثيرًا. ومع ذلك ، أجد هذا غريبًا لأن التخزين الثنائي للنموذج لا ينبغي أن يؤدي إلى أخطاء التقريب؟

أي شخص دليل؟

ملاحظة: يبدو أن تحميل وتوثيق عملية التدريب ليس مهمًا بالنسبة لي هنا. يمكنني تقديم تفاصيل إذا لزم الأمر ، أو إجراء محاكاة باستخدام بيانات وهمية لإثبات هذه النقطة.

Blocking bug

التعليق الأكثر فائدة

حل اللغز. لقد حددت السبب الحقيقي. عندما يتم حفظ النموذج على القرص ، يتم تجاهل المعلومات الخاصة بالإيقاف المبكر. في المثال ، يقوم XGBoost بتشغيل 6381 جولة تعزيز وإيجاد أفضل طراز في 6378 طلقة. يحتوي كائن النموذج الموجود في الذاكرة على 6381 شجرة ، وليس 6378 شجرة ، نظرًا لعدم إزالة أي شجرة. يوجد حقل إضافي best_iteration يتذكر التكرار الأفضل:

> fit$best_iteration
[1] 6378

يتم تجاهل هذا الحقل الإضافي بصمت عندما نحفظ النموذج على القرص. لذلك يستخدم predict() بالنموذج الأصلي 6378 شجرة ، بينما يستخدم predict() مع النموذج المستعاد 6381 شجرة.

> x <- predict(fit, newdata = dtrain2, predleaf = TRUE)
> x2 <- predict(fit.loaded, newdata = dtrain2, predleaf = TRUE)
> dim(x)
[1] 5000 6378
> dim(x2)
[1] 5000 6381

ال 33 كومينتر

لا ينبغي أن يكون هناك أي خطأ في التقريب لكل من النظام الثنائي أو json. هل تستخدم دارت؟

لا لست:

params <- list(objective = 'reg:squarederror',
               max_depth = 10, eta = 0.02, subsammple = 0.5,
               base_score = median(xgboost::getinfo(xgb.train, 'label'))
)

xgboost::xgb.train(
  params = params, data = xgb.train,
  watchlist = list('train' = xgb.train, 'test' = xgb.test),
  nrounds = 10000, verbose = TRUE, print_every_n = 25,
  eval_metric = 'mae',
  early_stopping_rounds = 3, maximize = FALSE)

هل يمكنك تزويدنا ببيانات وهمية حيث تحدث هذه الظاهرة؟

ها أنت ذا (سريع وقذر):

N <- 100000
set.seed(2020)
X <- data.frame('X1' = rnorm(N), 'X2' = runif(N), 'X3' = rpois(N, lambda = 1))
Y <- with(X, X1 + X2 - X3 + X1*X2^2 - ifelse(X1 > 0, 2, X3))

params <- list(objective = 'reg:squarederror',
               max_depth = 5, eta = 0.02, subsammple = 0.5,
               base_score = median(Y)
)

dtrain <- xgboost::xgb.DMatrix(data = data.matrix(X), label = Y)

fit <- xgboost::xgb.train(
  params = params, data = dtrain,
  watchlist = list('train' = dtrain),
  nrounds = 10000, verbose = TRUE, print_every_n = 25,
  eval_metric = 'mae',
  early_stopping_rounds = 3, maximize = FALSE
)

pred <- stats::predict(fit, newdata = dtrain)

xgboost::xgb.save(fit, 'booster.raw')
fit.loaded <- xgboost::xgb.load('booster.raw')

pred.loaded <- stats::predict(fit.loaded, newdata = dtrain)

identical(pred, pred.loaded)
pred[1:10]
pred.loaded[1:10]

sqrt(mean((Y - pred)^2))
sqrt(mean((Y - pred.loaded)^2))

على جهازي ، identical(pred, pred.loaded) هو FALSE (أي يجب أن يكون TRUE). هنا هو إخراج آخر الأوامر:

> identical(pred, pred.loaded)
[1] FALSE
> pred[1:10]
 [1] -4.7971768 -2.5070562 -0.8889422 -4.9199696 -4.4374819 -0.2739395 -0.9825708  0.4579227  1.3667605 -4.3333349
> pred.loaded[1:10]
 [1] -4.7971768 -2.5070562 -0.8889424 -4.9199696 -4.4373770 -0.2739397 -0.9825710  0.4579227  1.3667605 -4.3333349
> 
> sqrt(mean((Y - pred)^2))
[1] 0.02890702
> sqrt(mean((Y - pred.loaded)^2))
[1] 0.02890565

ترى أن التوقعات تختلف في بعض الأحيان قليلاً. هل يمكنك إعادة تشغيل رمز المثال على جهازك ومعرفة ما إذا كان لديه نفس المشكلة؟

بعض المعلومات الإضافية حول R و xgboost:

> sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] compiler_3.6.1    magrittr_1.5      Matrix_1.2-17     tools_3.6.1       yaml_2.2.0        xgboost_0.90.0.2  stringi_1.4.3     grid_3.6.1       
 [9] data.table_1.12.4 lattice_0.20-38 

لاحظ أيضًا أن:

> identical(fit$raw, fit.loaded$raw)
[1] TRUE

شكرا على السيناريو. مجرد تحديث ، قمت بتشغيله مع كل من الحفظ في ملف json و binary مع:

xgboost::xgb.save(fit, 'booster.json')
fit.loaded <- xgboost::xgb.load('booster.json')

xgboost::xgb.save(fit.loaded, 'booster-1.json')

قيم التجزئة (via sha256sum ./booster.json ) من booster.json و booster-1.json هي نفسها تمامًا ، لذا فإن تخميني هو في مكان ما يوجد به تباين ناتج عن حساب الفاصلة العائمة.

لماذا نغلق القضية دون معرفة السبب؟

trivialfis هل حصلت على True مقابل identical(pred, pred.loaded) ؟ يسأل OP لماذا لا تتطابق التنبؤات ، على الرغم من أن نموذجين لهما نفس التوقيع الثنائي.

سأحاول إعادة إنتاجه بنفسي.

أه آسف. السبب الذي وجدته هو ذاكرة التخزين المؤقت للتنبؤ. بعد تحميل النموذج ، تأتي قيم التنبؤ من التنبؤ الحقيقي ، بدلاً من القيمة المخزنة مؤقتًا:

لذا فإن تخميني يوجد في مكان ما هناك تناقض ناتج عن حساب الفاصلة العائمة.

إذن ، ذاكرة التخزين المؤقت للتنبؤ تتفاعل مع حساب الفاصلة العائمة بطريقة مدمرة؟

@ hcho3 إنها مشكلة وجدتها أثناء تطبيق طريقة التخليل الجديدة. أعتقد أنه يلعب دورًا رئيسيًا هنا. لذلك قم أولاً بتقليل عدد الأشجار إلى 1000 (والذي لا يزال ضخمًا جدًا ويجب أن يكون كافيًا للعرض التوضيحي).

أعد بناء DMatrix قبل التنبؤ لإخراج ذاكرة التخزين المؤقت من الطريق:

dtrain_2 <- xgboost::xgb.DMatrix(data = data.matrix(X), label = Y)

pred <- stats::predict(fit, newdata = dtrain_2)

سوف يجتاز الاختبار identical . وإلا فإنه يفشل.

الحصول على المزيد من الأشجار لا يزال الاختبار المماثل به اختلافات صغيرة (1e-7 لـ 2000 شجرة). ولكن هل نحتاج إلى إنتاج نتيجة متطابقة شيئًا فشيئًا حتى في بيئة متعددة الخيوط؟

نظرًا لأن تجميع النقطة العائمة ليس ترابطيًا ، فيمكننا جعله عنصرًا مهمًا للحصول على ضمان قوي لترتيب الحساب ، إذا كان ذلك مطلوبًا.

في الواقع ، لن ينجح تقديم ضمان قوي للطلب (سيساعد كثيرًا ولكن لا يزال هناك تناقض). يمكن أن يكون للنقطة العائمة في سجل وحدة المعالجة المركزية FPU دقة أعلى ثم يتم تخزينها مرة أخرى في الذاكرة. (يمكن أن يستخدم تنفيذ الأجهزة دقة أعلى لقيم الوسائط ، https://en.wikipedia.org/wiki/Extended_precision). نقطتي هي أنه عندما تكون نتيجة 1000 شجرة قابلة للتكرار تمامًا ضمن تعويم 32 بت ، فمن غير المحتمل وجود خطأ في البرمجة.

أوافق على أن مجموع النقطة العائمة ليس ترابطيًا. سأقوم بتشغيل البرنامج النصي بنفسي وأرى ما إذا كان الفرق صغيرًا بما يكفي ليعزوه إلى حساب الفاصلة العائمة.

بشكل عام ، عادةً ما أستخدم np.testing.assert_almost_equal مع decimal=5 لاختبار ما إذا كانت مصفوفتان عائمتان متساويتان تقريبًا مع بعضهما البعض.

نعم. نعتذر عن الإغلاق بدون ملاحظات مفصلة.

@ hcho3 أي تحديث؟

أنا لم ألتف حوله حتى الآن. اسمحوا لي أن ألقي نظرة هذا الأسبوع.

trivialfis تمكنت من إعادة إنتاج الخطأ. قمت بتشغيل النص المقدم وحصلت على FALSE مقابل identical(pred, pred.loaded) . حاولت إنشاء DMatrix جديد dtrain_2 كما اقترحت وما زلت أحصل على FALSE للاختبار.

الإخراج من نصDavorJ :

[1] FALSE     # identical(pred, pred.loaded)
 [1] -4.7760534 -2.5083885 -0.8860036 -4.9163256 -4.4455137 -0.2548684
 [7] -0.9745615  0.4646015  1.3602829 -4.3288369     # pred[1:10]
 [1] -4.7760534 -2.5083888 -0.8860038 -4.9163256 -4.4454765 -0.2548686
 [7] -0.9745617  0.4646015  1.3602829 -4.3288369     # pred.loaded[1:10]
[1] 0.02456085   # MSE on pred
[1] 0.02455945   # MSE on pred.loaded

الإخراج من برنامج نصي معدل ، بـ dtrain_2 <- xgboost::xgb.DMatrix(data = data.matrix(X), label = Y) :

[1] FALSE     # identical(pred, pred.loaded)
 [1] -4.7760534 -2.5083885 -0.8860036 -4.9163256 -4.4455137 -0.2548684
 [7] -0.9745615  0.4646015  1.3602829 -4.3288369     # pred[1:10]
 [1] -4.7760534 -2.5083888 -0.8860038 -4.9163256 -4.4454765 -0.2548686
 [7] -0.9745617  0.4646015  1.3602829 -4.3288369     # pred.loaded[1:10]
[1] 0.02456085   # MSE on pred
[1] 0.02455945   # MSE on pred.loaded

لذلك يجب أن يحدث شيء آخر.

حاولت أيضًا إجراء اختبار ذهابًا وإيابًا:

xgboost::xgb.save(fit, 'booster.raw')
fit.loaded <- xgboost::xgb.load('booster.raw')
xgboost::xgb.save(fit.loaded, 'booster.raw.roundtrip')

وكان الملفان الثنائيان booster.raw و booster.raw.roundtrip متطابقين.

أقصى فرق بين pred و pred.loaded هي 0.0008370876.

مثال أصغر يعمل بشكل أسرع:

library(xgboost)

N <- 5000
set.seed(2020)
X <- data.frame('X1' = rnorm(N), 'X2' = runif(N), 'X3' = rpois(N, lambda = 1))
Y <- with(X, X1 + X2 - X3 + X1*X2^2 - ifelse(X1 > 0, 2, X3))

params <- list(objective = 'reg:squarederror',
               max_depth = 5, eta = 0.02, subsammple = 0.5,
               base_score = median(Y)
)

dtrain <- xgboost::xgb.DMatrix(data = data.matrix(X), label = Y)

fit <- xgboost::xgb.train(
  params = params, data = dtrain,
  watchlist = list('train' = dtrain),
  nrounds = 10000, verbose = TRUE, print_every_n = 25,
  eval_metric = 'mae',
  early_stopping_rounds = 3, maximize = FALSE
)

pred <- stats::predict(fit, newdata = dtrain)

invisible(xgboost::xgb.save(fit, 'booster.raw'))
fit.loaded <- xgboost::xgb.load('booster.raw')
invisible(xgboost::xgb.save(fit.loaded, 'booster.raw.roundtrip'))

pred.loaded <- stats::predict(fit.loaded, newdata = dtrain)

identical(pred, pred.loaded)
pred[1:10]
pred.loaded[1:10]
max(abs(pred - pred.loaded))

sqrt(mean((Y - pred)^2))
sqrt(mean((Y - pred.loaded)^2))

انتاج:

[1] FALSE
 [1] -2.4875379 -0.9452241 -6.9658904 -2.9985323 -4.2192593 -0.8505422
 [7] -0.3928839 -1.6886091 -1.3611379 -3.1278882
 [1] -2.4875379 -0.9452239 -6.9658904 -2.9985323 -4.2192593 -0.8505420
 [7] -0.3928837 -1.6886090 -1.3611377 -3.1278882
[1] 0.0001592636
[1] 0.01370754
[1] 0.01370706

لقد حاولت للتو القيام برحلة إضافية ذهابًا وإيابًا ، والآن لا تتغير التوقعات بعد الآن.

library(xgboost)

N <- 5000
set.seed(2020)
X <- data.frame('X1' = rnorm(N), 'X2' = runif(N), 'X3' = rpois(N, lambda = 1))
Y <- with(X, X1 + X2 - X3 + X1*X2^2 - ifelse(X1 > 0, 2, X3))

params <- list(objective = 'reg:squarederror',
               max_depth = 5, eta = 0.02, subsammple = 0.5,
               base_score = median(Y)
)

dtrain <- xgboost::xgb.DMatrix(data = data.matrix(X), label = Y)

fit <- xgboost::xgb.train(
  params = params, data = dtrain,
  watchlist = list('train' = dtrain),
  nrounds = 10000, verbose = TRUE, print_every_n = 25,
  eval_metric = 'mae',
  early_stopping_rounds = 3, maximize = FALSE
)

pred <- stats::predict(fit, newdata = dtrain)

invisible(xgboost::xgb.save(fit, 'booster.raw'))
fit.loaded <- xgboost::xgb.load('booster.raw')
invisible(xgboost::xgb.save(fit.loaded, 'booster.raw.roundtrip'))
fit.loaded2 <- xgboost::xgb.load('booster.raw.roundtrip')

pred.loaded <- stats::predict(fit.loaded, newdata = dtrain)
pred.loaded2 <- stats::predict(fit.loaded2, newdata = dtrain)

identical(pred, pred.loaded)
identical(pred.loaded, pred.loaded2)
pred[1:10]
pred.loaded[1:10]
pred.loaded2[1:10]
max(abs(pred - pred.loaded))
max(abs(pred.loaded - pred.loaded2))

sqrt(mean((Y - pred)^2))
sqrt(mean((Y - pred.loaded)^2))
sqrt(mean((Y - pred.loaded2)^2))

نتيجة:

[1] FALSE
[1] TRUE
 [1] -2.4875379 -0.9452241 -6.9658904 -2.9985323 -4.2192593 -0.8505422
 [7] -0.3928839 -1.6886091 -1.3611379 -3.1278882
 [1] -2.4875379 -0.9452239 -6.9658904 -2.9985323 -4.2192593 -0.8505420
 [7] -0.3928837 -1.6886090 -1.3611377 -3.1278882
 [1] -2.4875379 -0.9452239 -6.9658904 -2.9985323 -4.2192593 -0.8505420
 [7] -0.3928837 -1.6886090 -1.3611377 -3.1278882
[1] 0.0001592636
[1] 0
[1] 0.01370754
[1] 0.01370706
[1] 0.01370706

لذلك ربما تكون ذاكرة التخزين المؤقت للتنبؤ مشكلة بالفعل.

أعدت تشغيل النص مع تعطيل التخزين المؤقت للتنبؤات:

diff --git a/src/predictor/cpu_predictor.cc b/src/predictor/cpu_predictor.cc
index ebc15128..c40309bc 100644
--- a/src/predictor/cpu_predictor.cc
+++ b/src/predictor/cpu_predictor.cc
@@ -259,7 +259,7 @@ class CPUPredictor : public Predictor {
     // delta means {size of forest} * {number of newly accumulated layers}
     uint32_t delta = end_version - beg_version;
     CHECK_LE(delta, model.trees.size());
-    predts->Update(delta);
+    //predts->Update(delta);

     CHECK(out_preds->Size() == output_groups * dmat->Info().num_row_ ||
           out_preds->Size() == dmat->Info().num_row_);

(يؤدي تعطيل التخزين المؤقت للتنبؤ إلى تدريب بطيء جدًا.)

انتاج:

[1] FALSE
[1] TRUE
 [1] -2.4908853 -0.9507379 -6.9615889 -2.9935317 -4.2165089 -0.8543566
 [7] -0.3940181 -1.6930715 -1.3572118 -3.1403396
 [1] -2.4908853 -0.9507380 -6.9615889 -2.9935317 -4.2165089 -0.8543567
 [7] -0.3940183 -1.6930716 -1.3572119 -3.1403399
 [1] -2.4908853 -0.9507380 -6.9615889 -2.9935317 -4.2165089 -0.8543567
 [7] -0.3940183 -1.6930716 -1.3572119 -3.1403399
[1] 0.0001471043
[1] 0
[1] 0.01284297
[1] 0.01284252
[1] 0.01284252

لذا فإن ذاكرة التخزين المؤقت للتنبؤ ليست بالتأكيد سبب هذا الخطأ.

تتباعد توقعات الأوراق أيضًا:

invisible(xgboost::xgb.save(fit, 'booster.raw'))
fit.loaded <- xgboost::xgb.load('booster.raw')
invisible(xgboost::xgb.save(fit.loaded, 'booster.raw.roundtrip'))
fit.loaded2 <- xgboost::xgb.load('booster.raw.roundtrip')

x <- predict(fit, newdata = dtrain2, predleaf = TRUE)
x2 <- predict(fit.loaded, newdata = dtrain2, predleaf = TRUE)
x3 <- predict(fit.loaded2, newdata = dtrain2, predleaf = TRUE)

identical(x, x2)
identical(x2, x3)

انتاج:

[1] FALSE
[1] TRUE

حل اللغز. لقد حددت السبب الحقيقي. عندما يتم حفظ النموذج على القرص ، يتم تجاهل المعلومات الخاصة بالإيقاف المبكر. في المثال ، يقوم XGBoost بتشغيل 6381 جولة تعزيز وإيجاد أفضل طراز في 6378 طلقة. يحتوي كائن النموذج الموجود في الذاكرة على 6381 شجرة ، وليس 6378 شجرة ، نظرًا لعدم إزالة أي شجرة. يوجد حقل إضافي best_iteration يتذكر التكرار الأفضل:

> fit$best_iteration
[1] 6378

يتم تجاهل هذا الحقل الإضافي بصمت عندما نحفظ النموذج على القرص. لذلك يستخدم predict() بالنموذج الأصلي 6378 شجرة ، بينما يستخدم predict() مع النموذج المستعاد 6381 شجرة.

> x <- predict(fit, newdata = dtrain2, predleaf = TRUE)
> x2 <- predict(fit.loaded, newdata = dtrain2, predleaf = TRUE)
> dim(x)
[1] 5000 6378
> dim(x2)
[1] 5000 6381

trivialfis أميل إلى إزالة الأشجار جسديًا. إذا توقف التدريب عند 6381 جولة وكان أفضل تكرار عند 6378 جولة ، فسوف يتوقع المستخدمون أن يحتوي النموذج النهائي على 6378 شجرة.

@ hcho3 أعتقد أنها مشكلة مماثلة في https://github.com/dmlc/xgboost/issues/4052 .

يجب حفظ bset_iteration في Learner::attributes_ ، والذي يمكن الوصول إليه من خلال xgboost::xgb.attr .

@ hcho3 ، تجد لطيفة!

لاحظ أيضًا وثائق xgboost:::predict.xgb.Booster() :

image

إذا فهمت بشكل صحيح ، فالتوثيق ليس صحيحًا تمامًا؟ بناءً على الوثائق ، كنت أتوقع أن التنبؤ قد استخدم بالفعل جميع الأشجار. لسوء الحظ لم أقم بالتحقق من هذا.

DavorJ عند تنشيط التوقف المبكر، predict() سوف تستخدم best_iteration المجال للحصول على التنبؤ.

trivialfis الوضع أسوأ من جانب Python ، حيث لن يستخدم xgb.predict() معلومات من التوقف المبكر على الإطلاق:

import xgboost as xgb
import numpy as np
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split

X, y = load_boston(return_X_y=True)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)

params = {'objective': 'reg:squarederror'}

bst = xgb.train(params, dtrain, 100, [(dtrain, 'train'), (dtest, 'test')],
                early_stopping_rounds=5)

x = bst.predict(dtrain, pred_leaf=True)
x2 = bst.predict(dtrain, pred_leaf=True, ntree_limit=bst.best_iteration)
print(x.shape)
print(x2.shape)

pred = bst.predict(dtrain)
pred2 = bst.predict(dtrain, ntree_limit=bst.best_iteration)

print(np.max(np.abs(pred - pred2)))

انتاج:

Will train until test-rmse hasn't improved in 5 rounds.
[1]     train-rmse:12.50316     test-rmse:11.92709
...
[25]    train-rmse:0.56720      test-rmse:2.56874
[26]    train-rmse:0.54151      test-rmse:2.56722
[27]    train-rmse:0.51842      test-rmse:2.56124
[28]    train-rmse:0.47489      test-rmse:2.56640
[29]    train-rmse:0.45489      test-rmse:2.58780
[30]    train-rmse:0.43093      test-rmse:2.59385
[31]    train-rmse:0.41865      test-rmse:2.59364
[32]    train-rmse:0.40823      test-rmse:2.59465
Stopping. Best iteration:
[27]    train-rmse:0.51842      test-rmse:2.56124
(404, 33)
(404, 27)
0.81269073

سيتعين على المستخدمين تذكر إحضار bst.best_iteration وتمريرها على أنها وسيطة ntree_limit عند استدعاء predict() . هذا عرضة للخطأ ويحدث مفاجأة غير سارة.

لدينا خياران للإصلاح:

  1. احذف الأشجار التي تجاوزت best_iteration .
  2. احتفظ بالمعلومات best_iteration عند تسلسل النموذج ، واستخدم الدالة predict() .

@ hcho3 لدي فكرة نصف مخبوزة حول هذا الأمر ، والتي ترتبط أيضًا process_type = update ، والغابة.

خلفية

لتلخيص قصير للمشكلات التي نواجهها مع update ، إذا كان num_boost_round المستخدم مع update أقل من عدد الأشجار الموجودة بالفعل ، فستتم إزالة تلك الأشجار التي لم يتم تحديثها .

للحصول على مقدمة موجزة عن مشكلات الغابة ، لا ينطبق best_iteration على الغابة لأن الوظيفة predict تتطلب عددًا محددًا من الأشجار بدلاً من التكرار ، لذلك في Python هناك شيء يسمى best_ntree_limit ، وهو أمر محير للغاية بالنسبة لي. لقد استبدلت صراحة ntree_limit في inplace_predict بـ iteration_range لتجنب هذه السمة.

فكرة

أريد إضافة طريقة slice وطريقة concat إلى booster ، والتي تستخرج الأشجار إلى نموذجين وتسلسل الأشجار من نموذجين إلى 1. إذا كان لدينا هاتان الطريقتان :

  • لم تعد هناك حاجة إلى base_margin_ وأعتقد أنه أكثر سهولة للمستخدمين الآخرين.
  • لم تعد هناك حاجة للتنبؤ ntree_limit ، نقوم فقط بتقسيم النموذج وتشغيل التنبؤ على الشرائح.
  • update بذاتها ، فقط قم بتحديث الأشجار في الشرائح دفعة واحدة ، لا num_boost_rounds .

بالإضافة إلى ذلك

كما أنني أعتقد أن هذا مرتبط بطريقة ما بأشجار متعددة الأهداف. كما لو كان بإمكاننا دعم الأشجار متعددة الفئات متعددة الأهداف في المستقبل ، ستكون هناك طرق متعددة لترتيب الأشجار ، مثل استخدام output_groups لكل فئة ، أو كل هدف ، مع الاقتران بأوراق الغابة والمتجهة. ntree_limit كافيًا.

أيضا # 5531.

لكن الفكرة ما زالت مبكرة جدًا ، لذا لم يكن لدي الثقة لمشاركتها ، والآن نحن بصدد هذه القضية ، ربما يمكنني الحصول على بعض المدخلات حول هذا الموضوع.

بالنظر إلى الجدول الزمني 1.1 ، هل يمكننا توسيع الوثائق لتوضيح كيف يحتاج المستخدمون إلى التقاط واستخدام هذا التكرار الأفضل يدويًا في التنبؤ؟
وإضافته إلى المشكلات المعروفة في ملاحظات الإصدار؟

يبدو trivialfis مثيرًا للاهتمام ، طالما أننا لا

يعد حذف الأشجار الإضافية من النموذج كما هو مقترح من قبل @ hcho3 أمرًا جذابًا حيث لا يتعين علينا التعامل مع أي تناقضات

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات