سؤال

لدي مجموعة من البيانات القادمة (المكالمات إلى Callcenter الآلي) حول ما إذا كان الشخص يشتري منتجا معينا، 1 لشراء، 0 لعدم الشراء.

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

أوصى أحد الأصدقاء بأنه مع احتمال Bayesian يمكنك "مساعدة" تقدير احتمالاتك من خلال الخروج ب "توزيع مسبق الاحتمال"، وهذا هو أساسا هو معلومات حول ما تتوقع رؤيته، قبل مراعاة البيانات الفعلية.

إذن ما أود القيام به هو إنشاء طريقة لها شيء مثل هذا التوقيع (Java):

double estimateProbability(double[] priorProbabilities, int buyCount, int noBuyCount);

يعد مسبق الأبواط عبارة عن مجموعة من الاحتمالات التي رأيتها في المنتجات السابقة، والتي ستستخدم هذه الطريقة لإنشاء توزيع مسبق لهذه الاحتمال. BuyCount و Nobuycount هي البيانات الفعلية الخاصة بهذا المنتج، والتي أريد تقدير احتمال شراء المستخدم، بالنظر إلى البيانات وقبل. يتم إرجاع هذا من الطريقة مزدوجة.

لا أحتاج إلى حل مثالي رياضيا، فقط شيء سيفعل أفضل من موحدة أو مسطحة مسبقة (أي. احتمال = buycount / (buycount + nobuycount)). نظرا لأنني أكثر دراية بكثير من التعليمات البرمجية المصدرية من الترميز الرياضي، فأنا أقدر ذلك إذا كان يمكن للناس استخدام التعليمات البرمجية في تفسيرهم.

هل كانت مفيدة؟

المحلول

إليك حساب Bayesian ومثال واحد / اختبار:

def estimateProbability(priorProbs, buyCount, noBuyCount):
  # first, estimate the prob that the actual buy/nobuy counts would be observed
  # given each of the priors (times a constant that's the same in each case and
  # not worth the effort of computing;-)`
  condProbs = [p**buyCount * (1.0-p)**noBuyCount for p in priorProbs]
  # the normalization factor for the above-mentioned neglected constant
  # can most easily be computed just once
  normalize = 1.0 / sum(condProbs)
  # so here's the probability for each of the prior (starting from a uniform
  # metaprior)
  priorMeta = [normalize * cp for cp in condProbs]
  # so the result is the sum of prior probs weighed by prior metaprobs
  return sum(pm * pp for pm, pp in zip(priorMeta, priorProbs))

def example(numProspects=4):
  # the a priori prob of buying was either 0.3 or 0.7, how does it change
  # depending on how 4 prospects bought or didn't?
  for bought in range(0, numProspects+1):
    result = estimateProbability([0.3, 0.7], bought, numProspects-bought)
    print 'b=%d, p=%.2f' % (bought, result)

example()

الإخراج هو:

b=0, p=0.31
b=1, p=0.36
b=2, p=0.50
b=3, p=0.64
b=4, p=0.69

الذي يوافق على حسابي الفردي لهذه الحالة البسيطة. لاحظ أن احتمال الشراء، بحكم التعريف، سيكون دائما بين الأدنى والأعلى من بين مجموعة من الاحتمالات البولية؛ إذا لم يكن هذا ليس ما تريد أن ترغب في إدخال حلوى صغيرة من خلال إدخال اثنين من "منتجات زائفة"، واحدة لا أحد سوف يشتري من أي وقت مضى (p = 0.0)، واحد أن أي شخص سوف يشتري دائما (p = 1.0) - وهذا يعطي زيادة الوزن إلى الملاحظات الفعلية، نادرة لأنها قد تكون، وأقل لإحصاءات المنتجات الماضية. إذا فعلنا ذلك هنا، نحصل على:

b=0, p=0.06
b=1, p=0.36
b=2, p=0.50
b=3, p=0.64
b=4, p=0.94

المستويات المتوسطة من الاختزاظ (لحساب غير مرجح ولكن ليس من المستحيل أن يكون هذا المنتج الجديد قد يكون أسوأ من أي شخص تم بيعه سابقا، أو أفضل من أي منهم) يمكن أن يتصور بسهولة (إعطاء وزن أقل إلى الاحتمالات الاصطناعية 0.0 و 1.0 ، عن طريق إضافة ناقلات Pretweights إلى estimateProbabilityالحجج).

هذا النوع من الأشياء هو جزء كبير من ما أقوم به طوال اليوم، والآن أعمل في تطوير الطلبات في ذكاء الأعمال، لكنني لا أستطيع الحصول على ما يكفي من ذلك ... -)

نصائح أخرى

طريقة بسيطة حقا للقيام بذلك دون أي أي رياضيات صعبة هي زيادة BuyCount و Nobuycount مصطنع عن طريق إضافة عملاء افتراضيين إما اشتروا أو لم يشترون المنتج. يمكنك ضبط مقدار ما تؤمن بكل احتمال مسبق لكل منهما من حيث عدد العملاء الظاهريين الذين تعتقدون أنه يستحق.

في pseudocode:

def estimateProbability(priorProbs, buyCount, noBuyCount, faithInPrior=None):
    if faithInPrior is None: faithInPrior = [10 for x in buyCount]
    adjustedBuyCount = [b + p*f for b,p,f in 
                                zip(buyCount, priorProbs, faithInPrior]
    adjustedNoBuyCount = [n + (1-p)*f for n,p,f in 
                                zip(noBuyCount, priorProbs, faithInPrior]
    return [b/(b+n) for b,n in zip(adjustedBuyCount, adjustedNoBuyCount]

يبدو وكأنه ما تحاول القيام به هو التعلم حكم الرابطة. وبعد ليس لدي وقت الآن لتزويدك بأي رمز، لكنني سأشير إليك في اتجاه Weka. وهي مجموعة أدوات تعدين بيانات مفتوحة مفتوحة المصدر رائعة ل Java. يجب أن تجد الكثير من الأشياء المثيرة للاهتمام التي ستساعدك في حل مشكلتك.

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top