The levels of detail are:
1) I hate and fear log functions, is this a problem?
2) I want to know why we're using log functions, with minimal mathematics.
3) Maths is just super, and there's a good chance I already understand log functions, but...
I want to see how linguists do maths.
IMPORTANT: Level 1 is enough to do everything on this course.
That's it! But would you like to know a little more?
We multiply probabilities for multiple events.
Look at these awesome dice:
When you multiply probabilities they get really small
What if we roll 100 dice?
What is $\frac{1}{20^{100}}$ written in decimal?
1/(20**100)
7.888609052210118e-131
How small is that number?
What does 7.9 x $10^{-131}$ mean in terms of probability?
To give an extremely natural and relatable example:
What's the lesson here?
That's really very interesting thank you so much, but why should I care?
1/(20**249)
0.0
1/(20**249)
0.0
We broke Python
Log functions are a way for Python to deal with really really small numbers.
When do we use log functions?
In general, the procedure works like this:
1) Turn all the probabilities into log-probabilities
2) Do all the math stuff using the log-probabilities (so Python doesn't break in weird ways)
3) When all the math stuff is finished, turn the log-probabilities back into normal probabilities.
That's it! Onwards...
Here are the awesome dice again!
We can plot the probability of getting all 20s for increasing numbers of dice:
dice_probs = []
for i in range(300):
dice_probs.append(1/(20**i))
plt.plot(dice_probs)
dice_probs = []
for i in range(100):
dice_probs.append(1/(20**i))
plt.plot(dice_probs)
plt.ylim(-0.05,1.05)
plt.ylabel('probability all 20s')
plt.xlabel('Number of dice rolled')
Text(0.5, 0, 'Number of dice rolled')
That's incredibly boring and unhelpful: the probabilities get super small really quickly
What if we plot the logarithm of the probabilities?
dice_logprobs = []
for p in dice_probs:
dice_logprobs.append(np.log10(p))
plt.plot(dice_logprobs)
plt.ylabel('log probability of all 20s')
plt.xlabel('Number of dice rolled')
Text(0.5, 0, 'Number of dice rolled')
It's still a bit boring, but now it decreases linearly
Logarithms scale over orders of magnitude
That's why logarithm-transformed numbers are easier for computers to represent.
Remember:
How do we do the last bit?
We convert back by using the log-probability as the exponent
probs = [1, 0.1, 0.01, 0.001, 0.0001, 10**-42]
print('Initial probs: ', probs)
log_probs = []
converted_probs = []
for p in probs:
log_probs.append(np.log10(p))
print('Log probabilities:', log_probs)
for lp in log_probs:
converted_probs.append(10**lp)
print('Converted back: ', converted_probs)
Initial probs: [1, 0.1, 0.01, 0.001, 0.0001, 1e-42] Log probabilities: [0.0, -1.0, -2.0, -3.0, -4.0, -42.0] Converted back: [1.0, 0.1, 0.01, 0.001, 0.0001, 1e-42]
Remember:
We still haven't talked about the bit where we do the maths!
It's really simple:
Because we changed the scale (to orders of magnitude),
prob_a = 1/(10**50)
prob_b = 1/(10**60)
prob_a * prob_b
1e-110
Now converting into log-probabilities, adding, and converting back into normal probability:
logprob_a = np.log10(prob_a)
logprob_b = np.log10(prob_b)
log_product = logprob_a + logprob_b
10**log_product
1e-110
We get the same result! But why should I care?
When we're doing stuff with Bayesian probability, most of the time:
Instead, we usually want to compare probabilities, for example:
Let's see this in action:
prob_A = 10**-100 * 10**-150 * 10**-200
prob_B = 10**-100 * 10**-150 * 10**-202
prob_A / prob_B
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-64-7084ccd17c93> in <module> ----> 1 prob_A / prob_B ZeroDivisionError: float division by zero
Disaster!
logprob_A = np.log10(10**-100) + np.log10(10**-150) + np.log10(10**-200)
logprob_B = np.log10(10**-100) + np.log10(10**-150) + np.log10(10**-202)
logratio = logprob_A - logprob_B
ratio = 10**logratio
print('The probability ratio of A/B=', ratio)
The probability ratio of A/B= 100.0
And that's pretty much it!