مرحبًا ، أنا مؤلف Dask ، مكتبة للحوسبة المتوازية والموزعة في Python. لدي فضول لمعرفة ما إذا كان هناك اهتمام داخل هذا المجتمع للتعاون في توزيع XGBoost على Dask إما للتدريب الموازي أو من أجل ETL.
من المحتمل أن يكون هناك مكونان من Dask مناسبين لهذا المشروع:
هل هناك اهتمام بالتعاون هنا؟
mrocklin اعتقدت أن Dask لديها تكامل مع sklearn. هل ألقيت نظرة على غلاف sklearn لمعرفة ما إذا كان سيعمل مع ذلك؟
يجب أن يتم التكامل بشكل هادف مع نظام موزع على مستوى كل خوارزمية بدلاً من مستوى المكتبة. هناك بعض الطرق التي يمكن من خلالها لـ SKLearn و Dask مساعدة بعضهما البعض ، نعم ، لكنها ليست عميقة بشكل خاص.
سيكون Dask dataframe بداية جيدة. في قاعدة الكود لدينا ، لدينا فحص لإطار بيانات الباندا. قد يكون هذا هو المكان الذي يناسب dask dataframe كبداية.
إذن ماذا يحدث إذا وصل شخص ما بإطار بيانات dask متعدد تيرابايت؟ هل تقوم فقط بتحويله إلى Pandas والمضي قدمًا؟ أو هل هناك طريقة لموازنة XGBoost بذكاء عبر مجموعة ، مما يشير إلى إطارات بيانات الباندا المختلفة التي تشكل إطار بيانات dask؟
يمكن للمستخدمين تحديد حجم الدفعة؟ أتخيل أنه يمكن استفادة المستخدمين من خلال ميزة التهيئة الجزئية.
cctqchen الذي هو أكثر دراية بالجزء الموزع من الكود.
يمكن ربط النسخة الموزعة من xgboost بقاذفة الوظائف الموزعة ، ومن الأفضل الحصول على تغذية قسم البيانات في xgboost ثم المتابعة.
mrocklin أعتقد أن الجزء الأكثر صلة هو الوحدة النمطية xgboost-spark و xgboost-flink ، والتي تقوم بتضمين xgboost في وظيفة mapPartition الخاصة بـ spark / flink. أعتقد أنه سيكون هناك شيء مشابه في داسك
الشرط من جانب xgboost هو أن XGBoost يتعامل مع اتصال العملية البينية عن طريق rabit ، وسيحتاج إلى بدء تعقب (يربط كل وظيفة) من جانب العميل.
انظر التعليمات البرمجية ذات الصلة في https://github.com/dmlc/xgboost/blob/master/jvm-packages/xgboost4j-spark/src/main/scala/ml/dmlc/xgboost4j/scala/spark/XGBoost.scala#L112
تم تصميم Rabit ليتم تضمينه في نظام موزع آخر ، لذلك أعتقد أنه قد لا يكون من الصعب جدًا إجراء التعديل في جانب الثعبان.
عادةً ما يكون إطلاق أنظمة موزعة أخرى من Dask ممكنًا جدًا. كيف تقوم بنقل البيانات من نظام الاستضافة الموزع (سبارك / فلنك / داسك) إلى إكس جي-بوست؟ أم أن هذا للتدريب الموزع على البيانات الصغيرة؟
بشكل ملموس ، أتوقع بناء نظام على النحو التالي:
هل يتوافق هذا مع توقعاتك؟ هل من السهل عليك توجيهي إلى Python API ذات الصلة؟
نعم ، راجع المعلومات ذات الصلة هنا https://github.com/dmlc/xgboost/blob/master/tests/distributed/ لواجهة برمجة تطبيقات python.
ما ستحتاج إلى القيام به بالإضافة إلى ذلك هو بدء متعقب rabit من جانب السائق (من المحتمل أن يكون المكان الذي يقود dask) ، ويتم ذلك في البرنامج النصي dmlc-submit هنا https://github.com/dmlc/dmlc-core / tree / master / tracker / dmlc_tracker
حسنًا ، أكمل المخطط التفصيلي الخاص بي من قبل:
في عقدة برنامج التشغيل / المجدول ، نبدأ أداة تعقب rabit
envs = {'DMLC_NUM_WORKER' : nworker,
'DMLC_NUM_SERVER' : nserver}
rabit = RabitTracker(hostIP=ip_address, nslave=num_workers)
envs.update(rabit.slave_envs())
rabit.start(args.num_workers) # manages connections in background thread
قد أخوض أيضًا في عملية مماثلة لبدء PSTracker
. هل يجب أن يكون هذا على نفس الجهاز المركزي أم يجب أن يكون في مكان آخر داخل الشبكة؟ هل يجب أن يكون هناك القليل من هؤلاء؟ هل يجب أن يكون هذا قابلًا للتكوين بواسطة المستخدم؟
في النهاية لدي متتبع (و pstrackers؟) ينضم إلى شبكة rabit والحظر.
rabit.join() # join network
في العقد العاملة ، أحتاج إلى تفريغ متغيرات البيئة هذه (التي سأنتقل إليها عبر قنوات dask العادية) في البيئة المحلية. ثم مجرد استدعاء xgboost.rabit.init()
يجب أن يكون كافياً
import os
os.environ.update(envs)
xgboost.rabit.init()
بالنظر إلى كود Rabit ، يبدو أن متغيرات البيئة هي الطريقة الوحيدة لتوفير هذه المعلومات. هل يمكنك التحقق من هذا؟ هل هناك طريقة لتوفير معلومات مضيف / منفذ تعقب كمدخلات مباشرة؟
ثم أقوم بتحويل المصفوفات المتناثرة / إطارات بيانات الباندا / المصفوفات المتناثرة إلى كائنات DMatrix ، وهذا يبدو واضحًا نسبيًا. ومع ذلك ، من المحتمل أن يكون لدي عدة دفعات من البيانات لكل عامل. هل هناك طريقة نظيفة للاتصال بالقطار عدة مرات بمزيد من البيانات عندما تصبح متاحة؟ أنا قلق بشأن التعليقات على هذه السطور:
# Run training, all the features in training API is available.
# Currently, this script only support calling train once for fault recovery purpose.
bst = xgb.train(param, dtrain, num_round, watchlist, early_stopping_rounds=2)
هل نحتاج إلى انتظار وصول جميع البيانات قبل بدء التدريب؟
إذا افترضنا أن كل شيء أعلاه صحيح ، فهل هناك مثال تدريب معياري موزع يستخدمه الناس في العرض التوضيحي؟
ليست هناك حاجة لبدء pstracker.
كان لدي بعض الوقت للعب مع هذا الصباح. النتائج هنا: https://github.com/mrocklin/dask-xgboost
حتى الآن ، يتعامل فقط مع التعلم الموزع لمجموعة بيانات واحدة في الذاكرة. نشأت بعض الأسئلة:
rabit.init
؟ ما هو شكل المدخلات المتوقع تحديدًا لـ rabit.init
؟ من الواضح أن تمرير نتيجة slave_envs()
إلى rabit.init لن ينجح لأنه يتوقع قائمة. هل يجب علينا تحويل كل اسم مفتاح إلى --key
، ربما بإسقاط البادئة DMLC
والتحويل إلى أحرف صغيرة؟rabit.init(['DMLC_KEY1=VALUE1', 'DMLC_KEY2=VALUE2']
سؤالان آخران بشكل عام حول كيفية استخدام هذا (ليس لدي خبرة مع XGBoost ولدي خبرة قليلة فقط في التعلم الآلي ، يرجى مسامحة جهلي).
ما هي حالة الاستخدام الأكثر شيوعًا؟
يجب أن يعمل كل عمل على قسم مختلف من البيانات (حسب الصفوف) ، ويجب ألا ينظروا إلى بيانات الإدخال نفسها.
هذا يتوافق عادةً مع عملية mapPartition في أطر مثل spark / flink
لنفترض أن مجموعة البيانات الخاصة بي تحتوي على 8 صفوف ، 4 أعمدة ، إذا بدأنا عاملين
حسنًا ، ما يوجد الآن هو أنظف قليلاً. سيكون من الرائع لو كانت لدينا بعض القدرة على استهلاك النتائج كما تم إنشاؤها على كل عامل ، لكننا عملنا على حلها في الوقت الحالي. ها هو الحل الحالي:
يبدو أن هذا الحل يمكن إدارته ، لكنه ليس مثاليًا. سيكون من الملائم أن تقبل xgboost-python النتائج فور وصولها. ومع ذلك ، أعتقد أن الشيء التالي الذي يجب فعله هو تجربته في الممارسة العملية.
سأبحث حول الإنترنت للحصول على أمثلة. إذا كان لدى أي شخص مشكلة مصطنعة يمكنني إنشاؤها بسهولة باستخدام واجهة برمجة تطبيقات numpy أو pandas التي ستكون موضع ترحيب. حتى ذلك الحين ، إليك مثال تافه على جهاز الكمبيوتر المحمول الخاص بي ببيانات عشوائية:
In [1]: import dask.dataframe as dd
In [2]: df = dd.demo.make_timeseries('2000', '2001', {'x': float, 'y': float, 'z': int}, freq='1s', partition_freq=
...: '1D') # some random time series data
In [3]: df.head()
Out[3]:
x y z
2000-01-01 00:00:00 0.778864 0.824796 977
2000-01-01 00:00:01 -0.019888 -0.173454 1023
2000-01-01 00:00:02 0.552826 0.051995 1083
2000-01-01 00:00:03 -0.761811 0.780124 959
2000-01-01 00:00:04 -0.643525 0.679375 980
In [4]: labels = df.z > 1000
In [5]: del df['z']
In [6]: df.head()
Out[6]:
x y
2000-01-01 00:00:00 0.778864 0.824796
2000-01-01 00:00:01 -0.019888 -0.173454
2000-01-01 00:00:02 0.552826 0.051995
2000-01-01 00:00:03 -0.761811 0.780124
2000-01-01 00:00:04 -0.643525 0.679375
In [7]: labels.head()
Out[7]:
2000-01-01 00:00:00 False
2000-01-01 00:00:01 True
2000-01-01 00:00:02 True
2000-01-01 00:00:03 False
2000-01-01 00:00:04 False
Name: z, dtype: bool
In [8]: from dask.distributed import Client
In [9]: c = Client() # creates a local "cluster" on my laptop
In [10]: from dask_xgboost import train
/home/mrocklin/Software/anaconda/lib/python3.5/site-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
"This module will be removed in 0.20.", DeprecationWarning)
In [11]: param = {'max_depth': 2, 'eta': 1, 'silent': 1, 'objective': 'binary:logistic'} # taken from example
In [12]: bst = train(c, param, df, labels)
/home/mrocklin/Software/anaconda/lib/python3.5/site-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
"This module will be removed in 0.20.", DeprecationWarning)
/home/mrocklin/Software/anaconda/lib/python3.5/site-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
"This module will be removed in 0.20.", DeprecationWarning)
/home/mrocklin/Software/anaconda/lib/python3.5/site-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
"This module will be removed in 0.20.", DeprecationWarning)
/home/mrocklin/Software/anaconda/lib/python3.5/site-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
"This module will be removed in 0.20.", DeprecationWarning)
[14:46:20] Tree method is automatically selected to be 'approx' for faster speed. to use old behavior(exact greedy algorithm on single machine), set tree_method to 'exact'
[14:46:20] Tree method is automatically selected to be 'approx' for faster speed. to use old behavior(exact greedy algorithm on single machine), set tree_method to 'exact'
[14:46:20] Tree method is automatically selected to be 'approx' for faster speed. to use old behavior(exact greedy algorithm on single machine), set tree_method to 'exact'
[14:46:20] Tree method is automatically selected to be 'approx' for faster speed. to use old behavior(exact greedy algorithm on single machine), set tree_method to 'exact'
In [13]: bst
Out[13]: <xgboost.core.Booster at 0x7fbaacfd17b8>
الكود ذو الصلة موجود هنا إذا أراد أي شخص إلقاء نظرة: https://github.com/mrocklin/dask-xgboost/blob/master/dask_xgboost/core.py
كما قلت ، أنا جديد على XGBoost ، لذلك ربما أفتقد أشياء.
مثال لعبة نموذجي يمكنك تجربته في https://github.com/dmlc/xgboost/tree/master/demo/data
إنه بتنسيق libsvm رغم ذلك ، ويحتاج إلى القليل من التحليل لتحويله إلى numpy
أي شيء أكبر (ستحتاج بالفعل إلى كتلة)؟ أم أن هناك طريقة قياسية لإنشاء مجموعة بيانات ذات حجم عشوائي؟
أو ربما يكون السؤال الأفضل هو: "ما الذي تود (أو أي شخص آخر يقرأ هذا العدد) أن تراه هنا؟"
توقع بناء الآن. إذا قمت بنقل النموذج مرة أخرى إلى عامل (يمر بعملية pickle / unpickle) ثم اتصلت بـ bst.predict
في بعض البيانات ، فسأحصل على الخطأ التالي:
Doing rabit call after Finalize
كان افتراضي ، في هذه المرحلة ، أن النموذج قائم بذاته ولم يعد بحاجة إلى استخدام الأرانب. يبدو أنه يعمل بشكل جيد على جهاز العميل. هل لديك أية أفكار حول سبب تلقي هذا الخطأ عند الاتصال بـ predict
؟
جزء من التنبؤ لا يزال يستخدم rabit ، ويرجع ذلك أساسًا إلى أن المتنبئ لا يزال يستخدم المتعلم مع بعض إجراءات التهيئة التي يتم مشاركتها مع التدريب. في النهاية يجب إصلاح هذا ، ولكن هذا هو الحال الآن.
أعتقد أنه طالما أنها تعمل بشكل جيد لمجموعة البيانات المشتركة ، فهي نقطة انطلاق مثيرة للاهتمام.
هناك أسباب لاستخدام مجموعة للبيانات المتوسطة على أي حال (سهولة الجدولة في بيئة المجموعة) ، قد يكون بعض مستخدمي pyspark مهتمين بتجربتها إذا قمنا بالإعلان عنها قليلاً
كان الاختبار على مجموعة البيانات المهمة حقًا صعبًا ، على سبيل المثال (جرب مجموعة بيانات واحدة تحتوي على مليار صف). قد تكون Kaggle مجموعة بيانات كبيرة يمكن أن تكون ذات صلة بحوالي 10 ملايين.
يعرض هذا المستودع تجارب على مجموعة بيانات شركات الطيران ، والتي أعتقد أنها موجودة في عشرات الملايين من الصفوف وعشرات الأعمدة (ألف بعد ترميز واحد ساخن؟) بالنسبة لمعيارهم ، يبدو أنهم أخذوا عينة من 100 ألف صف وتم إنشاؤها بشكل مصطنع أكبر مجموعات البيانات من هذه العينة. من المفترض أن نتمكن من توسيع نطاق هذا إذا لزم الأمر.
فيما يلي مثال على استخدام هذه البيانات مع حيوانات الباندا و xgboost في نواة واحدة. نرحب بأي توصيات بشأن إعداد البيانات أو المعلمات أو كيفية القيام بذلك بشكل صحيح.
In [1]: import pandas as pd
In [2]: df = pd.read_csv('train-0.1m.csv')
In [3]: df.head()
Out[3]:
Month DayofMonth DayOfWeek DepTime UniqueCarrier Origin Dest Distance \
0 c-8 c-21 c-7 1934 AA ATL DFW 732
1 c-4 c-20 c-3 1548 US PIT MCO 834
2 c-9 c-2 c-5 1422 XE RDU CLE 416
3 c-11 c-25 c-6 1015 OO DEN MEM 872
4 c-10 c-7 c-6 1828 WN MDW OMA 423
dep_delayed_15min
0 N
1 N
2 N
3 N
4 Y
In [4]: labels = df.dep_delayed_15min == 'Y'
In [5]: del df['dep_delayed_15min']
In [6]: df = pd.get_dummies(df)
In [7]: len(df.columns)
Out[7]: 652
In [8]: import xgboost as xgb
/home/mrocklin/Software/anaconda/lib/python3.5/site-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
"This module will be removed in 0.20.", DeprecationWarning)
In [9]: dtrain = xgb.DMatrix(df, label=labels)
In [10]: param = {} # Are there better choices for parameters? I could use help here
In [11]: bst = xgb.train(param, dtrain) # or other parameters here?
[17:50:28] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 124 extra nodes, 0 pruned nodes, max_depth=6
[17:50:30] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 120 extra nodes, 0 pruned nodes, max_depth=6
[17:50:32] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 120 extra nodes, 0 pruned nodes, max_depth=6
[17:50:33] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 116 extra nodes, 0 pruned nodes, max_depth=6
[17:50:35] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 112 extra nodes, 0 pruned nodes, max_depth=6
[17:50:36] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 114 extra nodes, 0 pruned nodes, max_depth=6
[17:50:38] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 106 extra nodes, 0 pruned nodes, max_depth=6
[17:50:39] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 116 extra nodes, 0 pruned nodes, max_depth=6
[17:50:41] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 104 extra nodes, 0 pruned nodes, max_depth=6
[17:50:43] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 100 extra nodes, 0 pruned nodes, max_depth=6
In [12]: test = pd.read_csv('test.csv')
In [13]: test.head()
Out[13]:
Month DayofMonth DayOfWeek DepTime UniqueCarrier Origin Dest Distance \
0 c-7 c-25 c-3 615 YV MRY PHX 598
1 c-4 c-17 c-2 739 WN LAS HOU 1235
2 c-12 c-2 c-7 651 MQ GSP ORD 577
3 c-3 c-25 c-7 1614 WN BWI MHT 377
4 c-6 c-6 c-3 1505 UA ORD STL 258
dep_delayed_15min
0 N
1 N
2 N
3 N
4 Y
In [14]: test_labels = test.dep_delayed_15min == 'Y'
In [16]: del test['dep_delayed_15min']
In [17]: test = pd.get_dummies(test)
In [18]: len(test.columns) # oops, looks like the columns don't match up
Out[18]: 670
In [19]: dtest = xgb.DMatrix(test)
In [20]: predictions = bst.predict(dtest) # this fails because of mismatched columns
على أي حال ، هنا خيار. تبدو مجموعة بيانات شركات الطيران معروفة جيدًا ويمكن أن تكون كبيرة بشكل غير مريح في الممارسة العملية. مرة أخرى ، التعلم الآلي ليس تخصصي ، لذلك لا أعرف ما إذا كان هذا مناسبًا أم لا.
ccTomAugspurger ، الذي يبدو مثل ذلك النوع من الرجل الذي قد يكون لديه أفكار حول هذا الأمر.
فيما يتعلق بـ Dask والتنبؤ ، يمكنني دائمًا إعداد rabit مرة أخرى. هذا يبدو غير نظيف بعض الشيء لأنه يفرض التقييم بدلاً من إبقاء الأمور كسولة. لكن هذا ليس مانعًا خطيرًا للاستخدام.
الوقوع في بعض المشاكل مع التنبؤ. سؤالين:
Booster.predict
عدة مرات في نفس جلسة rabit؟rabit.init
و Booster.predict
و rabit.finalize
في سلاسل منفصلة؟أقوم حاليًا بإنشاء أداة تعقب جديدة ، وأتصل بـ rabit.init
على مؤشر ترابط العامل الرئيسي. هذا يعمل بشكل جيد. ومع ذلك ، عندما أتصل بـ Booster.predict
في سلاسل العمليات (يحتفظ كل عامل dask بمجموعة مؤشرات ترابط للحساب) أحصل على أخطاء مثل Doing rabit call after Finalize
. أي توصيات؟
جزء من التنبؤ لا يزال يستخدم rabit ، ويرجع ذلك أساسًا إلى أن المتنبئ لا يزال يستخدم المتعلم مع بعض إجراءات التهيئة التي يتم مشاركتها مع التدريب. في النهاية يجب إصلاح هذا ، ولكن هذا هو الحال الآن.
أشعر بالفضول حيال هذا. بعد أن قمنا بإجراء تسلسل - نقل - إلغاء تسلسل النموذج المدرب من عامل إلى جهاز العميل الخاص بي ، يبدو أنه يعمل بشكل جيد على البيانات العادية على الرغم من عدم وجود شبكة rabit. يبدو أن نموذجًا تم تدريبه باستخدام Rabit يمكن استخدامه للتنبؤ بالبيانات بدون rabit. يبدو هذا أيضًا أنه سيكون ضروريًا في الإنتاج. هل يمكنك أن تقول المزيد عن قيود استخدام نموذج تدرب على الأرانب هنا؟
مثال على مجموعة البيانات / المشكلة
إذا افترضنا أن كل شيء أعلاه صحيح ، فهل هناك مثال تدريب معياري موزع يستخدمه الناس في العرض التوضيحي؟
سيكون من الرائع إعادة إنتاج نتائج هذه التجربة:
https://github.com/Microsoft/LightGBM/wiki/Experiments#parallel -experiment
مع خيار binning + fast fast الجديد من XGBoost (# 1950) ، يجب أن يكون من الممكن الحصول على نتائج مماثلة.
مثال لعبة نموذجي يمكنك تجربته في https://github.com/dmlc/xgboost/tree/master/demo/data
إنه بتنسيق libsvm رغم ذلك ، ويحتاج إلى القليل من التحليل لتحويله إلى numpy
قد تكون مهتمًا بهذا العلاقات العامة في sklearn: https://github.com/scikit-learn/scikit-learn/pull/935
mrocklin ليس هناك أي قيود على إعادة استخدام النموذج. لذلك يمكن استخدام النموذج المدرب في النسخة الموزعة في الإصدار التسلسلي. إنه فقط أن القيد الحالي للتنبؤ (عند تجميعه مع rabit) له وظيفة مختلطة مع وظيفة التدريب (لذلك حدث نداء rabit).
الآن بعد أن قلتها ، أعتقد أنه قد يكون لدينا حل للمشكلة. ببساطة قم بعمل rabit.init
(بدون تمرير أي شيء ، واجعل المتنبئ يعتقد أنه العامل الوحيد) قبل التنبؤ يجب أن يحل المشكلة
نعم. في الواقع هذا يحل المشكلة. يدعم dask-xgboost الآن التنبؤ: https://github.com/mrocklin/dask-xgboost/commit/827a03d96977cda8d104899c9f42f52dac446165
شكرا على الحل البديل tqchen !
فيما يلي سير عمل باستخدام dask.dataframe و xgboost في عينة صغيرة من مجموعة بيانات شركات الطيران على جهاز الكمبيوتر المحمول المحلي. هل هذا يبدو جيدا للجميع؟ هل هناك عناصر واجهة برمجة تطبيقات لـ XGBoost أفتقدها هنا؟
In [1]: import dask.dataframe as dd
In [2]: import dask_xgboost as dxgb
In [3]: df = dd.read_csv('train-0.1m.csv')
In [4]: df.head()
Out[4]:
Month DayofMonth DayOfWeek DepTime UniqueCarrier Origin Dest Distance \
0 c-8 c-21 c-7 1934 AA ATL DFW 732
1 c-4 c-20 c-3 1548 US PIT MCO 834
2 c-9 c-2 c-5 1422 XE RDU CLE 416
3 c-11 c-25 c-6 1015 OO DEN MEM 872
4 c-10 c-7 c-6 1828 WN MDW OMA 423
dep_delayed_15min
0 N
1 N
2 N
3 N
4 Y
In [5]: labels = df.dep_delayed_15min == 'Y'
In [6]: del df['dep_delayed_15min']
In [7]: df = df.categorize()
In [8]: df = dd.get_dummies(df)
In [9]: data_train, data_test = df.random_split([0.9, 0.1], random_state=123)
In [10]: labels_train, labels_test = labels.random_split([0.9, 0.1], random_state=123)
In [11]: from dask.distributed import Client
In [12]: client = Client() # in a large-data situation I probably should have done this before calling categorize above (which requires computation)
In [13]: param = {} # Are there better choices for parameters?
In [14]: bst = dxgb.train(client, {}, data_train, labels_train)
[14:00:46] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 120 extra nodes, 0 pruned nodes, max_depth=6
[14:00:48] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 120 extra nodes, 0 pruned nodes, max_depth=6
[14:00:50] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 122 extra nodes, 0 pruned nodes, max_depth=6
[14:00:53] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 118 extra nodes, 0 pruned nodes, max_depth=6
[14:00:55] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 120 extra nodes, 0 pruned nodes, max_depth=6
[14:00:57] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 114 extra nodes, 0 pruned nodes, max_depth=6
[14:00:59] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 118 extra nodes, 0 pruned nodes, max_depth=6
[14:01:01] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 118 extra nodes, 0 pruned nodes, max_depth=6
[14:01:04] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 94 extra nodes, 0 pruned nodes, max_depth=6
[14:01:06] src/tree/updater_prune.cc:74: tree pruning end, 1 roots, 102 extra nodes, 0 pruned nodes, max_depth=6
In [15]: bst
Out[15]: <xgboost.core.Booster at 0x7f689803af60>
In [16]: predictions = dxgb.predict(client, bst, data_test)
In [17]: predictions
Out[17]:
Dask Series Structure:
npartitions=1
None float32
None ...
Name: predictions, dtype: float32
Dask Name: _predict_part, 9 tasks
هدفي على المدى القصير هو كتابة منشور مدونة قصير حول هذا الأمر بحيث آمل أن يأتي شخص آخر لديه خبرة أكبر مع XGBoost ومع مزيد من الوقت لتبني هذا المشروع ودفعه إلى الأمام. (أنا ، مثل أي شخص آخر هنا ، أعمل على عدد قليل من المشاريع الأخرى مثل هذا في نفس الوقت.)
أنا جزء من مجموعة بيانات شركات الطيران لمجرد أنني حصلت عليها بالفعل في دلو S3. أوافق على الرغم من أن مجموعة بيانات Criteo ستوفر عرضًا أفضل على نطاق واسع.
ما زلت غير متأكد من المعلمات التي يجب استخدامها أو كيفية الحكم على النتيجة. للمعلمات يمكنني استخدام التجربة من szilard هنا . هل هناك طريقة جيدة للحكم على التنبؤات؟ على سبيل المثال ، هل نبحث عن predictions > 0.5
لمطابقة labels_test
؟
ربما تكون الطريقة الأكثر شيوعًا لتقييم الأداء التنبئي للتصنيف الثنائي (خاصة في إعدادات البحث أو المنافسة) هي استخدام المنطقة الواقعة تحت منحنى ROC (AUC) ، على الرغم من أنه في تطبيقات العالم الحقيقي يجب على المرء استخدام المقاييس التي تتوافق مع قيم "الأعمال" أنتجت باستخدام النماذج.
على سبيل المثال ، هل نبحث عن تنبؤات> 0.5 لمطابقة labels_test؟
نعم. إذا كنت تأخذ متوسط ذلك في مجموعة الاختبار ، فهذه هي دقة الاختبار. ولكن من المحتمل أن تكون مجموعة البيانات غير متوازنة (غياب النقرات أكثر بكثير من النقرات). في هذه الحالة ، تكون نتيجة ROC AUC مقياسًا أفضل.
from sklearn.metrics import roc_auc_score
print(roc_auc_score(labels_test, predictions))
بافتراض أن predictions
عبارة عن مصفوفة أحادية الأبعاد من الاحتمالات الإيجابية المقدرة بواسطة النموذج لكل صف في مجموعة الاختبار.
mrocklin سؤال متابعة واحد ، هل تسمح داسك بوظائف متعددة الخيوط؟ أعلم أن هذا ليس وثيق الصلة بـ Python بسبب GIL. ولكن يمكن أن تسمح xgboost بالتدريب متعدد الخيوط لكل عامل مع استمرار التنسيق مع بعضها البعض بشكل موزع. يجب أن نضع دائمًا وسيطات nthread لـ xgboost لتكون عدد النوى العاملة لهذا العامل
الإجابة المختصرة هي "نعم". يتم استخدام Dask في معظم الأحيان مع مشاريع مثل NumPy و Pandas و SKLearn وغيرها والتي تكون في الغالب مجرد كود C و Fortran ، وملفوفة ببايثون. لا يؤثر GIL على هذه المكتبات. بعض الأشخاص يستخدمون Dask لتطبيقات مماثلة لـ PySpark RDD (انظر dask.bag ) وسوف يتأثرون. هذه المجموعة هي في الأقلية بالرغم من ذلك.
لذا نعم ، يسمح Dask بالمهام متعددة الخيوط. كيف يمكننا إخبار XGBoost باستخدام خيوط متعددة؟ في تجاربي حتى الآن ، أرى استخدامًا مرتفعًا لوحدة المعالجة المركزية دون تغيير أي معلمات ، فربما يعمل كل شيء بشكل جيد افتراضيًا؟
يستخدم XGBoost خيوط متعددة بشكل افتراضي ، وسيستخدم جميع خيوط وحدة المعالجة المركزية المتاحة على الجهاز (بدلاً من ذلك العامل) إذا لم يتم تعيين nthread. يمكن أن يؤدي ذلك إلى إنشاء حالة سباق عندما يتم تعيين عدة عمال لنفس الجهاز.
لذلك من الجيد دائمًا تعيين معلمة nthread على الحد الأقصى لعدد النوى المسموح للعامل باستخدامها. عادة ما يتم استخدام الممارسة الجيدة حول 4 خيوط لكل عامل
بالتأكيد ، يجب أن يتم إنجازه في
https://github.com/mrocklin/dask-xgboost/commit/c22d066b67c78710d5ad99b8620edc55182adc8f
يوم الإثنين 20 فبراير 2017 الساعة 6:31 مساءً ، Tianqi Chen [email protected]
كتب:
يستخدم XGBoost خيوط متعددة بشكل افتراضي ، وسيستخدم كل وحدات المعالجة المركزية المتاحة
الخيوط على الجهاز (بدلاً من ذلك العامل) إذا لم يتم ضبط nthread.
يمكن أن يؤدي ذلك إلى إنشاء حالة سباق عند تعيين عدة عمال لنفس الأمر
آلة.لذلك من الجيد دائمًا تعيين معلمة nthread على الحد الأقصى لعدد
النوى المسموح للعامل باستخدامها. عادة ما يتم استخدام ممارسة جيدة حول القول
4 خيوط لكل عامل-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/dmlc/xgboost/issues/2032#issuecomment-281205747 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe-auth/AASszPELRoeIvqEzyJhkKumIs-vd0PHiks5reiJngaJpZM4L_PXa
.
مفكرة: https://gist.github.com/19c89d78e34437e061876a9872f4d2df
تسجيل قصير (ست دقائق): https://youtu.be/Cc4E-PdDSro
التعليقات النقدية موضع ترحيب كبير. مرة أخرى ، من فضلك اغفر جهلي في هذا المجال.
mrocklin عرض رائع! أعتقد أن أداء وقت التشغيل (وربما استخدام الذاكرة) يمكن أن يتحسن بشكل كبير باستخدام 'tree_method': 'hist', 'grow_policy': 'lossguide'
في البارامترات.
شكرا @ ogrisel. باستخدام هذه المعلمات ، يستغرق وقت التدريب من ست دقائق إلى دقيقة واحدة. يبدو أن استخدام الذاكرة يظل كما هو.
حسنًا ، نعود إلى هذا. هل هناك أي عمليات XGBoost بخلاف التدريب والتنبؤ بضرورة تنفيذها؟
tqchen أو ogrisel إذا كان لدى أي منكما الوقت للنظر في التنفيذ على https://github.com/mrocklin/dask-xgboost/blob/master/dask_xgboost/core.py سأكون ممتنًا. أفهم على الرغم من أن البحث في قاعدة بيانات أجنبية ليس دائمًا على رأس قائمة الأولويات.
إذا كان كل شيء على ما يرام ، فسأضيف المزيد إلى README ، وأنشر على PyPI ، ومن ثم يمكننا إغلاق هذه المشكلة على الأرجح.
أعتقد فقط التدريب والتنبؤ بالحاجة إلى التوزيع. لا يلزم توزيع الأشياء الأخرى نظرًا لأنها لا ترد على مجموعة البيانات
لقد دفعت dask-xgboost إلى PyPI ونقلته إلى https://github.com/dask/dask-xgboost
شكرًا لك tqchen و ogrisel على مساعدتك هنا. جعل هذا التعاون سهلاً نسبيًا.
سأكون سعيدًا بمساعدة الناس إذا أرادوا تنفيذ المعايير. حتى ذلك الحين ، سيتم الإغلاق.
التعليق الأكثر فائدة
مفكرة: https://gist.github.com/19c89d78e34437e061876a9872f4d2df
تسجيل قصير (ست دقائق): https://youtu.be/Cc4E-PdDSro
التعليقات النقدية موضع ترحيب كبير. مرة أخرى ، من فضلك اغفر جهلي في هذا المجال.