كتاب "البرمجة الاحتمالية في بيثون: الاستدلال والخوارزميات النظرية الافتراضية"

صورة مرحبا ، habrozhiteli! طرق Bayesian تخيف الصيغ من العديد من المتخصصين في تكنولوجيا المعلومات ، ولكن الآن لا يمكنك القيام به دون تحليل الإحصاءات والاحتمالات. يتحدث كاميرون ديفيدسون-بيلون عن طريقة بايزي من وجهة نظر مبرمج عملي يعمل مع PyMC بلغات متعددة الوظائف ومكتبات NumPy و SciPy و Matplotlib. بالكشف عن دور استنتاجات Bayesian في اختبار A / B ، وتحديد الاحتيال والمهام العاجلة الأخرى ، لن تفهم بسهولة هذا الموضوع غير التافه فحسب ، بل ستبدأ أيضًا في تطبيق المعرفة المكتسبة لتحقيق أهدافك.

مقتطف: 4.3.3. مثال: فرز التعليقات على رديت


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


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

النظر في موقع رديت شعبية (أنا عمدا لا توفر روابط لذلك ، لأن رديت سيئة السمعة لجذب المستخدمين ، وأخشى أنك لن تعود أبدا إلى كتابي). يوجد في هذا الموقع العديد من الروابط لقصص وصور مختلفة ، والتعليقات على هذه الروابط تحظى أيضًا بشعبية كبيرة. يمكن لمستخدمي الموقع (الذي يطلق عليه عادةً الكلمة redditor1) التصويت لصالح أو ضد كل تعليق (ما يسمى بـ upvotes و downvotes). يقوم Reddit بفرز التعليقات افتراضيًا بترتيب تنازلي. كيفية تحديد التعليقات التي هي الأفضل؟ وهي عادة ما تركز على المؤشرات العديدة التالية.

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

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

3. تصحيح للوقت . ضع في اعتبارك طريقة يتم فيها تقسيم الفرق بين إيجابيات وسلبيات حسب عمر التعليق ويتم الحصول على التردد ، على سبيل المثال ، الفرق في الثانية أو الدقيقة. يتبادر المثال المضاد فورًا إلى الذهن: عند استخدام خيار "في الثانية" ، سيكون التعليق الذي تم تركه قبل ثانية بتصويت "نعم" أفضل من اليسار قبل 100 ثانية مع 99 صوتًا "نعم". يمكن تجنب هذه المشكلة إذا كنت تفكر فقط في التعليقات التي تركت قبل ثوانٍ على الأقل. ولكن كيف تختار قيمة جيدة؟ هل هذا يعني أن جميع التعليقات المنشورة بعد ثوانٍ كانت سيئة؟ ستنتهي الحالة بمقارنة القيم غير المستقرة مع التعليقات (التعليقات الجديدة والقديمة).

4. القيمة . ترتيب التعليقات على نسبة عدد الأصوات المؤيدة لمجموع عدد الأصوات المؤيدة والمعارضة. هذا النهج يلغي مشكلة الطابع الزمني للتعليقات ، بحيث تحصل التعليقات المنشورة مؤخرًا ذات العلامات الجيدة على تصنيف عالي بنفس الاحتمال كتلك التي تركتها منذ فترة طويلة ، بشرط أن يكون لديها نسبة عالية نسبيًا من الأصوات إلى إجمالي عدد الأصوات. المشكلة في هذه الطريقة هي أن التعليق مع صوت واحد مؤيد (النسبة = 1.0) سيكون أفضل من التعليق مع 999 صوتًا مؤيدًا والآخر ضد (النسبة = 0.999) ، على الرغم من أنه من الواضح أن الثاني من هذه التعليقات من المحتمل أن تكون الأفضل.

كتبت "بالأحرى" لسبب ما. قد يتضح أن التعليق الأول بنص التصويت بنعم واحد هو حقًا أفضل من التعليق بنعم بنعم. من الصعب الموافقة على هذا البيان ، لأننا لا نعرف ما يمكن أن يكون 999 من الأصوات القادمة المحتملة للتعليق الأول. لنقل أنه قد يحصل على نتيجة 999 صوتًا مؤيدًا وليس تصويتًا واحدًا ضده ويكون أفضل من الثاني ، رغم أن هذا السيناريو ليس مرجحًا للغاية.

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

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

1. البيانات غير المتماثلة . تحتوي الغالبية المطلقة من التعليقات على عدد صغير جدًا من الأصوات ، ونتيجة لذلك ستكون نسب العديد من التعليقات قريبة من الحد الأقصى (انظر الرسم البياني "الثلاثي" في المثال مع مجموعة بيانات Kaggle في الشكل 4.4) وسيتم التوزيع "منحرف" بشدة. يمكنك محاولة مراعاة التعليقات التي يتجاوز عدد أصواتها قيمة عتبة معينة. ولكن هنا تنشأ صعوبات. على المرء أن يبحث عن توازن بين عدد التعليقات المتاحة ، من ناحية ، وقيمة عتبة أعلى مع دقة المقابلة المقابلة ، من ناحية أخرى.

2. بيانات متحيزة (تحتوي على خطأ منهجي) . يتكون Reddit من العديد من المنتديات الفرعية (subreddits). مثالان: r / aww مع صور حيوانات مضحكة و r / سياسة. من المرجّح أن يختلف سلوك المستخدمين عند التعليق على هذين المفتاحين الفرعيين لـ Reddit بشكل جذري: في الغالب ، من المرجح أن يتم لمس الزائرين وأن يتصرفوا بطريقة ودية ، مما يؤدي إلى عدد أكبر من الأصوات لصالحه ، مقارنةً بالثاني ، حيث الآراء في التعليقات من المرجح أن تتباعد.

في ضوء ما تقدم ، يبدو لي أنه من المنطقي استخدام توزيع موحد بشكل مسبق.

الآن يمكننا حساب التوزيع الخلفي للنسبة الفعلية للأصوات المؤيدة. يتم استخدام البرنامج النصي comments_for_top_reddit_pic.py لقص التعليقات من صورة Reddit الحالية الأكثر شيوعًا. في الكود التالي ، قمنا بإلغاء تعليقات Reddit المتعلقة بالصورة [3]: http://i.imgur.com/OYsHKlH.jpg.

from IPython.core.display import Image #       %run #   i-   . %run top_pic_comments.py 2 

 [Output]: Title of submission: Frozen mining truck http://i.imgur.com/OYsHKlH.jpg 

 """ Contents:       Votes:   NumPy  ""  ""    """ n_comments = len(contents) comments = np.random.randint(n_comments, size=4) print "  (    %d) \n -----------"%n_comments for i in comments: print '"' + contents[i] + '"' print " ""/"": ",votes[i,:] print 

 [Output]:   (   77) ----------- "Do these trucks remind anyone else of Sly Cooper?"  ""/"": [2 0] "Dammit Elsa I told you not to drink and drive."  ""/"": [7 0] "I've seen this picture before in a Duratray (the dump box supplier) brochure..."  ""/"": [2 0] "Actually it does not look frozen just covered in a layer of wind packed snow."  ""/"": [120 18] 

مع الأصوات N ونسبة فعلية معينة من الأصوات "لـ" p ، فإن عدد الأصوات "لـ" يشبه المتغير العشوائي ذو الحدين مع المعلمتين p و N (الحقيقة هي أن النسبة الفعلية للأصوات "لـ" تعادل احتمال إجراء تصويت على "بالمقارنة مع التصويت" ضد "مع N الأصوات المحتملة / المحاكمات). نخلق وظيفة لاشتقاق لغة بايز فيما يتعلق بمجموعة الأصوات "لصالح" / "ضد" تعليق معين.

 import pymc as pm def posterior_upvote_ratio(upvotes, downvotes, samples=20000): """         ""  "",   ,    ,    . ,    . """ N = upvotes + downvotes upvote_ratio = pm.Uniform("upvote_ratio", 0, 1) observations = pm.Binomial("obs", N, upvote_ratio, value=upvotes, observed=True) # ;    MAP,     #       . map_ = pm.MAP([upvote_ratio, observations]).fit() mcmc = pm.MCMC([upvote_ratio, observations]) mcmc.sample(samples, samples/4) return mcmc.trace("upvote_ratio")[:] 

فيما يلي التوزيعات الناتجة الناتجة.

 figsize(11., 8) posteriors = [] colors = ["#348ABD", "#A60628", "#7A68A6", "#467821", "#CF4457"] for i in range(len(comments)): j = comments[i] label = u'(%d :%d )\n%s...'%(votes[j, 0], votes[j,1], contents[j][:50]) posteriors.append(posterior_upvote_ratio(votes[j, 0], votes[j,1])) plt.hist(posteriors[i], bins=18, normed=True, alpha=.9, histtype="step", color=colors[i%5], lw=3, label=label) plt.hist(posteriors[i], bins=18, normed=True, alpha=.2, histtype="stepfilled", color=colors[i], lw=3) plt.legend(loc="upper left") plt.xlim(0, 1) plt.ylabel(u"") plt.xlabel(u"  ''") plt.title(u"    '' \   "); 

 [Output]: [****************100%******************] 20000 of 20000 complete 

كما يمكن أن يرى من التين. 4.5 ، يتم "الضغط" بشدة على بعض التوزيعات ، بينما لدى البعض الآخر "ذيول" طويلة نسبيًا ، معربًا عن أننا لا نعرف بالضبط النسبة الفعلية للأصوات.

صورة

4.3.4. الفرز


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

أوصي باستخدام القيمة الأقل 95٪ المعقولة ، والتي يتم تعريفها على أنها القيمة ذات الاحتمال 5٪ فقط أن القيمة الفعلية للمعلمة تحتها (راجع الحد الأدنى لفاصل الثقة Bayesian). بعد ذلك ، نرسم التوزيعات الخلفية مع القيمة المرجحة الأقل بنسبة 95٪ (الشكل 4.6).

صورة

 N = posteriors[0].shape[0] lower_limits = [] for i in range(len(comments)): j = comments[i] label = '(%d :%d )\n%s…'%(votes[j, 0], votes[j,1], contents[j][:50]) plt.hist(posteriors[i], bins=20, normed=True, alpha=.9, histtype="step", color=colors[i], lw=3, label=label) plt.hist(posteriors[i], bins=20, normed=True, alpha=.2, histtype="stepfilled", color=colors[i], lw=3) v = np.sort(posteriors[i])[int(0.05*N)] plt.vlines(v, 0, 10 , color=colors[i], linestyles="—", linewidths=3) lower_limits.append(v) plt.legend(loc="upper left") plt.ylabel(u"") plt.xlabel(u"  ''") plt.title(u"    '' \   "); order = np.argsort(-np.array(lower_limits)) print order, lower_limits 

 [Output]: [3 1 2 0] [0.36980613417267094, 0.68407203257290061, 0.37551825562169117, 0.8177566237850703] 

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

لماذا يعتمد الفرز على هذا المقياس فكرة جيدة؟ الفرز وفقًا للقيمة الأقل 95٪ المعقولة يعني الحد الأقصى من الحذر عند إعلان أن التعليقات هي الأفضل. هذا هو ، حتى في أسوأ السيناريوهات ، إذا كنا نبالغ في تقدير نسبة الأصوات المؤيدة ، فمن المضمون أن تكون أفضل التعليقات في المقدمة. مع هذا الطلب ، يتم توفير الخصائص الطبيعية للغاية التالية.

1. من بين التعليقات التي لها نفس النسبة المرصودة من الأصوات "لـ" ، سيتم التعرف على التعليق ذي أعلى عدد من الأصوات باعتباره الأفضل (لأن الثقة أعلى بالنسبة للنسبة الأعلى).

2. من بين التعليقات التي لها نفس العدد من الأصوات ، يعتبر الأفضل هو التعليق مع عدد أكبر من الأصوات المؤيدة.

»يمكن الاطلاع على مزيد من المعلومات حول الكتاب على موقع الناشر
» المحتويات
» مقتطفات

خصم 25 ٪ على كوبون الباعة المتجولين - جافا سكريبت

عند دفع النسخة الورقية من الكتاب ، يتم إرسال كتاب إلكتروني عبر البريد الإلكتروني.

Source: https://habr.com/ru/post/ar456562/


All Articles