كنت أقوم بتجربة بناء مجموعة XGBoost التدريجي بخطوة واحدة. عندما يتم إنشاء Booster بواسطة وظيفة xgboost.train ( مكتبة python ) ، يبدو أن كل شيء يعمل بشكل جيد.
ومع ذلك ، عندما أقوم بإنشاء المعزز وتحديثه باستخدام Booster.update مثل هذا:
"" الثعبان
booster_ = xgboost.Booster ({'target': 'reg: linear'})
Booster_.update (dtrain، 1)
the python process fails with a segmentation fault.
## Environment info
Operating System:
* **python 3.6** Mac OS X 10.10.5 (Darwin 14.5.0), Ubuntu 14.04.5 LTS (GNU/Linux 3.19.0-25-generic x86_64);
* **python 2.7** Mac OS X 10.10.6 (Darwin 15.6.0);
Compiler:
* **python 3.6** used `pip install xgboost`;
* **python 2.7** gcc (6.3.0 --without-multilib);
`xgboost` version used:
* **python 3.6** version 0.6 from pip;
* **python 2.7.13** git HEAD 4a63f4ab43480adaaf13bde2485d5bfedd952520;
## Steps to reproduce
```python
import xgboost
dtrain = xgboost.DMatrix(data=[[-1.0], [0.0], [1.0]], label=[0.0, -1.0, 1.0])
booster_ = xgboost.Booster({'objective': 'reg:linear', 'max_depth': 1})
booster_.update(dtrain, 1)
booster_.update(dtrain, 1)
السطر الأخير يسبب خطأ تجزئة. أرفق تقرير تعطل بيثون 2.7.13
أود أن أوضح ما أتوقعه من إجراء تحديثات إضافية لكائن Booster الفارغ الذي تم إرجاعه بواسطة
booster_ = xgboost.Booster({'objective': 'reg:linear', 'max_depth': 1})
وفقًا لخوارزمية تعزيز التدرج العام ، توقعت أنه بعد التحديث على عينة (X ، y) في DMatrix dtrain
مع
booster_.update(dtrain, 1)
المعزز الفارغ سيصبح إما f_0(x)
- التنبؤ الثابت ، أو f_1(x)
- التنبؤ بعد خطوة واحدة من تعزيز التدرج ، كما هو موضح أدناه (من Hastie ، Tibshirani ، Friedman ؛ 2013 الطبعة العاشرة الصفحة 361).
تمكنت من تتبع المشكلة وصولاً إلى متجه فارغ RegTree::FVec.data
في hte قدم مثالاً مستنسخًا. التتبع (اليدوي) للمكالمة الثانية إلى booster_.update
كما يلي:
this->UpdateOneIter(...);
this->PredictRaw(train, &preds_);
gbm_->Predict(data, out_preds, ntree_limit=0);
PredLoopInternal<GBTree>(p_fmat, out_preds, 0, ntree_limit, true);
PredValue(inst, gid, info.GetRoot(ridx), &feats, tree_begin, tree_end);
int tid = trees[i]->GetLeafIndex(*p_feats, root_index);
فشل هنا:
include / xgboost / tree_model.h: # L528
..., feat.fvalue(split_index), feat.is_missing(split_index), ...
يبدو أن feat.data.size() == 0
. لا أعرف لماذا بعد المكالمة الأولى إلى .update()
هذا المتجه لا يزال فارغًا ، لكنه غير فارغ بعد الاستدعاء البديل لـ .train()
.
لقد اكتشفت أصل المشكلة. اتضح أن إنشاء معزز فارغ عن طريق الاتصال
booster_ = xgboost.Booster({'objective': 'reg:linear'})
يقوم بتهيئة معزز GBTree جزئيًا فقط. على وجه الخصوص ، المعلمة الحاسمة num_feature
تم تعيينه افتراضيًا على 0 ولا يتم تحديثه إلى عدد مناسب من الميزات من خلال مكالمة لاحقة .update()
.
ومع ذلك ، فإن تمرير قيمة صريحة لـ num_feature
يحل خطأ التقسيم:
booster_ = xgboost.Booster({'objective': 'reg:linear', 'num_feature': dtrain.num_col()})
أعتقد أن xgboost.Booster()
يجب أن يصدر تحذيرًا إذا كان cache=()
فارغًا ، أو
لم يتم تعيين 'num_feature'
بشكل صريح في الوسيطة params
.
التعليق الأكثر فائدة
لقد اكتشفت أصل المشكلة. اتضح أن إنشاء معزز فارغ عن طريق الاتصال
يقوم بتهيئة معزز GBTree جزئيًا فقط. على وجه الخصوص ، المعلمة الحاسمة
num_feature
تم تعيينه افتراضيًا على 0 ولا يتم تحديثه إلى عدد مناسب من الميزات من خلال مكالمة لاحقة
.update()
.ومع ذلك ، فإن تمرير قيمة صريحة لـ
num_feature
يحل خطأ التقسيم:أعتقد أن
xgboost.Booster()
يجب أن يصدر تحذيرًا إذا كانcache=()
فارغًا ، أولم يتم تعيين
'num_feature'
بشكل صريح في الوسيطةparams
.