5

我有一堆关于一个人是否购买特定产品的数据(打给自动呼叫中心的电话),1 表示购买,0 表示不购买。

我想使用这些数据来创建一个人购买特定产品的估计概率,但问题是我可能需要使用相对较少的历史数据来做这件事,即有多少人购买/没有购买该产品。

一位朋友建议使用贝叶斯概率,您可以通过提出“先验概率分布”来“帮助”您的概率估计,本质上这是在考虑实际数据之前关于您期望看到的信息。

所以我想做的是创建一个具有类似签名(Java)的方法:

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

priorProbabilities 是我在以前的产品中看到的一组概率,该方法将使用它来创建此概率的先验分布。buyCount 和 noBuyCount 是该产品特定的实际数据,我想从中估计用户购买的概率,给定数据和先验。这是从方法作为双精度返回的。

我不需要数学上完美的解决方案,只需要比统一或平坦先验更好的解决方案(即概率 = buyCount / (buyCount+noBuyCount))。由于我对源代码比对数学符号更熟悉,如果人们可以在解释中使用代码,我将不胜感激。

4

4 回答 4

2

这是贝叶斯计算和一个示例/测试:

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 概率给予较低的权重) ,通过将向量priorWeights 添加到estimateProbability的参数)。

这种事情是我整天工作的重要组成部分,现在我在商业智能中开发应用程序,但我就是无法获得足够的......!-)

于 2009-06-09T02:28:03.643 回答
2

一个非常简单的方法是通过添加购买或未购买产品的虚拟客户来人为地增加 buyCount 和 noBuyCount。您可以根据您认为值得多少虚拟客户来调整您对每个特定先验概率的信任程度。

在伪代码中:

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]
于 2009-06-09T07:05:53.143 回答
0

听起来您正在尝试做的是关联规则学习。我现在没有时间为您提供任何代码,但我会为您指明WEKA的方向,这是一个出色的 Java 开源数据挖掘工具包。你应该在那里找到很多有趣的东西来帮助你解决问题。

于 2009-06-09T01:06:08.550 回答
0

在我看来,你能做的最好的就是使用均匀分布,除非你对分布有一些线索。或者您是在谈论在亚马逊时尚“购买该产品的人也购买......”的同一个人之前购买的产品之间建立关系??

于 2009-06-09T01:13:43.153 回答