估计给出来自先验的其他概率的概率

时间:2009-06-09 00:54:08

标签: java statistics probability

我有一大堆数据(调用自动呼叫中心),关于一个人是否购买特定产品,1是购买,0是不购买。

我想用这些数据来估算一个人购买特定产品的估计概率,但问题是我可能需要用相对较少的历史数据来做这件事,这些数据是关于有多少人购买/未购买的产品

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

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

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

priorProbabilities是我在以前的产品中看到的概率数组,该方法将用于为此概率创建先验分布。 buyCount和noBuyCount是该产品特有的实际数据,我想根据数据和先前的数据估算用户购买的概率。这是从方法返回的双倍。

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

4 个答案:

答案 0 :(得分: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概率,通过向estimateProbability的参数添加向量previousWeights)。

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

答案 1 :(得分: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]

答案 2 :(得分:0)

听起来你要做的就是Association Rule Learning。我现在没有时间为您提供任何代码,但我将指向WEKA的方向,这是一个非常棒的Java开源数据挖掘工具包。你应该找到很多有趣的东西来帮助你解决问题。

答案 3 :(得分:0)

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