0

I'm trying to make a function to calculate Bayesian probabilities in python without using scipy, and while I can get the function to print a single result, I'm having trouble getting it to iterate multiple times, using the previous result in the next calculation.

Here's what I have so far:

def prob_given_positive (prior, false_positive_rate, true_positive_rate):
  pdgp = (true_positive_rate * prior) / (false_positive_rate)
  for i in range(10):
    probability = (true_positive_rate * pdgp) / (false_positive_rate)
    print (probability)

prob_given_positive(.001,.08,1)

This is the print out I get

0.15625
0.15625
0.15625
0.15625
0.15625
0.15625
0.15625
0.15625
0.15625
0.15625

What I'd like instead is 10 different probabilities, where the 'prior' is replaced each time by the previous calculation's 'probability' or 'pdgp' ...

Guidance on what I'm missing?

ekselan
  • 137
  • 1
  • 10
  • 1
    You declare a variable i in your for loop, but never use it in the body. And none of the other variables are actually modified during an iteration so the output stays the same – Delphi1024 Mar 18 '20 at 22:52

3 Answers3

0

I'm not a fan of the saying "Insanity is doing the same thing over and over again and expecting different results", but even if it's not insanity, it's bad programming. Nothing's changing from one iteration of your for-loop to the other, so why do you expect different outputs?

using the previous result in the next calculation.

Where do you think you're telling Python you're using the previous result in the next calculation?

If you want to have the output from iteration to be input for the next, you need to have something that assigns the output to something. For instance (no guarantees that this is the correct code for what you want, just an example of the output from one iteration being used as input in the next):

def prob_given_positive (prior, false_positive_rate, 
  true_positive_rate):
  pdgp = (true_positive_rate * prior) / (false_positive_rate)
  for i in range(10):
    posterior = (true_positive_rate * pdgp) / 
      (false_positive_rate)
    prior = posterior
    pdgp = (true_positive_rate * prior) / (false_positive_rate)
  print (probability)

You might also look at whether there's a closed form formula for a n-th iterated Bayesian update.

Acccumulation
  • 3,491
  • 1
  • 8
  • 12
0

Well, what you want is the previous value of probability to become the next value of probability, so the easiest thing is to just get rid of that variable entirely and just use pdgp throughout, as in:

def prob_given_positive (prior, false_positive_rate, true_positive_rate):
  pdgp = (true_positive_rate * prior) / (false_positive_rate)
  for i in range(10):
    pdgp = (true_positive_rate * pdgp) / (false_positive_rate)
    print (pdgp)

prob_given_positive(.001,.08,1)

(This assumes that the formula you provide is actually correct!)

Note that the pdgp on the left-hand side of the equation is different from that on the right hand side -- that's why this works. The right-hand side of an expression with = is an instruction to the computer for making a new value which it then assigns to the left-hand side.

Actually, it can be simplified a bit further -- the long equation in the second line is basically the same as the equation as the one inside the loo -- except the prior is replaced by the posterior. So you can instead do:

def prob_given_positive (prior, false_positive_rate, true_positive_rate):
  pdgp = prior
  for i in range(10+1):
    pdgp = (true_positive_rate * pdgp) / (false_positive_rate)
    print (pdgp)

This uses a principle called "don't repeat yourself" or "DRY" -- this way the main formula only appears once.

But also note that your function doesn't return anything. You might want to store the values in a list as they are created, and return that:

def prob_given_positive (prior, false_positive_rate, true_positive_rate):
  result = [] ## empty list
  pdgp = prior
  for i in range(10+1):
    pdgp = (true_positive_rate * pdgp) / (false_positive_rate)
    result.append(pdgp)
  return(result)

print(prob_given_positive(0.001, 0.08, 1))
Andrew Jaffe
  • 26,554
  • 4
  • 50
  • 59
0

I do agree with the answers, but I am not sure what the "variable" factor is here for continuously getting new probabilities based on a possible previous "prior" is what I am thinking.

It is a little ambiguous but let say your "false_positive_rate" and "true_positive_rate" are consistent and variable change is "prior", you could do something like this, btw I think the other answers do a great job and there are probably many other ways of doing this:

def prob_given(pdgp=None, false_positive_rate=None, true_positive_rate=None):
  getallprobs = []
  for newpdgp in pdgp:
    probability = (true_positive_rate * newpdgp) / (false_positive_rate)
    getallprobs.append(probability)

  return getallprobs

def usePrevPdgp(prior,false_positive_rate, true_positive_rate):
  storePdgps = []
  while True:
   for i in range(10):
     prior += prior
     pdgp = (true_positive_rate * prior) / (false_positive_rate)
     storePdgps.append(pdgp)

   latestpdgp = [i for i in storePdgps]
   return latestpdgp

if __name__ == "__main__":
   newPdgp = usePrevPdgp(.001,.08,1)
   getNewProb = prob_given(newPdgp, .08, 1)
   print(getNewProb)
de_classified
  • 1,927
  • 1
  • 15
  • 19