Index Ai Academy
Phase 0 · Tools · Numbers for code

Fractions, ratios and rates

Shares, rates, percentage points and ratios, with Python doing the arithmetic.

About 20 minutes · Free lesson

Start this lesson

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

  1. A fraction is a division
  2. Rates: making groups comparable
  3. Which ad converts better?
  4. Percent change versus percentage points
  5. Report a change both ways
  6. Averages of rates can lie
  7. Ratios: scaling up and down
  8. Scale the trail mix
  9. Fractions all through AI
Quick check
Before any explaining, a guess. Shop A sold to 30 of its 200 visitors; shop B sold to 45 of its 450. What does this print?
a = 30 / 200
b = 45 / 450
print(a, b)
  1. 30 45
  2. 6.666666666666667 10.0
  3. 0.15 0.1
  4. 0.15 0.15
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:

fractiondecimalpercent
3/40.7575%
1/20.550%
1/80.12512.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
It runs right here in your browser, with nothing to install.
Try it now

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.

Quick check
Team North solved 180 of 240 support tickets; Team South solved 95 of 100. What does this print?
north = 180 / 240
south = 95 / 100
print(north > south)
  1. An error
  2. 0.75
  3. False
  4. True
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.

Drill

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, "%")
In the lesson, your code is checked as you write it.

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.

Quick check
A model's accuracy rose from 80% to 84%. Which statement is correct?
  1. It rose 4%, and 4 percentage points too
  2. It rose 84%, from 80% to 84%
  3. It rose 5 percentage points, a 4% increase
  4. It rose 4 percentage points, a 5% increase
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.

Drill

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)
In the lesson, your code is checked as you write it.

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.

Quick check
One store converted 20 of 40 visitors; another converted 30 of 160. What does this print?
print(round((20 + 30) / (40 + 160), 2))
  1. 0.5
  2. 50
  3. 0.34
  4. 0.25
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.

Quick check
A 750 ml bottle costs $6.00 and a 1,000 ml bottle costs $7.50. Using round() from the numbers lesson, what does this print?
small = round(6.00 / 750, 4)
large = round(7.50 / 1000, 4)
print(small, large)
  1. 0.008 0.0075
  2. 0.008 0.008
  3. 6.0 7.5
  4. 125.0 133.3333
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.

Drill

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)
In the lesson, your code is checked as you write it.

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?"

Quick check
An eval report says "412 correct". What do you need before you can judge it?
  1. Nothing: 412 is a high number
  2. How long the eval took to run
  3. Which model was evaluated first
  4. How many questions there were in total
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".

Quick check
A model gives its three possible answers these chances. What does this print?
a = 0.5
b = 0.3
c = 0.2
print(a + b + c)
  1. 100.0
  2. 0.5
  3. 1
  4. 1.0
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

Start this lesson

Try a quiz question

A click rate went from 2% to 3%. Which description is correct?

  1. Up 1 percentage point, a 50% increase
  2. Up 1%, which is also 1 point
  3. Up 50 percentage points
  4. Up 3%, from 2% to 3%

Answer it at the end of the lesson to see if you're right, and why.

Before this lesson