2009-06-09 38 views
5

trước đây Tôi có một loạt dữ liệu đến (gọi tới một trung tâm gọi tự động) về việc một người mua một sản phẩm cụ thể, 1 cho mua, 0 không mua.Ước tính xác suất cho các xác suất khác từ

Tôi muốn sử dụng dữ liệu này để tạo xác suất ước tính rằng một người sẽ mua một sản phẩm cụ thể, nhưng vấn đề là tôi có thể cần phải làm điều đó với dữ liệu lịch sử tương đối ít về số lượng người mua/không mua sản phẩm đó.

Một người bạn đề nghị rằng với xác suất Bayesian bạn có thể "giúp" ước tính xác suất bằng cách đưa ra "phân bố xác suất trước", về cơ bản đây là thông tin về những gì bạn mong đợi thấy trước khi tính đến dữ liệu thực tế.

Vì vậy, những gì tôi muốn làm là tạo ra một phương pháp mà có một cái gì đó giống như chữ ký này (Java):

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

priorProbabilities là một mảng của xác suất tôi đã nhìn thấy cho sản phẩm trước đó, trong đó phương pháp này sẽ sử dụng để tạo phân phối trước cho xác suất này. buyCount và noBuyCount là dữ liệu thực tế cụ thể cho sản phẩm này, từ đó tôi muốn ước tính xác suất của người dùng mua, được cung cấp dữ liệu và trước đó. Điều này được trả về từ phương thức này là gấp đôi.

Tôi không cần một giải pháp toán học hoàn hảo, chỉ cần một cái gì đó sẽ làm tốt hơn so với trước đó thống nhất hoặc bằng phẳng (ví dụ: xác suất = buyCount/(buyCount + noBuyCount)). Vì tôi quen thuộc hơn với mã nguồn hơn ký hiệu toán học, tôi sẽ đánh giá cao nếu mọi người có thể sử dụng mã trong lời giải thích của họ.

+1

vấn đề thực sự mát mẻ, và tôi nghĩ rằng tôi biết giải pháp Bayesian chính xác, nhưng nó vẫn sẽ mất một lúc để mã (bạn sẽ nhớ giả thực thi, nguồn AKA Python tôi? một tad gỉ với Java ... ;-). –

+0

Alex, vâng - Python hoặc giả python là hoàn toàn tốt đẹp! – sanity

+2

tôi không nghĩ rằng đây là một vấn đề lập trình cho mỗi se; nó là một câu hỏi toán học lý thuyết được bao bọc trong một phương thức java. –

Trả lời

2

Dưới đây là các tính toán Bayesian và một ví dụ/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() 

đầu ra là:

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 

mà đồng ý với tính toán bằng tay phải của tôi đối với trường hợp đơn giản này. Lưu ý rằng xác suất mua, theo định nghĩa, sẽ luôn là giữa mức thấp nhất và cao nhất trong số các xác suất trước; nếu đó không phải là những gì bạn muốn, bạn có thể giới thiệu một chút fudge bằng cách giới thiệu hai "sản phẩm giả", một sản phẩm không ai mua (p = 0.0), mà ai cũng sẽ mua (p = 1.0) - trọng lượng hơn để quan sát thực tế, khan hiếm như chúng có thể, và ít hơn để thống kê về các sản phẩm trong quá khứ. Nếu chúng ta làm điều đó ở đây, chúng tôi nhận được:

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 

mức Intermediate của fudging (chiếm cơ hội khó nhưng không phải không thể mà sản phẩm mới này có thể tồi tệ hơn bất kỳ ai bán trước đây, hoặc tốt hơn so với bất kỳ trong số họ) có thể dễ dàng được hình dung (cho trọng số thấp hơn tới xác suất 0.0 và 1.0 nhân tạo, bằng cách thêm một trọng số vector vào các đối số của estimateProbability).

Kiểu này mà là một phần quan trọng của những gì tôi làm cả ngày, bây giờ mà tôi làm việc phát triển ứng dụng trong Kinh doanh thông minh, nhưng tôi chỉ không thể có đủ của nó ... -!)

+0

Cảm ơn Alex, tôi rất vui vì ai đó đã đánh giá cao câu hỏi :-) Điều này chắc chắn có vẻ đúng nhưng tôi sẽ không thể kiểm tra câu trả lời của bạn chi tiết cho đến ngày mai. Điều đó đang được nói, tôi vui mừng chấp nhận câu trả lời của bạn bây giờ :-) – sanity

+0

Bằng mọi cách, hãy kiểm tra nó (chuyển mã sang Java khi cần thiết, nhưng hãy xem xét Jython để kiểm tra nhanh và bẩn) và lấy lại cho tôi, câu hỏi này hay câu hỏi mới, tôi ít nhất cũng quan tâm đến việc bạn làm việc này vừa đúng! -) * Bayes dài ...! -) * –

0

Âm thanh giống như những gì bạn đang cố gắng làm là Association Rule Learning. Tôi không có thời gian để cung cấp cho bạn bất kỳ mã nào, nhưng tôi sẽ chỉ cho bạn theo hướng WEKA là một bộ công cụ khai phá dữ liệu nguồn mở tuyệt vời cho Java. Bạn sẽ tìm thấy nhiều điều thú vị ở đó sẽ giúp bạn giải quyết vấn đề của mình.

+0

Điều này thật thú vị, nhưng tôi không thấy cách giải quyết vấn đề cụ thể mà tôi mô tả: -/ – sanity

+0

+1 để chống lại sự thiếu hiểu biết/lười biếng; đây là một gợi ý rất tốt –

+0

Steven, tôi đã đọc toàn bộ bài viết được liên kết trên ARL. Có lẽ bạn có thể giải thích cách đề xuất này giải quyết vấn đề cụ thể mà tôi phác thảo? – sanity

0

Như tôi thấy, tốt nhất bạn có thể làm là sử dụng phân phối đồng đều, trừ khi bạn có một số đầu mối liên quan đến phân phối. Hay bạn đang nói về việc tạo ra mối quan hệ giữa sản phẩm và sản phẩm này trước đó được mua bởi cùng một người trong Thời trang Amazon "những người mua sản phẩm này cũng mua ..." ??

+0

Các đầu mối liên quan đến phân phối được cung cấp trong tham số priorProbabilities cho phương thức. Đây là danh sách các xác suất mua hàng mà chúng tôi đã tìm thấy cho các sản phẩm khác - và nó có thể được sử dụng (hy vọng) để đưa ra phân phối trước cho xác suất mua của sản phẩm này. – sanity

+0

IMHO, bạn cần phải tương quan mua hoặc không mua với một số thông số khác (ví dụ: tuổi, giới tính. Quốc gia, thời gian trong năm, thời gian trong ngày, các sản phẩm khác đã mua, v.v ...). Nếu không, thông tin tốt nhất bạn có là phân phối đồng đều bằng cách sử dụng tỷ lệ mua tích lũy. – tekBlues

+0

Thực sự đó là tất cả những gì tôi đang tìm kiếm tại thời điểm này. Thông thường tôi sẽ tìm cách tương quan với siêu dữ liệu như tuổi tác và giới tính, nhưng vấn đề là chỉ đơn giản là không đủ dữ liệu cho điều đó. Thách thức của tôi ở đây là đưa ra xác suất chính xác nhất có thể về việc mua hàng dựa trên lượng dữ liệu tối thiểu (có lẽ chỉ có vài trăm cuộc gọi, trong đó tỷ lệ mua hàng điển hình là khoảng 5-10%). Phân vùng dữ liệu dựa trên độ tuổi hoặc giới tính đơn giản là không thể vì không có đủ dữ liệu cho việc này. – sanity

2

Một cách thực sự đơn giản để làm điều này mà không có bất kỳ toán học khó khăn nào là tăng buyCount và noBuyCount giả tạo bằng cách thêm khách hàng ảo mua hoặc không mua sản phẩm. Bạn có thể điều chỉnh số tiền bạn tin vào từng xác suất trước cụ thể về số lượng khách hàng ảo mà bạn cho là đáng giá.

Trong giả:

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] 
Các vấn đề liên quan