This Jupyter notebook contains code to find the optimal mutation rate and single nucleotide polymorphism (SNP) assignments of a hypothetical evolutionary tree through applying the Jukes-Cantor model and Felsenstein’s algorithm.
Evolutionary trees are a type of directed acyclic graph encapsulating an evolutionary process over time. For example, the binary tree below is a model of DNA sequence evolution. Each internal node represents an ancestor with two descendants, the branch length between them represents time and leaf node represents the terminal taxa, i.e. the most recent descendant for which an SNP is known.
The Jukes-Cantor model is Markov model of DNA sequence evolution used when calculating the likelihood of a phylogenetic tree. It assumes that the mutation rate