Оценка вероятности с учетом других вероятностей из предыдущего - PullRequest
5 голосов
/ 09 июня 2009

У меня есть куча данных (звонки в автоматизированный центр обработки вызовов) о том, покупает ли человек конкретный продукт, 1 за покупку, 0 за не покупку.

Я хочу использовать эти данные для создания предполагаемой вероятности того, что человек купит конкретный продукт, но проблема в том, что мне может потребоваться сделать это с относительно небольшими историческими данными о том, сколько людей купили / не купили это продукт.

Друг порекомендовал, чтобы с байесовской вероятностью вы могли «помочь» в оценке вероятности, придумав «предварительное распределение вероятностей», по сути это информация о том, что вы ожидаете увидеть, до учета фактических данных.

Итак, я хотел бы создать метод с такой сигнатурой (Java):

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

priorProbabilities - это массив вероятностей, которые я видел для предыдущих продуктов, которые этот метод использовал бы для создания предварительного распределения этой вероятности. buyCount и noBuyCount - это фактические данные, характерные для этого продукта, из которых я хочу оценить вероятность покупки пользователем, учитывая данные и предыдущие. Возвращается из метода как double.

Мне не нужно математически совершенное решение, просто что-то, что будет лучше, чем предыдущая униформа или флет (т.е. вероятность = buyCount / (buyCount + noBuyCount) ). Поскольку я гораздо лучше знаком с исходным кодом, чем с математическими обозначениями, я был бы признателен, если бы люди могли использовать код в своих объяснениях.

Ответы [ 4 ]

2 голосов
/ 09 июня 2009

Действительно простой способ сделать это без какой-либо сложной математики - искусственно увеличить 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 голосов
/ 09 июня 2009

Вот байесовские вычисления и один пример / тест:

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).

Подобные вещи являются существенной частью того, что я делаю весь день, сейчас, когда я работаю над разработкой приложений в Business Intelligence, но мне просто не хватает этого ...! -)

0 голосов
/ 09 июня 2009

На мой взгляд, лучшее, что вы можете сделать, - это использовать равномерный дистрибутив, если у вас нет какой-либо подсказки относительно дистрибутива. Или вы говорите о том, чтобы установить отношения между этими продуктами и продуктами, ранее купленными одним и тем же человеком в Amazon Fashion "люди, которые покупают этот продукт, также покупают ..." ??

0 голосов
/ 09 июня 2009

Похоже, то, что вы пытаетесь сделать, это Обучение правилам ассоциации . Сейчас у меня нет времени, чтобы предоставить вам какой-либо код, но я покажу вам направление WEKA , которое является фантастическим набором инструментов для анализа данных с открытым исходным кодом для Java. Там вы найдете множество интересных вещей, которые помогут вам решить вашу проблему.

...