مصنفات بايز الساذجة
“نظرية بايز + افتراض جريء واحد = مصنّف قوي بشكل مدهش”
مبرهنة بايز وافتراض الاستقلالية الشرطية ومتغيرات Gaussian/Multinomial/Complement وتمهيد Laplace وتصنيف النصوص بـTF-IDF ومعايرة الاحتمالات.
المتطلبات الأساسية
المفاهيم المغطاة
∑الصيغ الرئيسية
نظرية بايز
الاحتمال الخلفي = الاحتمالية × المسبق / الدليل
الفرضية الساذجة
الميزات مستقلة شرطياً بإعطاء الفئة — الجزء 'الساذج'
قرار MAP
الأعظمية الخلفية — تجاهل P(x) لأنه متساوٍ لجميع الفئات
الاحتمالية الغاوسية
يفترض NB الغاوسي أن كل ميزة موزَّعة توزيعاً طبيعياً داخل كل فئة
▶محاكاة تفاعلية
لماذا نتعلم بايز الساذج؟
يُصنِّف Naïve Bayes رسائل البريد المزعج بشكل أفضل من كثير من النماذج المعقدة، يعمل في ميكروثوانٍ، يحتاج بيانات تدريب قليلة جداً، يتعامل بلطف مع الميزات الناقصة، ويُنتج احتمالات مُعايَرة. كان فلتر البريد المزعج الأصلي في Gmail يستخدم Naïve Bayes. هو المرجع القياسي لمسائل تصنيف النصوص. فهمه يمنح حدساً عميقاً حول المصنِّفات الاحتمالية ولماذا فرضية 'الساذج' (الاستقلالية الشرطية) يمكنها رغم ذلك إنتاج نماذج مفيدة.
رغم أن فرضية الاستقلالية 'الساذجة' خاطئة تقريباً دائماً في الواقع، يحقق Naïve Bayes باستمرار دقة تصنيف قريبة من المثالي في مهام تصنيف النصوص والوثائق.
الحدس الاحتمالي
افترض أنك تريد تصنيف بريد إلكتروني كـ'مزعج' أو 'طبيعي'. رأيت 1000 بريد: 300 كانت مزعجة. كلمة 'فياغرا' تظهر في 250 من 300 رسائل مزعجة وفقط 1 من 700 طبيعية. كلمة 'اجتماع' تظهر في 5 مزعجة و400 طبيعية. لبريد جديد يحتوي الكلمتين، يضرب Naïve Bayes: P(مزعج) × P(فياغرا|مزعج) × P(اجتماع|مزعج). هذا الناتج هو الاحتمال الخلفي غير المُطبَّع — قارنه بـP(طبيعي) × P(فياغرا|طبيعي) × P(اجتماع|طبيعي). الأكبر يفوز. الفرضية 'الساذجة' تجعل هذا الضرب صالحاً.
اشتقاق قاعدة القرار
بنظرية بايز: P(C|x) ∝ P(x|C)P(C). الفرضية الساذجة تُفكِّك P(x|C) = ∏ P(xⱼ|C). بما أن P(x) ثابت بين الفئات، نحتاج فقط البسط. بأخذ اللوغاريتم (للاستقرار العددي — ضرب احتمالات صغيرة يُفيض): log P(C|x) = log P(C) + Σⱼ log P(xⱼ|C). في NB الغاوسي، P(xⱼ|C) غاوسية بمتوسط وتباين مُقدَّرَين لكل فئة. في NB متعدد الحدود (النصوص)، P(xⱼ|C) هي تكرار الكلمة المُملَّس في الفئة C.
تمهيد لابلاس: تجنب الاحتمالات الصفرية
إذا لم تظهر كلمة قط في رسائل التدريب المزعجة، فإن P(كلمة|مزعج)=0 ويُصبح كامل الناتج صفراً — كلمة واحدة غير مرئية تجعل المصنِّف يتجاهل كل الأدلة الأخرى. يُضيف تمهيد لابلاس α (عادةً 1) لجميع أعداد الكلمات: P(xⱼ|C) = (عدد(xⱼ,C) + α) / (عدد(C) + α × |V|) حيث |V| حجم المفردات. هذا يضمن ألا يكون أي احتمال صفراً تماماً. α أكبر = تمهيد أكثر = أقرب للتوزيع المنتظم.
تمهيد لابلاس شكل من أشكال تنظيم L1 في السمبلكس الاحتمالي. يمنع الإفراط في التعلم على الكلمات النادرة وهو حاسم لـNB متعدد الحدود على بيانات النصوص.
أي متغير من بايز الساذج تستخدم؟
GaussianNB: ميزات مستمرة مفترض أنها غاوسية لكل فئة. جيد لبيانات المستشعرات والقياسات الطبية. MultinomialNB: ميزات أعداد صحيحة (أعداد الكلمات، TF-IDF×N). قياسي لتصنيف الوثائق. BernoulliNB: ميزات ثنائية (وجود/غياب الكلمات). جيد للنصوص القصيرة. ComplementNB: يعالج تحيز MultinomialNB على البيانات غير المتوازنة — غالباً الأفضل لتصنيف النصوص.
ميزات مستمرة → GaussianNB
أعداد كلمات / ميزات TF-IDF → MultinomialNB (تتطلب قيماً غير سالبة)
ميزات ثنائية (كلمة موجودة/غائبة) → BernoulliNB
تصنيف نصوص غير متوازن → ComplementNB
أنواع مختلطة → استخدام ColumnTransformer + NB مختلف لكل نوع عمود
تصنيف النصوص مع بايز الساذج
from sklearn.naive_bayes import MultinomialNB, ComplementNB, GaussianNB from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.pipeline import Pipeline from sklearn.model_selection import cross_val_score, train_test_split from sklearn.calibration import CalibratedClassifierCV from sklearn.preprocessing import LabelEncoder class="tok-comment"># ── Sample text data ─────────────────────────────────────────────────── X_text = [ class="tok-str">"buy cheap pills now", class="tok-str">"get rich quick scheme", class="tok-str">"free money click here", class="tok-str">"meeting at 3pm tomorrow", class="tok-str">"quarterly report attached", class="tok-str">"team lunch Friday", class="tok-str">"win a prize enter now", class="tok-str">"limited offer act fast", class="tok-str">"investment opportunity", class="tok-str">"project deadline next week", class="tok-str">"budget review scheduled", class="tok-str">"please review document", ] * class="tok-num">20 class="tok-comment"># class="tok-num">240 samples y_raw = ([class="tok-num">1, class="tok-num">1, class="tok-num">1, class="tok-num">0, class="tok-num">0, class="tok-num">0, class="tok-num">1, class="tok-num">1, class="tok-num">1, class="tok-num">0, class="tok-num">0, class="tok-num">0] * class="tok-num">20) class="tok-comment"># class="tok-num">1=spam, class="tok-num">0=ham import numpy as np y = np.array(y_raw) X_train, X_test, y_train, y_test = train_test_split( X_text, y, test_size=class="tok-num">0.2, random_state=class="tok-num">42) class="tok-comment"># ── Text classification (spam detection) ────────────────────────── pipe = Pipeline([ (class="tok-str">'tfidf', TfidfVectorizer( ngram_range=(class="tok-num">1,class="tok-num">2), class="tok-comment"># unigrams + bigrams max_features=50_000, sublinear_tf=True, class="tok-comment"># log(class="tok-num">1+tf) min_df=class="tok-num">3, )), (class="tok-str">'clf', ComplementNB(alpha=class="tok-num">0.1)), class="tok-comment"># best for text ]) scores = cross_val_score(pipe, X_text, y, cv=class="tok-num">5, scoring=class="tok-str">'f1_macro') print(fclass="tok-str">"F1: {scores.mean():.3f} ± {scores.std():.3f}") class="tok-comment"># ── Calibrated probabilities ─────────────────────────────────────── class="tok-comment"># NB probabilities are often poorly calibrated (overconfident) class="tok-comment"># Use isotonic regression calibration for better probability estimates pipe_cal = CalibratedClassifierCV(pipe, cv=class="tok-num">5, method=class="tok-str">'isotonic') pipe_cal.fit(X_train, y_train) probs = pipe_cal.predict_proba(X_test) class="tok-comment"># ── Continuous features: GaussianNB ──────────────────────────────── from sklearn.preprocessing import StandardScaler gnb = Pipeline([ (class="tok-str">'scaler', StandardScaler()), (class="tok-str">'clf', GaussianNB(var_smoothing=class="tok-num">1e-9)), ]) gnb.fit(X_train, y_train) print(fclass="tok-str">"GaussianNB accuracy: {gnb.score(X_test, y_test):.3f}") class="tok-comment"># ── Inspect learned parameters ───────────────────────────────────── nb = gnb.named_steps[class="tok-str">'clf'] print(class="tok-str">"Class priors:", nb.class_prior_) print(class="tok-str">"Feature means per class:", nb.theta_) class="tok-comment"># shape (n_classes, n_features)
مزالق بايز الساذج
فرضية الاستقلالية تعني أن الميزات المترابطة تُحتسب مرتين. إذا كانت 'فياغرا' و'حبة' تتزامنان دائماً في البريد المزعج، فدليلهما المشترك يُحتسب مرتين مما يؤدي لاحتمالات خلفية مفرطة الثقة. لهذا تكون احتمالات NB عموماً سيئة التعيير حتى حين تكون التصنيفات صحيحة — دائماً استخدم CalibratedClassifierCV للمخرجات الاحتمالية. أيضاً: MultinomialNB يتطلب ميزات غير سالبة.
Naïve Bayes خط أساس ممتاز وغالباً يصعب التفوق عليه في مجموعات النصوص الصغيرة. إذا سجّل 85% ونموذجك المعقد 87%، فاسأل: هل يستحق الكسب بنسبة 2% تعقيداً أعلى 10× وزمن تدريب أطول؟
?اختبار المعرفة
يتم حفظ التقدم في متصفحك — لا حاجة لحساب.