Pergunta

Eu tenho um monte de dados que entram (chamadas para um callcenter automatizado) sobre se ou não uma pessoa compra um determinado produto, 1 para comprar, 0 para não comprar.

Eu quero usar esses dados para criar uma probabilidade estimada que uma pessoa vai comprar um determinado produto, mas o problema é que eu preciso fazê-lo com os dados relativamente pouco histórico sobre quantas pessoas compraram / não comprar que produto.

Um amigo recomendou que com Bayesian probabilidade você pode "ajudar" a sua estimativa de probabilidade por surgir com uma "distribuição de probabilidade prévia", essencialmente, esta é a informação sobre o que você espera para ver, antes de tomar em conta os dados reais.

Então, o que eu gostaria de fazer é criar um método que tem algo como esta assinatura (Java):

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

priorProbabilities é uma matriz de probabilidades que eu vi de produtos anteriores, que este método seria usar para criar uma distribuição prévia para essa probabilidade. buyCount e noBuyCount são específicas de dados reais a este produto, a partir do qual eu quero para estimar a probabilidade da compra do usuário, dada a dados ea prévio. Esta é devolvido a partir do método como um duplo.

Eu não preciso de uma solução matematicamente perfeita, apenas algo que vai fazer melhor do que um uniforme ou apartamento antes (ie. probabilidade = buyCount / (buyCount + noBuyCount) ). Desde que eu sou muito mais familiarizado com o código fonte de notação matemática, eu apreciaria se as pessoas pudessem usar o código em sua explicação.

Foi útil?

Solução

Aqui está o cálculo Bayesian e um exemplo / test:

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

saída é:

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

que concorda com a minha computação pela mão para este caso simples. Note-se que a probabilidade de compra, por definição, estará sempre entre o menor eo maior entre o conjunto de probabilidades a priori; se isso não é o que você quer que você pode querer introduzir um pouco de fudge através da introdução de duas "pseudo-produtos", aquele que ninguém nunca vai comprar (p = 0,0), que ninguém vai sempre comprar (p = 1.0) - o que dá mais peso às observações reais, escasso como eles podem ser, e menos com as estatísticas sobre produtos anteriores. Se fizermos isso aqui, temos:

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

Os níveis intermediários de falsificação (a conta para a possibilidade improvável mas não impossível que este novo produto pode ser pior do que qualquer um já vendido anteriormente, ou melhor do que qualquer um deles) pode ser facilmente imaginado (dar um peso inferior ao artificial 0.0 e 1,0 probabilidades, adicionando um vetor priorWeights aos argumentos de estimateProbability).

Este tipo de coisa é uma parte substancial do que eu faço todos os dias, agora que eu trabalho aplicações em Business Intelligence em desenvolvimento, mas eu simplesmente não consegue obter o suficiente dele ... -!)

Outras dicas

Uma maneira realmente simples de fazer isso sem qualquer matemática difícil é aumentar buyCount e noBuyCount artificialmente pela adição de clientes virtuais que comprou ou não comprar o produto. Você pode ajustar o quanto você acredita em cada probabilidade anterior em particular em termos de quantos clientes virtuais você acha que vale a pena.

Em pseudocódigo:

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]

Parece que você está tentando fazer é Associação regra de aprendizagem . Eu não tenho tempo agora para lhe fornecer qualquer código, mas vou apontá-lo na direção de WEKA que é uma fonte aberta kit de ferramentas de mineração de dados fantástico para Java. Você deve encontrar muitas coisas interessantes lá que o ajudarão a resolver o seu problema.

A meu ver, o melhor que você pode fazer é usar a distribuição uniforme, a menos que tenha alguma pista a respeito da distribuição. Ou você está falando sobre como fazer uma relação entre estes produtos e produtos previamente comprados pela mesma pessoa na Amazônia Fashion "pessoas que compram este produto também compram ..." ??

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top