Book a trial
Mathematics6 min read

Ranking Pokémon on Three Axes: A Model We Built in Class


Published on

29 June 2026

Contributors

George Ionitsa
George Ionitsa

Quant Developer and Olympiad Coach

Ranking Pokémon on Three Axes: A Model We Built in Class

Tier lists are loud. We built explainable rules instead — three scores, different averages for different jobs, and a full leaderboard. Bulbasaur is our worked example.

Every ranking argument sounds the same at first.

"This Pokémon is S-tier." "No, that one clears it." "Just look at the stats."

Tier lists, FIFA ratings, game meta charts, playground debates about the best starter — teenagers live inside ranking culture. The opinions are loud. The rules are usually missing.

In a recent group project we tried something different. A student picked Bulbasaur. Not because he thought Bulbasaur would win. Because he wanted a fair answer to a fair question:

Where does Bulbasaur actually rank — and can we explain why?

Not vibes. Not nostalgia. A model with rules we could defend.

His stats look fine — until you compare

Bulbasaur's base stats:

StatValue
Attack49
Special Attack65
HP45
Defense49
Special Defense65
Speed45

Add them up and you get 318. That feels tidy. It is also a trap.

Different stats do not live on the same scale. HP can go much higher than Attack. A single total hides what is actually strong and what is actually weak. This is the same conversation we have in class when we work on Sums and Averages: the average you choose matters.

Bulbasaur

How we compared him fairly

We scored 1,350 Pokémon variants with the same rules. For each stat we asked a simple question: where does Bulbasaur sit compared with everyone else?

Where Bulbasaur sits on each stat

The picture is blunt.

  • Attack, HP, Defense, and Speed — weak (bottom quarter)
  • Special Attack and Special Defense — below average, but not terrible

So Bulbasaur is not awful everywhere. He is uneven. That is already more useful than shouting "mid."

Three components in our notebook model

Six numbers are still a lot. In our Jupyter notebook we boil them down to three components — each with its own job and its own way of combining stats.

The three components of our model

Component 1 — Attack power

This is about how hard Bulbasaur hits. We combine Attack and Special Attack, but we count his better attack side more — a bit like picking your strongest subject when you form a team. Different averages for different jobs is exactly what we talk about in Sums and Averages.

Bulbasaur's Special Attack is okay. His physical Attack is weak. The model leans toward the better side, but both are still below average — so attack power lands at 39.3. That is his least bad axis.

Component 2 — Toughness

This is about how hard he is to knock out. We combine HP, Defense, and Special Defense.

Here we use the geometric mean — the same family of idea as AM–GM inequalities, which we study in class. Why? Because one terrible stat should drag everything down.

Class example: geometric mean with 2, 2, and 50

Take 2, 2, and 50 in class: the ordinary average is 18, but the geometric mean is about 6. One tiny value pulls the team down hard.

Bulbasaur toughness: geometric mean of HP, Defense, and Sp. Defense

Bulbasaur's HP and physical Defense sit in the bottom quarter of all Pokémon. His Special Defense is only below average. The geometric mean still punishes him — exactly like a group project where one person does no work. That is why toughness is only 21.9, not somewhere in the middle.

Component 3 — Speed

Speed is one stat and one comparison. No extra formula — we just ask where Bulbasaur's Speed ranks against everyone else.

He is in the bottom quarter. Speed: 22.0.

Bulbasaur's three scores and overall value

Bulbasaur's final value: 26.7

When we need one headline number, we take the geometric mean of the three components — equal weight, same "one weak link drags it down" logic as toughness.

Overall value: 26.7 out of 100

Rank: #1021 out of 1,350

That is bottom quarter on this model. Not useless — just not a stat monster.

Evolution tells the same story in a way everyone understands:

Bulbasaur, Ivysaur, and Venusaur overall scores

FormOverall value
Bulbasaur26.7
Ivysaur43.7
Venusaur66.5

Same rules. Better numbers every step. No nostalgia bonus.

What the model does not know

We were strict about this.

The score only sees base stats. It does not know:

  • typings or resistances
  • moves like Sleep Powder or Leech Seed
  • abilities, items, or matchups
  • whether you love Bulbasaur because he was your first starter

A low score here does not mean "bad Pokémon." It means weak on the things we chose to measure.

That honesty is the point. Real models say what they include — and what they leave out.

Explore the 3D map

We built an interactive map of all 1,350 Pokémon in attack-power / toughness / speed space. Bulbasaur starts highlighted in gold. Spin it, zoom, click other dots to compare.

This is the kind of data project we do in class now: a question, a dataset, a model you can argue with, and a chart you can explore — not a black-box tier list from the internet.

Full rankings

Want the whole leaderboard? We exported every result from the same model.

Download full rankings (CSV) — all 1,350 variants with stats and scores.

Top 20 by overall value:

PokémonOverall
Eternatus Eternamax94.0
Mewtwo Mega X93.2
Rayquaza Mega91.7
Necrozma Ultra91.5
Arceus91.2
Zacian Crowned90.3
Mewtwo Mega Y89.7
Salamence Mega89.6
Koraidon88.9
Koraidon Limited Build88.9
Koraidon Sprinting Build88.9
Koraidon Swimming Build88.9
Koraidon Gliding Build88.9
Garchomp Mega Z88.5
Miraidon88.2
Miraidon Low Power Mode88.2
Miraidon Drive Mode88.2
Miraidon Aquatic Mode88.2
Miraidon Glide Mode88.2
Palkia Origin88.2

Built in a Jupyter notebook during the project. If you want to run your own version — different weights, different favourite Pokémon — that is exactly what our group lessons are for.

For solo practice between sessions, problems.cc is full of questions that reward the same habit: stop guessing, start structuring.