كجزء من تنفيذ المهمة الكبيرة لتحليل المشاعر (تحليل المراجعات) ، قررت تكريس بعض الوقت لدراسة إضافية للعنصر المنفصل - باستخدام VotingClassifier من وحدة sklearn.ensemble كأداة لبناء مجموعة من نماذج التصنيف وتحسين الجودة النهائية للتنبؤات. لماذا هذا مهم وما هي الفروق الدقيقة؟

غالبًا ما يحدث أنه خلال حل المشكلة التطبيقية لتحليل البيانات ، ليس من الواضح على الفور (أو ليس واضحًا على الإطلاق) أي نموذج التدريب الأنسب. يمكن أن يكون أحد الحلول هو اختيار النموذج الأكثر شيوعًا و / أو المناسب بشكل بديهي بناءً على طبيعة البيانات المتاحة. في هذه الحالة ، يتم تحسين معلمات النموذج المحدد (على سبيل المثال ، من خلال GridSearchCV) ويتم استخدامه في العمل. قد يكون النهج الآخر هو استخدام مجموعة من النماذج عندما تشارك نتائج العديد منها في وقت واحد في تشكيل النتيجة النهائية. سأقول على الفور أن الغرض من المقالة ليس وصف مزايا استخدام مجموعة من النماذج أو مبادئ بنائها (يمكن العثور عليها
هنا ) ، بل في نهج واحد يتم تطبيقه بشكل منفصل لحل المشكلة باستخدام مثال محدد وتحليل الفروق الدقيقة التي تنشأ أثناء مثل هذا الحل.
بيان المشكلة العالمية هو كما يلي : تم تقديم
100 مراجعة فقط على الهواتف المحمولة كعينة اختبار ، ونحن بحاجة إلى نموذج مدرب مسبقًا سيعرض أفضل نتيجة على هذه المراجعات الـ 100 - أي أنه سيحدد ما إذا كانت المراجعة إيجابية أم سلبية. هناك صعوبة إضافية ، كما يلي من ظروف المشكلة ، هي عدم وجود عينة تدريبية. للتغلب على هذه الصعوبة بمساعدة مكتبة Beautiful Soup ، تم تحليل 10000 مراجعة حول الهواتف المحمولة والتصنيفات لها من أحد المواقع الروسية بنجاح.
تخطي خطوات التحليل ومعالجة البيانات ودراسة هيكلها الأولي ، ننتقل إلى اللحظة التي توجد فيها:
- عينة تدريبية ، تتكون من 10000 مراجعة هاتفية ، كل مراجعة لها علامة ثنائية (إيجابية أو سلبية). ترميز لتعريف المراجعات بتصنيفات 1-3 سلبية و 4-5 إيجابية.
- باستخدام Count Vectorizer ، يتم تقديم البيانات في شكل مناسب لنماذج مصنف التدريب
كيف تقرر النموذج الأفضل بالنسبة لك؟ ليس لدينا القدرة على التكرار يدويًا على النماذج ، لأن تشكل عينة الاختبار المكونة من 100 مراجعة فقط خطرًا كبيرًا من أن بعض النماذج تتناسب بشكل أفضل مع هذه العينة الاختبارية ، ولكن إذا استخدمتها في عينة إضافية مخفية منا أو في "معركة" ، فستكون النتيجة أقل من المتوسط.
لحل هذه المشكلة
، تحتوي مكتبة Scikit-Learn على وحدة VotingClassifier ، وهي أداة ممتازة لاستخدام العديد من نماذج التعلم الآلي المختلفة عن بعضها البعض ودمجها في مصنف واحد. هذا يقلل من خطر إعادة التدريب ، وكذلك التفسير غير الصحيح لنتائج أي نموذج معين.
يتم استيراد الوحدة النمطية VotingClassifier بالأمر التالي :
from sklearn.ensemble import VotingClassifier
التفاصيل العملية عند العمل مع هذه الوحدة:
1) أول وأهم شيء هو كيفية الحصول على تنبؤ مأخوذ من المصنف المجمع بعد تلقي التوقعات من كل من النماذج المدرجة فيه. من بين معلمات VotingClassifier هناك معلمة
تصويت ذات قيمتين محتملتين: "صلب" و "ناعم".
1.1) في الحالة الأولى ، تتوافق الإجابة النهائية للمصنف المشترك مع "رأي" أغلبية أعضائه. على سبيل المثال ، يستخدم المصنف المدمج بيانات من ثلاثة نماذج مختلفة. ويتنبأ اثنان منهم في ملاحظة محددة بأن الاستجابة "ردود فعل إيجابية" ، والثالثة - "ردود فعل سلبية". وبالتالي ، بالنسبة لهذه الملاحظة ، فإن التنبؤ النهائي سيكون "ردود فعل إيجابية" ، حيث لدينا 2 - "لـ" و 1 "ضد".
1.2) في الحالة الثانية ، أي عند استخدام القيمة "السهلة" لمعلمة
التصويت ، يكون هناك "تصويت" كامل وترجيح لتنبؤات النموذج
لكل فئة ، لذا فإن الإجابة النهائية للمُصنِّف المُجمَّع هي argmax لمجموع الاحتمالات المتوقعة.
هام! من أجل أن تكون قادرًا على استخدام طريقة "التصويت" هذه ، يجب أن يدعم
كل مصنف من تلك المدرجة في مجموعتك طريقة
التنبؤ_الحالية () للحصول على تقدير كمي لاحتمال حدوث كل فئة. يرجى ملاحظة أنه لا تدعم جميع نماذج المصنف هذه الطريقة ، وبالتالي ، يمكن استخدامها في إطار VotingClassifier عند استخدام طريقة الاحتمالات المرجحة (التصويت الناعم).
دعونا نلقي نظرة على مثال : هناك ثلاثة مصنفات وفئتان من المراجعات: إيجابية وسلبية. سيعطي كل مصنف ، من خلال طريقة التنبؤ _ بروبا ، قيمة احتمالية معينة (p) ، يتم من خلالها تخصيص ملاحظة معينة للفئة 1 ، وبالتالي مع الاحتمال (1-p) للفئة الثانية. المصنف المشترك ، بعد تلقي إجابة من كل من النماذج ، يقوم بترجيح التقديرات التي تم الحصول عليها ويعطي النتيجة النهائية التي تم الحصول عليها
$$ display $$ max (w1 * p1 + w2 * p1 + w3 * p1 ، w1 * p2 + w2 * p2 + w3 * p3) $$ display $$
، حيث w1 ، w2 ، w3 هي أوزان المصنفات المدرجة في المجموعة ، افتراضيًا لها أوزان متساوية ، و p1 ، p2 هو تقييم الانتماء إلى الفئة 1 أو الفئة 2 لكل منها. يرجى أيضًا ملاحظة أن أوزان المصنفات عند استخدام Soft Vote يمكن تغييرها باستخدام معلمة الأوزان ، لذا يجب أن يبدو استدعاء الوحدة على النحو التالي:
... = VotingClassifier(estimators=[('..', clf1), ('..', clf2), ('...', clf3)], voting='soft', weights=[*,*,*])
، حيث قد تشير العلامات النجمية إلى الأوزان المطلوبة لكل نموذج.
2) القدرة على استخدام الوحدة النمطية VotingClassifier و GridSearch في
نفس الوقت لتحسين المعلمات الفائقة لكل من المصنفات المدرجة في المجموعة.
عندما تخطط لاستخدام مجموعة وترغب في تحسين النماذج المضمنة فيها ، يمكنك استخدام GridSearch بالفعل في المصنف الموحد. ويوضح الكود أدناه كيف يمكنك العمل مع النماذج المضمنة فيه (الانحدار اللوجستي ، Bayes الساذج ، نزول التدرج العشوائي) بينما تبقى في إطار المصنف الموحد (VotingClassifier):
clf1 = LogisticRegression() clf2 = MultinomialNB() clf3 = SGDClassifier(max_iter=1000, loss='log') eclf = VotingClassifier(estimators=[ ('lr', clf1), ('nb', clf2),('sgd', clf3)], voting='hard') # (hard voting), . . 1.1 <b>params = {'lr__C' : [0.5,1,1.5], 'lr__class_weight': [None,'balanced'], 'nb__alpha' : [0.1,1,2], 'sgd__penalty' : ['l2', 'l1'], 'sgd__alpha': [0.0001,0.001,0.01]} </b> # , , grid = GridSearchCV(estimator=eclf, param_grid=params, cv=5, scoring='accuracy', n_jobs=-1) grid = grid.fit(data_messages_vectorized, df_texts['Binary_Rate']) # , 5
وبالتالي ، يجب تعيين قاموس المعلمات بحيث يمكنك عند الوصول إليه من خلال GridSearch ، تحديد المعلمة في مجموعة النماذج التي تشير إلى معلمة تريد تحسين قيمتها.
هذا كل ما تحتاج إلى معرفته لاستخدام أداة VotingClassifier بشكل كامل كطريقة لبناء مجموعة من النماذج وتحسينها. دعونا نلقي نظرة على النتائج:
print grid.best_params_ {'lr__class_weight': 'balanced', 'sgd__penalty': 'l1', 'nb__alpha': 1, 'lr__C': 1, 'sgd__alpha': 0.001}
تم العثور على القيم المثلى للمعلمات ، ويبقى لمقارنة نتائج العمل لمجموعة المصنفات (VotingClassifier) مع المعلمات المثلى ، وسوف نقوم بالتحقق من صحة عينة التدريب ومقارنة النماذج بالمعلمات المثالية والمجموعة التي تتكون منها:
for clf, label in zip([clf1, clf2, clf3, eclf], ['Logistic Regression', 'Naive Bayes', 'SGD', 'Ensemble_HardVoting']): scores = cross_val_score(clf, data_messages_vectorized, df_texts['Binary_Rate'], cv=3, scoring='accuracy') print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label))
النتيجة النهائية:
الدقة: 0.75 (± 0.02) [الانحدار اللوجستي]
الدقة: 0.79 (± 0.02) [Naive Bayes]
الدقة: 0.79 (± 0.02) [SGD]
الدقة: 0.79 (± 0.02) [Ensemble_HardVoting]
كما ترى ، أظهرت النماذج نفسها بشكل مختلف إلى حد ما في عينة التدريب (مع المعلمات القياسية ، كان هذا الاختلاف أكثر وضوحًا). علاوة على ذلك ، لا يجب أن تتجاوز القيمة الإجمالية (وفقًا لمقياس الدقة) للمجموعة أفضل قيمة من النماذج المدرجة فيها ، لأن المجموعة هي نموذج أكثر استقرارًا ، وقادرة على إظهار نتيجة مماثلة في مجموعة الاختبار وفي "المعركة" ، مما يعني تقليل خطر إعادة التدريب ، والتناسب مع مجموعة التدريب ، وغيرها من المصنفات المتعلقة بالتدريب. حظا سعيدا في حل المشاكل التطبيقية وشكرا لاهتمامكم!
PS بالنظر إلى تفاصيل وقواعد النشر في وضع الحماية ، لا يمكنني تقديم رابط إلى github وشفرة المصدر للتحليل الوارد في هذه المقالة ، بالإضافة إلى روابط إلى Kaggle ، في إطار مسابقة InClass التي وفرت مجموعة اختبار وأدوات للتحقق من النماذج عليه. لا يسعني إلا أن أقول أن هذه المجموعة تغلبت بشكل كبير على خط الأساس وأخذت مكانها الصحيح على لوحة الصدارة بعد التحقق من مجموعة الاختبار. آمل في المنشورات التالية التي يمكنني مشاركتها.