Fractions, ratios and rates
Shares, rates, percentage points and ratios, with Python doing the arithmetic.
Why it matters
Most numbers in AI work are fractions in disguise. A click rate is clicks over views. A model's accuracy is right answers over all answers. When a model is "0.73 sure", that's a share of one whole. Mix up a count with a rate, or a percent with a percentage point, and you'll back the wrong campaign or misread a result. This lesson makes fractions, rates and ratios second nature, with Python doing the arithmetic.
What you'll be able to do
- Turn a fraction into a decimal and a percentage, and back again
- Compare groups of different sizes with rates instead of counts
- Tell a percent change from a change in percentage points
- Scale amounts up and down with a ratio, and compare unit prices
What it covers
- A fraction is a division
- Rates: making groups comparable
- Which ad converts better?
- Percent change versus percentage points
- Report a change both ways
- Averages of rates can lie
- Ratios: scaling up and down
- Scale the trail mix
- Fractions all through AI
a = 30 / 200 b = 45 / 450 print(a, b)
Show the answer
0.15 0.1
Dividing the part by the whole gives each shop's share: 0.15 and 0.1. B sold more in total, but A sold to a bigger share of its visitors. That's the whole idea of a rate.
A fraction is a division
A fraction says how much of a whole you have. 3/4 of a pizza means it was cut into 4 equal slices and you have 3. The line in the middle means divide: 3 ÷ 4 = 0.75. The same amount can be written three ways:
| fraction | decimal | percent |
|---|---|---|
| 3/4 | 0.75 | 75% |
| 1/2 | 0.5 | 50% |
| 1/8 | 0.125 | 12.5% |
Fractions that look different can be the same share: 3/4, 6/8 and 75/100 are all 0.75. Dividing turns each one into a single number, which is the easiest way to compare them.
Percent means "out of a hundred", so to turn a decimal into a percent, multiply by 100. To go back, divide by 100:
part = 3 whole = 8 share = part / whole print(share) # as a decimal print(share * 100, "%") # as a percent print(25 / 100) # 25% back as a decimal
Drag the part and the whole. The decimal and the percent always say the same thing two ways.
Rates: making groups comparable
Counts mislead whenever the groups differ in size. A newsletter that got 300 clicks sounds better than one that got 120, until you learn the first went to 10,000 people and the second to 2,000.
A rate is a count divided by how many chances there were. It answers "out of how many?":
big_clicks = 300 big_sent = 10000 small_clicks = 120 small_sent = 2000 print("Big list:", big_clicks / big_sent) print("Small list:", small_clicks / small_sent)
The small list's rate, 0.06 (6%), is double the big list's 0.03 (3%). Rates are often quoted per 1,000 or per 100,000 to avoid tiny decimals: a rate of 0.003 is 3 per 1,000.
Choosing the whole matters as much as the part. A click rate usually divides by the times an ad was shown; a conversion rate divides by visits, or by visitors, which aren't the same, since one person can visit twice. Two teams that divide by different wholes will report different rates for the same campaign, so always say what you divided by.
north = 180 / 240 south = 95 / 100 print(north > south)
Show the answer
False
North's rate is 0.75 and South's is 0.95, so north > south is False, even though North solved more tickets. Compare rates, not counts.
Which ad converts better?
Ad A got 48 sign-ups from 1,200 clicks. Ad B got 30 sign-ups from 600 clicks. Set rate_a and rate_b to each ad's sign-up rate as a percentage, rounded to 1 decimal place.
a_signups = 48 a_clicks = 1200 b_signups = 30 b_clicks = 600 rate_a = 0 # sign-ups out of clicks, as a percentage rate_b = 0 print("A:", rate_a, "%") print("B:", rate_b, "%")
Percent change versus percentage points
A checkout page converted 4% of visitors last month and 5% this month. Did conversion go up by 1% or by 25%? Both numbers are honest, which is why people trip over them:
- The difference between the rates is 1 percentage point: 5 − 4.
- The percent change compares that difference with where you started: 1 ÷ 4 = 0.25, a 25% increase.
The recipe for a percent change is (new − old) ÷ old × 100:
old_rate = 4.0 new_rate = 5.0 points = new_rate - old_rate percent_change = (new_rate - old_rate) / old_rate * 100 print(points, "percentage points") print(percent_change, "% change")
Headlines love whichever sounds bigger. When you report a change in a rate, say which one you mean.
One more trap: percent changes don't cancel out. A price that rises 50% and then falls 50% doesn't end where it began. $100 becomes $150, then $75, because the fall is half of the bigger, later amount.
Show the answer
It rose 4 percentage points, a 5% increase
84 − 80 is 4 percentage points. Compared with where it started, 4 ÷ 80 = 0.05, a 5% increase. "Accuracy rose 4%" is ambiguous at best.
Report a change both ways
Last month 250 of 5,000 visitors signed up. This month 330 of 5,500 did. Set old_rate and new_rate as percentages, points (their difference) and change (the percent change), each rounded to 1 decimal place.
old_signups = 250 old_visitors = 5000 new_signups = 330 new_visitors = 5500 old_rate = 0 new_rate = 0 points = 0 change = 0 print(old_rate, new_rate, points, change)
Averages of rates can lie
On Monday, 9 of 10 visitors to a new landing page signed up. On Tuesday, after an ad went out, 10 of 100 did. What was the page's sign-up rate over the two days?
It's tempting to average the two daily rates, 90% and 10%, and say 50%. But Tuesday had ten times the visitors, so it should count ten times as much. The honest overall rate adds up all the parts and all the wholes first:
monday = 9 / 10 tuesday = 10 / 100 print("Average of the rates:", (monday + tuesday) / 2) print("Overall rate:", (9 + 10) / (10 + 100))
The overall rate is about 17%, nowhere near 50%. Whenever groups differ in size, combine the counts, then divide. It's the same reason an average over customers and an average over orders can disagree: they weigh things differently.
print(round((20 + 30) / (40 + 160), 2))
Show the answer
0.25
All the conversions over all the visitors: 50 / 200 = 0.25. Averaging the two rates (0.5 and 0.1875) would give about 0.34, which overweights the small store.
Ratios: scaling up and down
A ratio compares two amounts. A pancake recipe with 2 cups of flour to 1 cup of milk has a 2 : 1 ratio of flour to milk. Keep the ratio and you can make any amount. To scale a recipe, work out the scale factor, what you need divided by what the recipe makes, and multiply every amount by it. A ratio can also be read as a share of the total: in a 2 : 1 mix, flour is 2 of every 3 cups, or 2/3 of the batter.
serves = 4 guests = 10 factor = guests / serves # 2.5 times the recipe print(factor, 2 * factor, 1 * factor)
The same idea gives a unit price: divide the price by the amount to get the price of one unit. That's how you compare a 750 ml bottle with a 1,000 ml one, or a monthly plan with a yearly one. Bigger packs are often, but not always, cheaper per unit, which is exactly why it's worth dividing.
small = round(6.00 / 750, 4) large = round(7.50 / 1000, 4) print(small, large)
Show the answer
0.008 0.0075
Price divided by amount is the price per ml: $0.008 against $0.0075, so the bigger bottle is cheaper per ml. round(..., 4) keeps four decimal places, as in the numbers lesson.
Scale the trail mix
A trail-mix recipe for 6 hikers uses 300 g of nuts and 150 g of raisins. Set factor to the scale factor for 15 hikers, then nuts and raisins to the grams needed for 15, each rounded to 1 decimal place.
recipe_hikers = 6 nuts_per_recipe = 300 raisins_per_recipe = 150 hikers = 15 factor = 0 nuts = 0 raisins = 0 print(factor, nuts, raisins)
Fractions all through AI
You'll meet these ideas in every phase. An eval's accuracy is correct answers over all answers. A model's probabilities are shares of one whole, so they add up to 1. The share of a budget each campaign gets, a classifier's error rate, an API's cache hit rate: each is a part over a whole.
Fractions also hide traps you'll meet again. A model that's right 95% of the time sounds good, until you learn that 95% of the test answers were "no" and it always says no. You'll take that one apart in Phase 3.
Two questions catch most mistakes. Whenever you see a count, ask "out of how many?" Whenever you see a change in a rate, ask "points, or percent?"
Show the answer
How many questions there were in total
412 out of 420 is 98%; 412 out of 1,000 is 41%. A count means little until you know "out of how many".
a = 0.5 b = 0.3 c = 0.2 print(a + b + c)
Show the answer
1.0
A model's chances for all its options are shares of one whole, so they add up to 1. Adding floats gives a float, so Python prints 1.0.
Practice what you just read
- 5 code examples you can edit and run
- a practice exercise that checks your code
- a 6-question quiz
- 5 review cards for spaced repetition
Try a quiz question
A click rate went from 2% to 3%. Which description is correct?