2009-06-09 5 views
5

人が特定の製品を購入するかどうかについては、購入するために1つ、買わないには0つのデータが入ってくる(自動コールセンターへの呼び出し)。他の可能性を前もって与えて確率を見積もる

このデータを使用して、特定の製品を購入する見込みの確率を作成したいが、購入した/購入しなかった人の数の履歴データを比較的少なくして、その製品。

友人は、ベイズ確率を使用して、「事前確率分布」を立てることによって確率推定を助けることをお勧めします。本質的にこれは、実際のデータを考慮に入れる前に見たいものに関する情報です。

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

priorProbabilitiesが、私は以前の製品に見てきた確率の配列があり、この方法:

は、だから私がやりたいものをこの署名(Java)のようなものを持っているメソッドを作成していますこの確率に対する事前分布を作成するために使用する。 buyCountとnoBuyCountは、この製品固有の実際のデータです。データと前回のデータを考慮して、ユーザーの購入確率を見積もりたいと思います。これはメソッドからdoubleとして返されます。

私は、数学的に完璧な解決策は必要ありません。これは、均一またはフラットな事前確率(すなわち、確率= buyCount /(buyCount + noBuyCount))より優れています。私は数学的表記法よりもソースコードにははるかに精通しているので、説明にコードを使うことができれば分かります。

+1

本当にクールな問題、と私は私が正確なベイズソリューションを知っていると思うが、それはまだAKA Pythonのソース、あなたが実行可能な擬似コードを気にします(コードにしばらく時間がかかるだろう? Javaで錆びついている... ;-)。 –

+0

アレックス、はい - Pythonまたは擬似Pythonはまったく問題ありません! – sanity

+2

これはプログラミング上の問題とは思われません。これは、Javaメソッドスタブに包まれた理論上の数学的質問です。 –

答えて

2

ここでベイズ計算し、1例/テストです:

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 

。定義によると、購入確率は、先験的確率の集合の中で常に最も低いものと最も高いものとの間にあることに留意されたい。それがあなたが望むものでなければ、誰も購入しない2つの「疑似製品」(p = 0.0)、誰かがいつも買うもの(p = 1.0)を導入することで、実際の観測に比べてより多くの重みを持ち、過去の製品に関する統計量は少ない。私たちがここにいることをすれば、我々が得る:この新製品は、これまで、以前に販売いずれかより悪い、またはそれらのいずれかよりも良いかもしれ性は低いが、不可能ではない可能性を考慮するために(fudgingの

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 

中級レベル)は容易に想像することができます(estimateProbabilityの引数にベクトルpriorWeightsを追加することにより、人工的な0.0と1.0の確率に低い重みを与えます)。

この種のことは、今、私が働くことをビジネスインテリジェンスでアプリケーションを開発し、私は一日何をすべきかの実質的な部分ですが、私はちょうどそれを十分に得ることができない... - !)

+0

ありがとうアレックス、誰かが質問を高く評価してうれしいです:-)これは間違いなく正しいようですが、明日まであなたの答えを詳細に調べることはできません。つまり、私は今あなたの答えを受け入れることができてうれしく思います:-) – sanity

+0

是非、チェックアウトしてください(必要に応じてJavaにトランスコードしますが、迅速で汚れたテストのためにJythonを検討してください)この質問や新しいこと、私は少なくともこれはちょうど良い仕事を得るためにあなたのように熱心です! - )*長いライブベイズ...!)*)* –

0

あなたがしようとしているようなサウンドはAssociation Rule Learningです。私は今すぐあなたにコードを提供する時間がありませんが、私はWEKAの方向にあなたを指摘します。これはJavaのための素晴らしいオープンソースのデータマイニングツールキットです。そこには、あなたの問題を解決するのに役立つ興味深いものがたくさんあるはずです。

+0

これは興味深いですが、私はそれが私が描写している特定の問題を解決する方法を見ていません: -/ – sanity

+0

+1は、無知/怠惰に対抗します。これは非常に良い提案です –

+0

スティーブン、私はARLのリンク先の記事全体を読んだことがあります。おそらくあなたはこの提案が私が概説した特定の問題を解決する方法を説明することができますか? – sanity

0

私が見ているように、配布に関して何か手掛かりがない限り、一様分布を使用することができます。それとも、この商品とAmazonのファッションで同じ人が前に買った商品との関係を作ることを話しているのですか?「この商品を購入する人々も購入します...」

+0

分布に関するヒントは、メソッドのpriorProbabilitiesパラメータで提供されます。これは、他の製品で見つかった購入確率のリストです。この製品の購入確率の事前分布を作成するために(うまくいけば)使用することができます。 – sanity

+0

IMHO、あなたは買物かどうか他のいくつかのパラメータ(例えば、年齢、性別、国、時間、時間、他の購入された製品など)と相関させる必要があります。それ以外の場合は、累積購入率を使用した一様分布です。 – tekBlues

+0

本当にこれが私が今見つけたすべてです。通常、私は年齢や性別などのメタデータと関連付けることを検討していますが、問題は単にそれに十分なデータがないことです。 私の挑戦は、最小限のデータ量(おそらく数百コール、典型的な購入率は約5-10%)に基づいて購入する可能性が最も高い確率を考え出すことです。 データが十分でないため、年齢や性別に基づいてデータを単純にパーティション化することはできません。 – sanity

2

A困難な計算なしでこれを行う本当に簡単な方法は、購入したか購入しなかったかの仮想顧客を追加して、人為的に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] 
関連する問題