Revealing hidden evolution with Markov chains
| Term | Refers to | Example |
|---|---|---|
| Site | A position; in an alignment, a column of homologous positions | “3rd codon positions evolve faster than other sites” |
| Nucleotide | The building block of DNA: sugar + phosphate + base | “nucleotide substitution” |
| Base | The part of a nucleotide that makes it A, C, G, or T (the letter we write) |
“base frequencies”, “base pair” |
| Residue | A building block linked into a chain: Nucleotides or amino acids | “amino acid residues” |
Site 3
↓
Species 1: A C G T
Species 2: A C A T
The site persists; a mutation changes the nucleotide/base that occupies it
We have measured how different two sequences are by counting differences
But are we measuring the thing we care about?
The number of differences between two sequences is not the same as the amount of evolution that separates them.
Three sites in an ancestor and a descendant:
| Site | History | Substitutions | Differences we see |
|---|---|---|---|
| 1 | A → G |
1 | 1 |
| 2 | A → G → T |
2 | 1 |
| 3 | A → G → A |
2 | 0 |
5 substitutions happened, but we only observe 2 differences
Multiple hits: A later change can hide an earlier one
A model of sequence evolution describes the probabilities of substitution over time
With a model, we can ask:
This is our first probabilistic model of the semester
Chop time into many tiny steps. In each step, every base follows the same rule1:
That’s the entire model!
You will write a Python function to do this in the exercise
\(t = 1\) does not mean every site changed once. Some changed zero times, some twice, some more.
Rows: The base now. Columns: The base it changes to.
| A | C | G | T | |
|---|---|---|---|---|
| A | — | \(\mu\) | \(\mu\) | \(\mu\) |
| C | \(\mu\) | — | \(\mu\) | \(\mu\) |
| G | \(\mu\) | \(\mu\) | — | \(\mu\) |
| T | \(\mu\) | \(\mu\) | \(\mu\) | — |
Every possible change happens at the same rate (\(\mu\))
A random process with this memoryless property is a Markov chain
Nearly every model of sequence evolution used in biology is a Markov chain
Start 1,000 sites as A and let them evolve:
AA is lost and C, G, T are gainedThis is the model’s stationary distribution
The probability that a site differs from its ancestor after time \(t\):
\[ P(\text{different}) = \frac{3}{4}\left(1 - e^{-\frac{4}{3}t}\right) \]
This is the “differences we see” curve from the saturation plot
We observe \(p\), the proportion of sites that differ. Solve for \(t\) (and replace with \(d\) for distance):
\[ d = -\frac{3}{4}\ln\left(1 - \frac{4}{3}p\right) \]
| \(p\) (what we see) | 0.01 | 0.10 | 0.30 | 0.50 | 0.70 | \(\geq 0.75\) |
|---|---|---|---|---|---|---|
| \(d\) (Jukes-Cantor distance) | 0.010 | 0.107 | 0.383 | 0.824 | 2.031 | \(\infty\) |
Real sequences break these assumptions
Transitions are more common
A ↔︎ GC ↔︎ TSites differ in rate
You will see both in a real yeast gene in the exercise
Same machinery, more entries in the table:
| Model | Adds | Free parameters |
|---|---|---|
| JC691 | Nothing: all changes equal, all bases equal | 0 |
| K802 | Transitions and transversions have different rates (\(\kappa\)) | 1 |
| HKY853 | Unequal base frequencies | 4 |
| GTR4 | Every pair of bases has its own rate | 8 |
Plus: Let rates vary among sites (e.g., “+Γ”5)
Each model is a special case of the next
Flip a coin 10 times: 7 heads. If \(P(\text{heads}) = \theta\):
\[ L(\theta) = \theta^{7}(1 - \theta)^{3} \]
| \(\theta\) | 0.3 | 0.5 | 0.7 | 0.9 |
|---|---|---|---|---|
| \(L(\theta)\) | 0.000075 | 0.00098 | 0.0022 | 0.00048 |
Each site “comes up different” with probability \(P(\text{different})\), which depends on \(t\)
\(n\) sites compared, \(k\) differ:
\[ L(t) = P(\text{different})^{k} \times \big(1 - P(\text{different})\big)^{n - k} \]
The value of \(t\) that maximizes \(L(t)\) is the Jukes-Cantor distance
The Jukes-Cantor distance formula we used is a maximum likelihood estimate!
Thousands of sites means multiplying thousands of probabilities (numbers less than 1)
The fix: \(\ln(a \times b) = \ln a + \ln b\)
\[ \ln L(t) = k \ln P(\text{different}) + (n - k) \ln\big(1 - P(\text{different})\big) \]
Coming up: the likelihood of a tree1
get_different_base and evolve_one_stepA evolve over timejc_distance: Correct for the changes you cannot seelog_likelihood: Find where the corrected distance comes fromWatch for
How good a simple model can be versus counting differences
I used Anthropic’s Claude (Opus 5.5 model) to generate a draft of these slides.