غاوسيان ساذج بايز ، شرح

غاوسيان ساذج بايز ، شرح

عقدة المصدر: 2021431

غاوسيان ساذج بايز ، شرح
منطقة القرار لمصنف غاوسي ساذج بايز. صورة المؤلف.

 

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

في هذه المقالة ، يمكنك أن تتعلم

  • كيف تعمل مصنفات بايز الساذجة ،
  • لماذا من المنطقي تعريفهم بالطريقة التي هم بها و
  • كيفية تنفيذها في Python باستخدام NumPy.

يمكنك العثور على الرمز على جيثب الخاص بي.

قد يكون من المفيد قليلاً مراجعة كتابي التمهيدي عن إحصائيات بايزي مقدمة لطيفة للاستدلال بايزي للتعود على صيغة بايز. نظرًا لأننا سنقوم بتطبيق المصنف بطريقة متوافقة مع scikit ، فمن المفيد أيضًا مراجعة مقالتي قم ببناء انحدار scikit-Learn المخصص الخاص بك. ومع ذلك ، فإن النفقات العامة لـ scikit-Learn صغيرة جدًا ويجب أن تكون قادرًا على المتابعة على أي حال.

سنبدأ في استكشاف النظرية البسيطة المذهلة لتصنيف بايز الساذج ثم ننتقل إلى التنفيذ.

ما الذي نهتم به حقًا عند التصنيف؟ ماذا نفعل بالفعل ، ما هو المدخل والمخرج؟ الجواب بسيط:

بالنظر إلى نقطة البيانات x ، ما احتمال انتماء x إلى فئة معينة من الفئة c؟

هذا كل ما نريد الرد عليه أي وقت تصنيف. يمكنك نمذجة هذه العبارة مباشرة كاحتمال شرطي: p(c|x).

على سبيل المثال ، إذا كان هناك

  • دروس 3 جججو
  • يتكون من 2 ميزات س₁س₂,

يمكن أن تكون نتيجة المصنف شيئًا مثل p(ج|س₁س₂) = 0.3 ، p(ج|س₁س₂) = 0.5 و p(ج|س₁س₂) = 0.2. إذا كنا نهتم بتسمية واحدة كناتج ، فسنختار التسمية ذات الاحتمال الأعلى ، أي ج مع احتمال 50٪ هنا.

يحاول مصنف Bayes الساذج حساب هذه الاحتمالات مباشرة.

ساذجة بايز

حسنًا ، نظرًا لنقطة البيانات x، نريد أن نحسب p(c|x) لجميع الفصول ثم إخراج ملف c بأعلى احتمال. في الصيغ غالبًا ما ترى هذا كـ

 

غاوسيان ساذج بايز ، شرح
صورة المؤلف.

 

ملحوظة: ماكس p(c|x) ترجع الحد الأقصى للاحتمال بينما argmax p(c|x) يعيد ال c مع هذا الاحتمال الأعلى.

ولكن قبل أن نتمكن من التحسين p(c|x) ، يجب أن نكون قادرين على حسابه. لهذا نستخدم مبرهنة بايز:

 

غاوسيان ساذج بايز ، شرح
مبرهنة بايز. صورة المؤلف.

 

هذا هو جزء Bayes من Bayes الساذج. لكن الآن لدينا المشكلة التالية: ما هي p(x|c) و p(c)?

هذا ما يدور حوله تدريب مصنف بايز الساذج.

التدريب

لتوضيح كل شيء ، دعونا نستخدم مجموعة بيانات لعبة مع سمتان حقيقيتان س₁س₂و ثلاثة فصول ججج في التالي.

 

غاوسيان ساذج بايز ، شرح
البيانات تصور. صورة المؤلف.

 

يمكنك إنشاء مجموعة البيانات هذه عبر

from sklearn.datasets import make_blobs X, y = make_blobs(n_samples=20, centers=[(0,0), (5,5), (-5, 5)], random_state=0)

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

هناك 7 نقاط من أصل 20 فئة مصنفة ج (أزرق) في مجموعة البيانات ، لذلك نقول p(ج) = 7/20. لدينا 7 نقاط للفصل ج (أحمر) كذلك ، لذلك وضعناها p(ج) = 7/20. الصف الأخير ج (أصفر) لديه 6 نقاط فقط ، وبالتالي p(ج) = 6/20.

يشبه هذا الحساب البسيط لاحتمالات الفئة نهج الاحتمالية القصوى. يمكنك ، مع ذلك ، استخدام أخرى قبل التوزيع ، إذا أردت. على سبيل المثال ، إذا كنت تعلم أن مجموعة البيانات هذه لا تمثل السكان الحقيقيين بسبب الطبقة ج يجب أن تظهر في 50٪ من الحالات ، ثم تقوم بتعيين p(ج) = 0.25 ، p(ج) = 0.25 و p(ج) = 0.5. كل ما يساعدك على تحسين الأداء في مجموعة الاختبار.

ننتقل الآن إلى أرجحية p(x|c)=p(س₁س₂|c). تتمثل إحدى طرق حساب هذا الاحتمال في تصفية مجموعة البيانات للعينات ذات الملصق ثم حاول العثور على توزيع (مثل غاوسي ثنائي الأبعاد) يلتقط السمات س₁س₂.

لسوء الحظ ، في العادة ، ليس لدينا عينات كافية لكل فصل لإجراء تقدير مناسب للاحتمالية.

لتكون قادرًا على بناء نموذج أكثر قوة ، نصنع افتراض ساذج أن الميزات س₁س₂مستقل عشوائيا، معطى c. هذه مجرد طريقة رائعة لجعل الرياضيات أسهل

 

غاوسيان ساذج بايز ، شرح
صورة المؤلف

 

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

الحجج المذكورة أعلاه هي نفسها بالنسبة لأي مصنف Bayes ساذج يمكنك العثور عليه. الآن الأمر يعتمد فقط على طريقة عرضك ص (س₁ | ج₁) ، ف (س₂ | ج₁) ، ف (س₁ | ج₂) ، ف (س₂ | ج₂) ، ف (س₁ | ج₃) و  ص (س₂ | ج₃).

إذا كانت ميزاتك 0 و 1 فقط ، فيمكنك استخدام ملف توزيع برنولي. إذا كانت أعداد صحيحة ، أ توزيع متعدد الحدود. ومع ذلك ، لدينا قيم ميزة حقيقية ونقرر أ جاوس التوزيع ، ومن هنا جاء اسم Gaussian naive Bayes. نفترض الشكل التالي

 

غاوسيان ساذج بايز ، شرح
صورة المؤلف.

 

أين μᵢ ، ⱼ هو يعني و σᵢ ، ⱼ هو الانحراف المعياري الذي يتعين علينا تقديره من البيانات. هذا يعني أننا نحصل على وسيلة واحدة لكل ميزة i مقرونة بفئة ج, في حالتنا 2 * 3 = 6 يعني. الشيء نفسه ينطبق على الانحرافات المعيارية. هذا يستدعي مثالا.

دعونا نحاول أن نقدر μ₂ ، ₁ و  σ₂ ، ₁. لان j= 1 ، نحن مهتمون بالفصل فقط ج، دعنا نحتفظ فقط بالعينات التي تحمل هذا الملصق. تبقى العينات التالية:

# samples with label = c_1 array([[ 0.14404357, 1.45427351], [ 0.97873798, 2.2408932 ], [ 1.86755799, -0.97727788], [ 1.76405235, 0.40015721], [ 0.76103773, 0.12167502], [-0.10321885, 0.4105985 ], [ 0.95008842, -0.15135721]])

الآن ، بسبب i= 2 علينا فقط النظر في العمود الثاني. μ₂، ₁ هو المتوسط ​​و σ₂₁ الانحراف المعياري لهذا العمود أي μ₂و ₁ = 0.49985176 و σ₂، ₁ = 0.9789976.

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

نحسب هذا الآن للمجموعات الخمس الأخرى وقد انتهينا!

في Python ، يمكنك القيام بذلك على النحو التالي:

from sklearn.datasets import make_blobs
import numpy as np # Create the data. The classes are c_1=0, c_2=1 and c_3=2.
X, y = make_blobs( n_samples=20, centers=[(0, 0), (5, 5), (-5, 5)], random_state=0
) # The class probabilities.
# np.bincounts counts the occurence of each label.
prior = np.bincount(y) / len(y) # np.where(y==i) returns all indices where the y==i.
# This is the filtering step.
means = np.array([X[np.where(y == i)].mean(axis=0) for i in range(3)])
stds = np.array([X[np.where(y == i)].std(axis=0) for i in range(3)])

تصلنا

# priors
array([0.35, 0.35, 0.3 ])
# means array([[ 0.90889988, 0.49985176], [ 5.4111385 , 4.6491892 ], [-4.7841679 , 5.15385848]])
# stds
array([[0.6853714 , 0.9789976 ], [1.40218915, 0.67078568], [0.88192625, 1.12879666]])

هذا هو نتيجة تدريب مصنف بايز غاوسي الساذج.

يتنبأ

صيغة التنبؤ الكاملة هي

 

غاوسيان ساذج بايز ، شرح
صورة المؤلف.

 

لنفترض نقطة بيانات جديدة س * =(-2 ، 5) يأتي.

 

غاوسيان ساذج بايز ، شرح
صورة المؤلف.

 

لمعرفة الفئة التي تنتمي إليها ، دعونا نحسب p(c|x*) لجميع الفصول. من الصورة ، يجب أن تنتمي إلى الفصل ج = 2 ، لكن دعنا نرى. دعونا نتجاهل المقام p(x) لثانية. باستخدام الحلقة التالية تم حساب المرشحات لـ j = 1، 2، 3.

x_new = np.array([-2, 5]) for j in range(3): print( f"Probability for class {j}: {(1/np.sqrt(2*np.pi*stds[j]**2)*np.exp(-0.5*((x_new-means[j])/stds[j])**2)).prod()*p[j]:.12f}" )

تصلنا

Probability for class 0: 0.000000000263
Probability for class 1: 0.000000044359
Probability for class 2: 0.000325643718

بالطبع ، هؤلاء الاحتمالات (لا ينبغي أن نسميها بهذه الطريقة) لا تضيف ما يصل إلى واحد لأننا تجاهلنا المقام. ومع ذلك ، هذه ليست مشكلة حيث يمكننا فقط أخذ هذه الاحتمالات غير الطبيعية وقسمتها على مجموعها ، ثم ستجمع ما يصل إلى واحد. إذن ، بقسمة هذه القيم الثلاث على مجموعها البالغ حوالي 0.00032569 ، نحصل على

 

غاوسيان ساذج بايز ، شرح
صورة المؤلف.

 

فائز واضح كما توقعنا. الآن ، دعونا ننفذها!

هذا التنفيذ غير فعال إلى حد بعيد ، وليس مستقرًا عدديًا ، فهو يخدم غرضًا تعليميًا فقط. لقد ناقشنا معظم الأشياء ، لذا يجب أن يكون من السهل متابعتها الآن. يمكنك تجاهل كل ملفات check وظائف ، أو قراءة مقالتي قم ببناء برنامج scikit-Learn المخصص الخاص بك إذا كنت مهتمًا بما يفعلونه بالضبط.

فقط لاحظ أنني قمت بتطبيق ملف predict_proba الطريقة الأولى لحساب الاحتمالات. طريقة predict فقط استدعاء هذه الطريقة وإرجاع الفهرس (= class) بأعلى احتمال باستخدام دالة argmax (هناك مرة أخرى!). الفصل ينتظر الصفوف من 0 إلى k-1 ، أين k هو عدد الفصول.

import numpy as np
from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.utils.validation import check_X_y, check_array, check_is_fitted class GaussianNaiveBayesClassifier(BaseEstimator, ClassifierMixin): def fit(self, X, y): X, y = check_X_y(X, y) self.priors_ = np.bincount(y) / len(y) self.n_classes_ = np.max(y) + 1 self.means_ = np.array( [X[np.where(y == i)].mean(axis=0) for i in range(self.n_classes_)] ) self.stds_ = np.array( [X[np.where(y == i)].std(axis=0) for i in range(self.n_classes_)] ) return self def predict_proba(self, X): check_is_fitted(self) X = check_array(X) res = [] for i in range(len(X)): probas = [] for j in range(self.n_classes_): probas.append( ( 1 / np.sqrt(2 * np.pi * self.stds_[j] ** 2) * np.exp(-0.5 * ((X[i] - self.means_[j]) / self.stds_[j]) ** 2) ).prod() * self.priors_[j] ) probas = np.array(probas) res.append(probas / probas.sum()) return np.array(res) def predict(self, X): check_is_fitted(self) X = check_array(X) res = self.predict_proba(X) return res.argmax(axis=1)

اختبار التنفيذ

على الرغم من أن الشفرة قصيرة جدًا ، إلا أنها لا تزال طويلة جدًا للتأكد من أننا لم نرتكب أي أخطاء. لذا ، دعنا نتحقق من أسعارها مقابل مصنف scikit-Learn GaussianNB.

my_gauss = GaussianNaiveBayesClassifier()
my_gauss.fit(X, y)
my_gauss.predict_proba([[-2, 5], [0,0], [6, -0.3]])

النتائج

array([[8.06313823e-07, 1.36201957e-04, 9.99862992e-01], [1.00000000e+00, 4.23258691e-14, 1.92051255e-11], [4.30879705e-01, 5.69120295e-01, 9.66618838e-27]])

التنبؤات باستخدام predict الطريقة هي

# my_gauss.predict([[-2, 5], [0,0], [6, -0.3]])
array([2, 0, 1])

الآن ، دعونا نستخدم scikit-Learn. رمي بعض التعليمات البرمجية

from sklearn.naive_bayes import GaussianNB gnb = GaussianNB()
gnb.fit(X, y)
gnb.predict_proba([[-2, 5], [0,0], [6, -0.3]])

عائدات

array([[8.06314158e-07, 1.36201959e-04, 9.99862992e-01], [1.00000000e+00, 4.23259111e-14, 1.92051343e-11], [4.30879698e-01, 5.69120302e-01, 9.66619630e-27]])

تبدو الأرقام مشابهة نوعًا ما لأرقام المصنف الخاص بنا ، لكنها قليلة قليلاً في الأرقام القليلة الأخيرة المعروضة. هل فعلنا أي خطأ؟ رقم يستخدم إصدار scikit-Learn فقط معلمة تشعبية أخرى var_smoothing=1e-09 . إذا قمنا بتعيين هذا على صفر، نحصل على أرقامنا بالضبط. ممتاز!

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

 

غاوسيان ساذج بايز ، شرح

مناطق القرار مع 3 نقاط جديدة. صورة المؤلف.

 

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

تابعنا من خلال حساب بعض الأمثلة وجمع بعض الأجزاء المفيدة من التعليمات البرمجية في الطريق. أخيرًا ، قمنا بتطبيق مصنف Gaussian naive Bayes الكامل بطريقة تعمل بشكل جيد مع scikit-Learn. هذا يعني أنه يمكنك استخدامه في خطوط الأنابيب أو البحث في الشبكة ، على سبيل المثال.

في النهاية ، أجرينا فحصًا بسيطًا للعقل عن طريق استيراد مُصنِّف بايز غاوس الساذج الخاص بـ scikit-learns واختبار ما إذا كان كلا المصنفين لدينا و scikit-learn ينتج نفس النتيجة. كان هذا الاختبار ناجحًا.

 
 
دكتور روبرت كوبلر هو عالم بيانات في Publicis Media ومؤلف في Towards Data Science.

 
أصلي. تم إعادة النشر بإذن.
 

الطابع الزمني:

اكثر من KD nuggets