๐Ÿ“ ML & Bayesian
HOME

๐Ÿง  Fundamentals of ML & Bayesian Phylogenetics

๐ŸŽฏ Statistical Phylogenetics

Maximum Likelihood (ML) and Bayesian inference are the two dominant statistical frameworks for phylogenetic tree estimation. Both use explicit evolutionary models and evaluate trees based on the probability of the observed sequence data. ML finds the single best tree; Bayesian inference samples the posterior distribution of trees. Together they form the backbone of modern molecular phylogenetics.

Why They Matter

Statistical: Explicit models. Accurate: Better than distance/parsimony. Uncertainty: Bootstrap/PP. Complex: Rate variation, partitions. Time: Divergence dating. Standard: Publication-quality.

๐Ÿ“Œ Statistical๐Ÿ“Œ Model-based๐Ÿ“Œ Likelihood๐Ÿ“Œ Posterior
# ML & Bayesian Phylogenetics โ€” the big picture # Statistical inference of evolutionary trees. # CONCEPTUAL OVERVIEW print(""" === ML & Bayesian Phylogenetics === What they are: - Statistical tree inference - Explicit evolutionary models - Probability of data given tree - Two dominant frameworks Why they matter: - More accurate than NJ/MP - Handle rate variation - Provide uncertainty - Enable time trees - Publication standard ML: - Find best tree (point estimate) - Maximize likelihood - Bootstrap for support - Tools: IQ-TREE, RAxML Bayesian: - Sample posterior distribution - MCMC - Posterior probabilities - Tools: MrBayes, BEAST Data: - DNA sequences - Protein sequences - Morphology - SNPs Models: - JC69, K80, HKY, GTR - +G, +I, +I+G - Partitioned models - Codon models Workflow: 1. MSA (MAFFT) 2. Trim (Gblocks) 3. Model selection (ModelFinder) 4. Tree inference (IQ-TREE/MrBayes) 5. Support (bootstrap/PP) 6. Visualization (FigTree) Applications: - Species trees - Gene trees - Viral phylodynamics - Cancer evolution - Divergence dating - Comparative methods """) # WHY IT MATTERS print("=== Why It Matters ===") print(""" Biological questions: - What is the best tree? - How confident are we? - When did lineages diverge? - What is the rate of evolution? - What is the ancestral state? ML & Bayesian answer: - Best tree topology - Branch lengths - Support values - Divergence times - Model parameters """) # HISTORICAL CONTEXT print("=== Historical Context ===") print(""" 1960s: Molecular clock 1981: Felsenstein ML 1988: MCMC (Gelfand & Smith) 1990s: Bayesian phylogenetics 1996: MrBayes (Huelsenbeck & Ronquist) 2000s: RAxML, PhyML 2010s: IQ-TREE, BEAST 2020s: ModelFinder, UFBoot, large-scale """) # CHALLENGES print("=== Challenges ===") print(""" 1. MODEL SELECTION - Which model? - Over-parameterization - Model uncertainty 2. COMPUTATIONAL - Tree space search - MCMC convergence - Large datasets 3. CONVERGENCE - ESS - PSRF - Burn-in 4. SUPPORT - Bootstrap vs PP - Interpretation - Overconfidence 5. INTERPRETATION - Gene vs species tree - Rate variation - Long-branch attraction """)

๐ŸŽฏ Why ML & Bayesian Matter

๐ŸŽฏ The Value of Statistical Phylogenetics

ML and Bayesian methods provide the statistical rigor needed for robust evolutionary inference.

Key Advantages

Accuracy: Model-based. Uncertainty: Support values. Flexibility: Complex models. Time: Divergence dating. Comparisons: Model testing. Standard: Publication.

๐ŸŽฏ Accuracy๐ŸŽฏ Uncertainty๐ŸŽฏ Flexibility๐ŸŽฏ Time trees
# Why ML & Bayesian Matter print("=== 1. Statistical Rigor ===") print(""" Statistical: - Explicit model - Likelihood - Probability - Model comparison Advantages: - Accounts for multiple hits - Handles rate variation - Provides uncertainty - Testable hypotheses Example: - NJ: Fast but no model - ML: Model-based, accurate - Bayesian: Posterior distribution """) print("\n=== 2. Rate Variation ===") print(""" Rate variation: - Sites evolve at different rates - Important for realistic models Models: - +G: Gamma distribution - +I: Invariant sites - +I+G: Both Example: - Conserved sites (slow) - Variable sites (fast) - Phylogenetically informative ML & Bayesian: - Handle rate variation - Estimate ฮฑ (gamma shape) - Estimate p_inv (invariant) """) print("\n=== 3. Uncertainty Quantification ===") print(""" Uncertainty: - Bootstrap (ML) - Posterior probability (Bayesian) - Confidence intervals ML: - Bootstrap 1000 - UFBoot - SH-aLRT Bayesian: - Posterior probability - Credible intervals - HPD """) print("\n=== 4. Divergence Time Estimation ===") print(""" Time trees: - Molecular clock - Calibration - Divergence times Bayesian: - BEAST - Relaxed clock - Fossil calibration - HPD intervals Example: - Human-Chimp: 6.5 MYA (5.5-7.5) - Mammal diversification - Viral phylodynamics """) print("\n=== 5. Model Comparison ===") print(""" Model comparison: - Which model fits best? - AIC, BIC - Bayes factors ML: - ModelFinder - AIC/BIC - Likelihood ratio test Bayesian: - Bayes factors - Path sampling - Stepping stone """) print("\n=== 6. Complex Models ===") print(""" Complex models: - Partitioned models - Codon models - Mixture models - Trait evolution ML: - PartitionFinder - IQ-TREE - RAxML Bayesian: - MrBayes - BEAST - RevBayes """) print("\n=== 7. Viral Phylodynamics ===") print(""" Phylodynamics: - Viral spread - Population size - Selection Bayesian: - BEAST - Skyline plot - Tip dates - Real-time Examples: - SARS-CoV-2 - HIV - Influenza - Ebola """) print("\n=== 8. Cancer Evolution ===") print(""" Cancer: - Clonal evolution - Driver mutations - Metastasis Bayesian: - BEAST - PyClone - SciClone - Tree inference Example: - Leukemia - Breast cancer - Lung cancer """)

๐Ÿ“ Maximum Likelihood

๐ŸŽฏ Finding the Best Tree

Maximum Likelihood (ML) finds the tree topology and branch lengths that maximize the probability of observing the data given an evolutionary model.

ML

Likelihood: P(data | tree, model). Search: Tree space. Optimal: Best tree. Model: Substitution. Bootstrap: Support. Tools: IQ-TREE, RAxML.

๐Ÿ“ Likelihood๐Ÿ“ Tree search๐Ÿ“ Bootstrap๐Ÿ“ Model
# Maximum Likelihood print("=== Likelihood ===") print(""" Likelihood: L = P(data | tree, model) lnL = log likelihood For a tree: - Model: substitution rates - Branch lengths: substitutions per site - Likelihood: probability of alignment Example: Alignment: 4 taxa, 1000 bp Model: GTR+G Tree: ((A,B),(C,D)) lnL: -12345.67 """) print("\n=== ML Algorithm ===") print(""" Steps: 1. Choose substitution model 2. Start with initial tree (NJ) 3. Optimize branch lengths 4. Search tree space: - NNI (nearest neighbor interchange) - SPR (subtree pruning and regrafting) - TBR (tree bisection and reconnection) 5. Find tree with max lnL 6. Bootstrap for support Search: - Heuristic - Local optima - Multiple starting trees - Random addition """) print("\n=== Felsenstein's Pruning Algorithm ===") print(""" Pruning: - Efficient likelihood computation - Dynamic programming - O(n * k^2) per site Steps: 1. Root tree 2. Post-order traversal 3. Compute conditional likelihoods 4. Combine at nodes 5. Sum over root states Complexity: - n taxa - k states (4 for DNA) - L sites - O(n * k^2 * L) """) print("\n=== IQ-TREE ===") print(""" IQ-TREE: - Fast ML - ModelFinder - UFBoot - Partition models Command: iqtree -s alignment.fa -m MFP -B 1000 -T 8 Options: -m MFP: ModelFinder -B 1000: UFBoot -alrt 1000: SH-aLRT -T 8: Threads Output: alignment.fa.treefile alignment.fa.iqtree alignment.fa.log """) print("\n=== RAxML ===") print(""" RAxML: - ML - Fast - Standard Command: raxmlHPC-PTHREADS-SSE3 \ -T 8 \ -s alignment.fa \ -n result \ -m GTRGAMMA \ -p 12345 \ -x 12345 \ -# 1000 \ -f a Options: -m: Model -p: Parsimony seed -x: Bootstrap seed -#: Replicates -f a: ML + bootstrap """) print("\n=== RAxML-NG ===") print(""" RAxML-NG: - Next generation - Faster - Better Command: raxml-ng \ --all \ --msa alignment.fa \ --model GTR+G \ --tree pars{10},rand{10} \ --bs-trees 1000 \ --threads 8 Output: alignment.fa.raxml.bestTree alignment.fa.raxml.support """) print("\n=== ML Advantages & Disadvantages ===") print(""" ADVANTAGES: โœ“ Statistical โœ“ Explicit model โœ“ Accurate โœ“ Rate variation โœ“ Branch lengths โœ“ Publication standard DISADVANTAGES: โœ— Slow โœ— Model dependence โœ— Local optima โœ— Bootstrap costly โœ— Long-branch attraction """)

๐ŸŽฒ Bayesian Inference

๐ŸŽฏ Posterior Distribution

Bayesian inference estimates the posterior distribution of trees using MCMC, combining likelihood with priors.

Bayesian

Prior: Before data. Likelihood: Data. Posterior: After data. MCMC: Sampling. PP: Posterior probability. MrBayes: Standard.

๐ŸŽฒ Prior๐ŸŽฒ Posterior๐ŸŽฒ MCMC๐ŸŽฒ PP
# Bayesian Inference print("=== Bayes' Theorem ===") print(""" Bayes: P(tree | data) = P(data | tree) * P(tree) / P(data) Where: P(tree | data): Posterior P(data | tree): Likelihood P(tree): Prior P(data): Marginal likelihood Goal: - Sample from posterior - Estimate tree distribution - Posterior probabilities """) print("\n=== MCMC ===") print(""" MCMC (Markov Chain Monte Carlo): - Sample tree space - Propose new trees - Accept/reject - Converge to posterior Steps: 1. Start tree 2. Propose change: - Topology (NNI, SPR) - Branch lengths - Model parameters 3. Compute likelihood 4. Accept/reject (Metropolis) 5. Repeat Chains: - Multiple chains - Heated chains - Swap - Convergence (ESS, PSRF) """) print("\n=== Metropolis-Hastings ===") print(""" Metropolis-Hastings: - Propose new state - Accept with probability: ฮฑ = min(1, P(new) / P(old) * q(old|new) / q(new|old)) - P = posterior - q = proposal For phylogenetics: - Propose NNI/SPR - Propose branch length - Propose model parameters """) print("\n=== MrBayes ===") print(""" MrBayes: - Most popular - MCMC - Many models - Standard Nexus input: #NEXUS begin data; dimensions ntax=10 nchar=1000; format datatype=dna; matrix taxon1 ACGT... taxon2 ACGT... ; end; begin mrbayes; lset nst=6 rates=gamma; mcmc ngen=1000000 samplefreq=1000; sump burnin=250; sumt burnin=250; end; Command: mb input.nexus Output: input.nexus.con.tre input.nexus.p input.nexus.t """) print("\n=== BEAST ===") print(""" BEAST: - Bayesian - Time-calibrated - Coalescent - Phylodynamics Input: - XML (BEAUti) - Alignment - Calibration - Model Output: - MCC tree - Divergence times - Skyline plot Tools: - BEAUti - Tracer - TreeAnnotator - FigTree """) print("\n=== Priors ===") print(""" Priors: - Tree prior (coalescent, Yule) - Substitution model - Branch lengths - Clock Tree priors: - Yule: Speciation - Birth-death: Extinction - Coalescent: Population Clock priors: - Strict - Relaxed (log-normal, exponential) Prior sensitivity: - Test different priors - Compare posteriors """) print("\n=== Bayesian Advantages & Disadvantages ===") print(""" ADVANTAGES: โœ“ Posterior probabilities โœ“ Complex models โœ“ Time-calibrated โœ“ Uncertainty โœ“ Prior knowledge โœ“ Model comparison DISADVANTAGES: โœ— Slow โœ— Computationally intensive โœ— Prior sensitivity โœ— Convergence issues โœ— Model complexity """)

โš–๏ธ ML vs Bayesian

๐ŸŽฏ Two Frameworks

ML and Bayesian inference are complementary. ML finds the best tree; Bayesian samples the posterior distribution.

Comparison

ML: Point estimate. Bayesian: Distribution. Support: Bootstrap vs PP. Speed: ML faster. Models: Bayesian complex. Both: Statistical.

โš–๏ธ MLโš–๏ธ Bayesianโš–๏ธ Bootstrapโš–๏ธ PP
Feature Maximum Likelihood Bayesian Inference
OutputSingle best treePosterior distribution
SupportBootstrapPosterior probability
UncertaintyBootstrap valuesCredible intervals
SpeedFastSlow
PriorsNoYes
Complex modelsPossibleNatural
Time treesMCMCtreeBEAST
Model comparisonAIC/BICBayes factors
ConvergenceLocal optimaMCMC diagnostics
ToolsIQ-TREE, RAxMLMrBayes, BEAST
# ML vs Bayesian print("=== Philosophical Differences ===") print(""" ML (Frequentist): - Data is random - Parameters fixed - Find best estimate - Confidence intervals - Bootstrap Bayesian: - Parameters random - Data fixed - Posterior distribution - Credible intervals - MCMC Both: - Use likelihood - Explicit models - Statistical - Publication standard """) print("\n=== When to Use ML ===") print(""" Use ML: โœ“ Fast analysis โœ“ Large datasets โœ“ Initial tree โœ“ Model selection โœ“ Publication (common) โœ“ Simple models Tools: - IQ-TREE - RAxML - PhyML - FastTree """) print("\n=== When to Use Bayesian ===") print(""" Use Bayesian: โœ“ Posterior probabilities โœ“ Complex models โœ“ Time trees โœ“ Phylodynamics โœ“ Prior information โœ“ Uncertainty Tools: - MrBayes - BEAST - RevBayes - PhyloBayes """) print("\n=== Combining Approaches ===") print(""" Best practice: 1. ML for initial tree 2. ML for model selection 3. Bayesian for final 4. Compare results 5. Report both Example: - IQ-TREE for ML - MrBayes for Bayesian - Compare topologies - Check support """) print("\n=== Support Comparison ===") print(f"{'Method':<20} {'Threshold':<20} {'Interpretation':<25}") print("-" * 65) print(f"{'Bootstrap':<20} {'> 70%':<20} {'Moderate-strong':<25}") print(f"{'UFBoot':<20} {'> 95%':<20} {'Strong':<25}") print(f"{'SH-aLRT':<20} {'> 80%':<20} {'Strong':<25}") print(f"{'Posterior':<20} {'> 0.95':<20} {'Strong':<25}") print("\n=== Speed Comparison ===") print(f"{'Method':<20} {'10 taxa':<15} {'100 taxa':<15}") print("-" * 50) print(f"{'IQ-TREE ML':<20} {'10s':<15} {'10 min':<15}") print(f"{'RAxML ML':<20} {'30s':<15} {'30 min':<15}") print(f"{'MrBayes':<20} {'1 min':<15} {'Hours':<15}") print(f"{'BEAST':<20} {'5 min':<15} {'Days':<15}")

โš™๏ธ Substitution Models

๐ŸŽฏ Modeling Sequence Evolution

Substitution models describe how nucleotides or amino acids change over time. Choosing the right model is critical for accurate phylogenies.

Models

JC69: Simplest. K80: ts/tv. HKY: Base freq. GTR: General. +G: Gamma. +I: Invariant. ModelFinder: Selection.

โš™๏ธ JC69โš™๏ธ HKYโš™๏ธ GTRโš™๏ธ +G
# Substitution Models print("=== DNA Models ===") print(""" JC69 (Jukes-Cantor, 1969): - Equal base frequencies - Equal rates - Simplest K80 (Kimura 2-parameter, 1980): - Equal base frequencies - Different ts/tv F81 (Felsenstein, 1981): - Different base frequencies - Equal rates HKY85 (Hasegawa-Kishino-Yano): - Different base frequencies - Different ts/tv TN93 (Tamura-Nei): - Different base frequencies - Different ts/tv rates GTR (General Time Reversible): - Different base frequencies - Different rates - Most general """) print("\n=== Model Parameters ===") print(""" Base frequencies: - ฯ€A, ฯ€C, ฯ€G, ฯ€T - Equal or estimated Substitution rates: - a, b, c, d, e, f - 6 rates (GTR) Rate heterogeneity: - +G: Gamma distribution - +I: Invariant sites - +I+G: Both Alpha (ฮฑ): - Shape parameter - ฮฑ < 1: High variation - ฮฑ > 1: Low variation p_inv: - Proportion invariant - 0 to 1 """) print("\n=== Protein Models ===") print(""" Amino acid models: - Poisson: Equal rates - JTT: Jones-Taylor-Thornton - WAG: Whelan & Goldman - LG: Le & Gascuel - Dayhoff - Blosum62 - mtMAM: Mitochondrial Model selection: - ModelFinder - ProtTest """) print("\n=== Codon Models ===") print(""" Codon models: - Account for genetic code - dN/dS ratio - Selection Models: - M0: One ฯ‰ - M1a: Neutral - M2a: Selection - M7: Beta - M8: Beta + ฯ‰ Tools: - PAML - HyPhy - IQ-TREE """) print("\n=== Partition Models ===") print(""" Partitioning: - Different genes - Different codons - Different regions Example: Gene 1: GTR+G Gene 2: HKY+I Gene 3: GTR+I+G Tools: - PartitionFinder - IQ-TREE (-p) - RAxML (-q) Command: iqtree -s alignment.fa -p partition.txt -m MFP """) print("\n=== ModelFinder ===") print(""" ModelFinder: - IQ-TREE - Fast - Comprehensive - Standard Command: iqtree -s alignment.fa -m MFP Output: Best model: GTR+F+I+G4 BIC: 12345.67 AIC: 12340.12 Criteria: - AIC: Akaike Information Criterion - BIC: Bayesian Information Criterion - AICc: Corrected AIC """) print("\n=== Model Selection Tools ===") print(""" 1. ModelFinder (IQ-TREE) - Fast - Comprehensive - Standard 2. jModelTest - Java - GUI - Many models 3. Modeltest-NG - Fast - Many models 4. ProtTest - Protein models 5. PartitionFinder - Partitioning """) print("\n=== Best Practices ===") print(""" 1. Always select model 2. Use ModelFinder 3. Consider partitioning 4. Check parameter estimates 5. Compare models (AIC/BIC) 6. Report model 7. Consider rate variation 8. Check for saturation """)

๐Ÿ” Model Selection

๐ŸŽฏ Choosing the Best Model

Model selection identifies the substitution model that best fits the data without over-parameterization.

Selection

AIC: Akaike. BIC: Bayesian. Likelihood: Fit. Parameters: Penalty. ModelFinder: Fast. jModelTest: Classic.

๐Ÿ” AIC๐Ÿ” BIC๐Ÿ” Likelihood๐Ÿ” Penalty
# Model Selection print("=== Criteria ===") print(""" AIC (Akaike Information Criterion): AIC = -2 lnL + 2k k = number of parameters BIC (Bayesian Information Criterion): BIC = -2 lnL + k ln(n) n = sample size AICc (Corrected AIC): AICc = AIC + 2k(k+1)/(n-k-1) For small samples Best model: - Lowest AIC/BIC - Balance fit and complexity """) print("\n=== ModelFinder ===") print(""" ModelFinder: - IQ-TREE - Fast - Comprehensive Command: iqtree -s alignment.fa -m MFP Output: Best model: GTR+F+I+G4 BIC: 12345.67 AIC: 12340.12 Options: -m MFP: ModelFinder + tree -m MF: ModelFinder only -mtree: ModelFinder + tree -mset: Restrict models """) print("\n=== jModelTest ===") print(""" jModelTest: - Java - GUI - Classic Steps: 1. Load alignment 2. Select models 3. Compute likelihood 4. Compare AIC/BIC 5. Select best Output: - Best model - Parameter estimates - Model averaging """) print("\n=== Model Uncertainty ===") print(""" Model uncertainty: - Which model is best? - Model averaging - Confidence set Approaches: - AIC weights - BIC weights - Model averaging - Bayesian model selection Tools: - ModelFinder - jModelTest - MrBayes (Bayes factors) """) print("\n=== Partitioning ===") print(""" Partitioning: - Different genes - Different codons - Different regions PartitionFinder: - Finds best partitioning - Model per partition Command: partitionfinder.py alignment.fa -c config.cfg Output: partition.txt best_scheme.txt IQ-TREE: iqtree -s alignment.fa -p partition.txt -m MFP """) print("\n=== Best Practices ===") print(""" 1. Use ModelFinder 2. Consider partitioning 3. Check AIC/BIC 4. Report model 5. Test sensitivity 6. Compare with alternatives 7. Check parameter estimates 8. Consider model averaging """)

๐Ÿ”— MCMC & Convergence

๐ŸŽฏ Sampling the Posterior

MCMC samples from the posterior distribution. Convergence diagnostics are essential for reliable Bayesian inference.

MCMC

Chain: Sample. Proposal: Change. Accept: Metropolis. Convergence: ESS. Burn-in: Discard. Tracer: Diagnose.

๐Ÿ”— Chain๐Ÿ”— Proposal๐Ÿ”— Accept๐Ÿ”— Convergence
# MCMC & Convergence print("=== MCMC Algorithm ===") print(""" MCMC: 1. Start tree 2. Propose change: - Topology (NNI, SPR) - Branch lengths - Model parameters 3. Compute likelihood 4. Accept/reject: - Accept if better - Accept if worse with probability 5. Repeat Proposals: - NNI: Nearest neighbor interchange - SPR: Subtree pruning and regrafting - Branch length - Model parameters """) print("\n=== Metropolis-Hastings ===") print(""" Metropolis-Hastings: - Propose new state - Accept with probability: ฮฑ = min(1, P(new) / P(old) * q(old|new) / q(new|old)) - P = posterior - q = proposal For phylogenetics: - Propose NNI/SPR - Propose branch length - Propose model parameters """) print("\n=== Convergence Diagnostics ===") print(""" ESS (Effective Sample Size): - Independent samples - ESS > 200: Good - ESS > 1000: Excellent PSRF (Potential Scale Reduction Factor): - Between vs within chain - PSRF ~ 1.0: Converged - PSRF < 1.1: Acceptable Trace plots: - Stationary - Well-mixed - No trends Autocorrelation: - Low - Rapid decay """) print("\n=== Tracer ===") print(""" Tracer: - GUI - Diagnostics - Standard Steps: 1. Load .log files 2. Check ESS 3. Check trace 4. Check autocorrelation 5. Check burn-in Interpretation: - ESS > 200 - PSRF ~ 1.0 - Stationary trace - No trends """) print("\n=== Burn-in ===") print(""" Burn-in: - Discard initial samples - Before convergence - Usually 10-25% Example: ngen = 1,000,000 samplefreq = 1000 burnin = 250 (25%) Check: - Trace plot - Running mean - ESS """) print("\n=== MrBayes Convergence ===") print(""" MrBayes: - Multiple chains (4) - Heated chains - Swap - Convergence Output: .p file: Parameters .t file: Trees .con.tre: Consensus Check: - Average standard deviation of split frequencies - < 0.01: Good - < 0.05: Acceptable """) print("\n=== Troubleshooting ===") print(""" Problems: - Low ESS - Poor mixing - Non-convergence - High autocorrelation Solutions: - Run longer - More chains - Better proposals - Check model - Check priors - Simplify model """) print("\n=== Best Practices ===") print(""" 1. Multiple runs (4+) 2. Long enough (ESS > 200) 3. Check convergence 4. Appropriate burn-in 5. Tracer diagnostics 6. Report ESS 7. Report PSRF 8. Sensitivity analysis """)

๐Ÿ“Š Branch Support

๐ŸŽฏ How Confident Are We?

Branch support measures confidence in tree branches. Bootstrap for ML, posterior probabilities for Bayesian.

Support

Bootstrap: Resampling. UFBoot: Fast. SH-aLRT: Fast. PP: Posterior. Threshold: 70% / 0.95. Interpret: Confidence.

๐Ÿ“Š Bootstrap๐Ÿ“Š UFBoot๐Ÿ“Š SH-aLRT๐Ÿ“Š PP
# Branch Support print("=== Bootstrap ===") print(""" Bootstrap: - Resampling columns - With replacement - 1000 replicates - Count branch frequency Steps: 1. Original alignment 2. Resample columns (n) 3. Build tree 4. Repeat 1000x 5. Count branch Interpretation: - > 95%: Strong - 70-95%: Moderate - 50-70%: Weak - < 50%: Not supported Command (IQ-TREE): iqtree -s alignment.fa -m MFP -B 1000 -T 8 Command (RAxML): raxmlHPC -s alignment.fa -m GTRGAMMA -p 12345 -b 12345 -# 1000 """) print("\n=== UFBoot ===") print(""" UFBoot (Ultrafast Bootstrap): - IQ-TREE - Fast - 1000 replicates - Recommended Command: iqtree -s alignment.fa -m MFP -B 1000 -T 8 Interpretation: - > 95%: Strong - 70-95%: Moderate - < 70%: Weak Advantages: - Fast - Accurate - Standard """) print("\n=== SH-aLRT ===") print(""" SH-aLRT (Shimodaira-Hasegawa approximate likelihood ratio test): - Fast - IQ-TREE - Alternative to bootstrap Command: iqtree -s alignment.fa -m MFP -alrt 1000 -B 1000 Interpretation: - > 80%: Strong - 70-80%: Moderate - < 70%: Weak """) print("\n=== aBayes ===") print(""" aBayes: - Approximate Bayes - Fast - PhyML, IQ-TREE Command: iqtree -s alignment.fa -m MFP -abayes Interpretation: - > 0.95: Strong - 0.90-0.95: Moderate """) print("\n=== Posterior Probability ===") print(""" PP: - Bayesian - Frequency in posterior - MrBayes, BEAST Interpretation: - > 0.95: Strong - 0.90-0.95: Moderate - < 0.90: Weak PP vs Bootstrap: - PP often higher - Bootstrap more conservative - Both should be reported """) print("\n=== Support Comparison ===") print(f"{'Method':<20} {'Threshold':<20} {'Speed':<15} {'Tool':<15}") print("-" * 70) print(f"{'Bootstrap':<20} {'70-95%':<20} {'Slow':<15} {'RAxML':<15}") print(f"{'UFBoot':<20} {'95%':<20} {'Fast':<15} {'IQ-TREE':<15}") print(f"{'SH-aLRT':<20} {'80%':<20} {'Fast':<15} {'IQ-TREE':<15}") print(f"{'aBayes':<20} {'0.95':<20} {'Fast':<15} {'PhyML':<15}") print(f"{'Posterior':<20} {'0.95':<20} {'Slow':<15} {'MrBayes':<15}") print("\n=== Best Practices ===") print(""" 1. Use 1000 bootstrap 2. Use UFBoot for speed 3. Report support values 4. Use multiple methods 5. Check support distribution 6. Collapse low support 7. Don't overinterpret 8. Consider gene trees """)

๐Ÿ› ๏ธ Tools (RAxML, IQ-TREE, MrBayes, BEAST)

๐ŸŽฏ Ready-to-Use Tools

Many high-quality ML and Bayesian tools exist. Each has strengths and is suited to different analyses.

Tools

IQ-TREE: Fast ML. RAxML: ML. MrBayes: Bayesian. BEAST: Time. PhyML: ML. RevBayes: Bayesian.

๐Ÿ› ๏ธ IQ-TREE๐Ÿ› ๏ธ RAxML๐Ÿ› ๏ธ MrBayes๐Ÿ› ๏ธ BEAST
# Tools print("=== IQ-TREE ===") print(""" IQ-TREE: - Fast ML - ModelFinder - UFBoot - Partition models - Standard Command (basic): iqtree -s alignment.fa -m MFP -B 1000 -T 8 Command (partitioned): iqtree -s alignment.fa -p partition.txt -m MFP -B 1000 Options: -m MFP: ModelFinder -B 1000: UFBoot -alrt 1000: SH-aLRT -T 8: Threads -pre: Prefix Output: alignment.fa.treefile alignment.fa.iqtree alignment.fa.log """) print("\n=== RAxML ===") print(""" RAxML: - ML - Fast - Standard - Many models Command: raxmlHPC-PTHREADS-SSE3 \ -T 8 \ -s alignment.fa \ -n result \ -m GTRGAMMA \ -p 12345 \ -x 12345 \ -# 1000 \ -f a Options: -m: Model -p: Parsimony seed -x: Bootstrap seed -#: Replicates -f a: ML + bootstrap Output: RAxML_bestTree.result RAxML_bipartitions.result """) print("\n=== RAxML-NG ===") print(""" RAxML-NG: - Next generation - Faster - Better Command: raxml-ng \ --all \ --msa alignment.fa \ --model GTR+G \ --tree pars{10},rand{10} \ --bs-trees 1000 \ --threads 8 Output: alignment.fa.raxml.bestTree alignment.fa.raxml.support """) print("\n=== MrBayes ===") print(""" MrBayes: - Bayesian - MCMC - Standard Nexus input: #NEXUS begin data; dimensions ntax=10 nchar=1000; format datatype=dna; matrix taxon1 ACGT... ; end; begin mrbayes; lset nst=6 rates=gamma; mcmc ngen=1000000 samplefreq=1000; sump burnin=250; sumt burnin=250; end; Command: mb input.nexus Output: input.nexus.con.tre input.nexus.p """) print("\n=== BEAST ===") print(""" BEAST: - Bayesian - Time-calibrated - Phylodynamics Workflow: 1. BEAUti (XML) 2. BEAST (MCMC) 3. Tracer (convergence) 4. TreeAnnotator (MCC) 5. FigTree (visualize) Command: beast input.xml Output: input.xml.trees input.xml.log """) print("\n=== PhyML ===") print(""" PhyML: - ML - Fast - GUI + CLI Command: phyml -i alignment.phy -d nt -m GTR -a e -b 1000 Options: -d: Data type -m: Model -a: Gamma -b: Bootstrap """) print("\n=== RevBayes ===") print(""" RevBayes: - Bayesian - Flexible - Scriptable Features: - Complex models - Graphical models - MCMC Example: revbayes script.rev """) print("\n=== Other Tools ===") print(""" 1. FastTree - Very fast - Large datasets 2. PhyloBayes - Bayesian - Complex models 3. MCMCtree - PAML - Time trees 4. TreeTime - Time trees - Phylodynamics 5. Nextstrain - Real-time - Viral """) print("\n=== Installation ===") print(""" # Conda conda install -c bioconda iqtree raxml raxml-ng mrbayes beast phyml revbayes # Docker docker pull quay.io/biocontainers/iqtree # From source git clone https://github.com/iqtree/iqtree2 """)

๐Ÿ Python Integration

๐ŸŽฏ Phylogenetics from Python

You can run ML and Bayesian tools from Python using subprocess and analyze results with Biopython, ete3, and DendroPy.

Python

subprocess: Run CLI. Biopython: Trees. ete3: Analysis. DendroPy: Trees. PyMC: Bayesian. Pipeline: Automate.

๐Ÿ subprocess๐Ÿ Biopython๐Ÿ ete3๐Ÿ DendroPy
# Python Integration print("=== Run IQ-TREE ===") print(""" import subprocess def run_iqtree(alignment, model="MFP", bootstrap=1000, threads=8, prefix="iqtree"): \"\"\"Run IQ-TREE.\"\"\" cmd = [ 'iqtree', '-s', alignment, '-m', model, '-B', str(bootstrap), '-T', str(threads), '-pre', prefix ] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: raise RuntimeError(f"IQ-TREE failed: {result.stderr}") return f"{prefix}.treefile" # Use # tree = run_iqtree("alignment.fa") """) print("\n=== Run RAxML ===") print(""" def run_raxml(alignment, model="GTRGAMMA", bootstrap=1000, threads=8): \"\"\"Run RAxML.\"\"\" cmd = [ 'raxmlHPC-PTHREADS-SSE3', '-T', str(threads), '-s', alignment, '-n', 'result', '-m', model, '-p', '12345', '-x', '12345', '-#', str(bootstrap), '-f', 'a' ] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: raise RuntimeError(f"RAxML failed: {result.stderr}") return "RAxML_bipartitions.result" # Use # tree = run_raxml("alignment.fa") """) print("\n=== Run MrBayes ===") print(""" def run_mrbayes(nexus_file): \"\"\"Run MrBayes.\"\"\" cmd = ['mb', nexus_file] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: raise RuntimeError(f"MrBayes failed: {result.stderr}") return f"{nexus_file}.con.tre" # Use # tree = run_mrbayes("input.nexus") """) print("\n=== Parse Trees with Biopython ===") print(""" from Bio import Phylo def parse_tree(tree_file): \"\"\"Parse Newick tree.\"\"\" tree = Phylo.read(tree_file, "newick") print(f"Tree: {tree}") print(f"Terminals: {len(tree.get_terminals())}") print(f"Non-terminals: {len(tree.get_nonterminals())}") # Branch lengths for clade in tree.find_clades(): if clade.branch_length: print(f"{clade.name}: {clade.branch_length:.4f}") return tree # Use # tree = parse_tree("tree.nwk") """) print("\n=== Analyze Tree ===") print(""" from Bio import Phylo def analyze_tree(tree_file): \"\"\"Analyze tree structure.\"\"\" tree = Phylo.read(tree_file, "newick") # Total tree length total = sum(c.branch_length for c in tree.find_clades() if c.branch_length) print(f"Total tree length: {total:.4f}") # Find clades for clade in tree.find_clades(): if clade.is_terminal(): print(f"Tip: {clade.name}") # Distance between taxa dist = tree.distance("taxon1", "taxon2") print(f"Distance: {dist:.4f}") # Common ancestor mrca = tree.common_ancestor("taxon1", "taxon2") print(f"MRCA: {mrca}") return tree # Use # tree = analyze_tree("tree.nwk") """) print("\n=== ete3 ===") print(""" from ete3 import Tree def analyze_ete(tree_file): \"\"\"Analyze tree with ete3.\"\"\" t = Tree(tree_file) # Basic info print(f"Leaves: {len(t.get_leaves())}") print(f"Nodes: {len(t.get_descendants())}") # Root print(f"Root: {t.get_tree_root()}") # Traverse for node in t.traverse(): print(f"Node: {node.name}, dist: {node.dist}") # Distance print(f"Distance: {t.get_distance('taxon1', 'taxon2')}") return t # Use # t = analyze_ete("tree.nwk") """) print("\n=== Convergence Diagnostics ===") print(""" import pandas as pd def check_convergence(log_file): \"\"\"Check MCMC convergence.\"\"\" # Load Tracer log df = pd.read_csv(log_file, sep='\\t', comment='#') # ESS (simplified) for col in df.columns: if col != 'Gen': ess = len(df) / (1 + 2 * df[col].autocorr()) print(f"{col}: ESS ~ {ess:.0f}") return df # Use # df = check_convergence("input.log") """) print("\n=== Complete Pipeline ===") print(""" import subprocess from Bio import Phylo def phylo_pipeline(sequences, output_dir="phylo_output", threads=8): \"\"\"Complete phylogenetic pipeline.\"\"\" import os os.makedirs(output_dir, exist_ok=True) # 1. Align print("Aligning...") subprocess.run([ 'mafft', '--auto', sequences ], stdout=open(f'{output_dir}/aligned.fa', 'w'), check=True) # 2. Trim print("Trimming...") subprocess.run([ 'trimal', '-in', f'{output_dir}/aligned.fa', '-out', f'{output_dir}/trimmed.fa', '-automated1' ], check=True) # 3. Model selection + Tree print("Building tree...") tree_file = run_iqtree(f'{output_dir}/trimmed.fa', prefix=f'{output_dir}/tree') # 4. Parse tree = Phylo.read(tree_file, "newick") print(f"Tree: {len(tree.get_terminals())} taxa") return tree_file # Use # tree = phylo_pipeline("sequences.fa") """)

๐ŸŽจ Visualization

๐ŸŽฏ Seeing the Tree

Tree visualization is essential for interpretation and publication. FigTree, iTOL, and ggtree are the standard tools.

Visualization

FigTree: GUI. iTOL: Web. ggtree: R. Toytree: Python. Dendroscope: Networks. Evolview: Web.

๐ŸŽจ FigTree๐ŸŽจ iTOL๐ŸŽจ ggtree๐ŸŽจ Toytree
# Visualization print("=== FigTree ===") print(""" FigTree: - GUI - Free - Standard - Java Features: - Load Newick/Nexus - Root - Branch lengths - Support values - Node labels - Colors - Export PDF/SVG Workflow: 1. Open tree 2. Root (outgroup) 3. Adjust layout 4. Color clades 5. Export """) print("\n=== iTOL ===") print(""" iTOL (Interactive Tree Of Life): - Web - Free - Interactive - Publication Features: - Drag and drop - Annotations - Colors - Heatmaps - Metadata - Export Workflow: 1. Upload tree 2. Annotate 3. Customize 4. Export Web: itol.embl.de """) print("\n=== ggtree (R) ===") print(""" ggtree: - R package - ggplot2-based - Flexible - Publication R code: library(ggtree) library(treeio) # Load tree <- read.tree("tree.nwk") # Plot ggtree(tree) + geom_tiplab() + geom_nodelab() + theme_tree2() # Annotate ggtree(tree) + geom_tiplab() + geom_text2(aes(label=label), color="red") # Heatmap gheatmap(p, data, width=0.5) """) print("\n=== Toytree (Python) ===") print(""" toytree: - Python - Interactive - Publication Python code: import toytree # Load tree = toytree.tree("tree.nwk") # Plot tree.draw() # Customize tree.draw( tip_labels=True, node_labels=True, edge_widths=2, tip_labels_colors="blue" ) # Save tree.draw().save("tree.png") """) print("\n=== Dendroscope ===") print(""" Dendroscope: - Networks - Trees - Large datasets Features: - Interactive - Tanglegram - Networks - Export """) print("\n=== Evolview ===") print(""" Evolview: - Web - Free - Annotations Features: - Upload tree - Annotate - Colors - Heatmaps - Export Web: www.evolgenius.info/evolview """) print("\n=== Comparison ===") print(f"{'Tool':<20} {'Platform':<15} {'Best For':<25}") print("-" * 60) print(f"{'FigTree':<20} {'GUI':<15} {'Standard':<25}") print(f"{'iTOL':<20} {'Web':<15} {'Interactive':<25}") print(f"{'ggtree':<20} {'R':<15} {'Publication':<25}") print(f"{'Toytree':<20} {'Python':<15} {'Python users':<25}") print(f"{'Dendroscope':<20} {'GUI':<15} {'Networks':<25}") print(f"{'Evolview':<20} {'Web':<15} {'Annotations':<25}") print("\n=== Best Practices ===") print(""" 1. Root properly 2. Show support values 3. Use scale bar 4. Colorblind-friendly 5. High resolution 6. Vector format 7. Annotate metadata 8. Document parameters """)

๐Ÿ’ผ Use Cases

๐ŸŽฏ Where ML & Bayesian Are Used

ML and Bayesian phylogenetics are used in virtually every area of biology: evolution, epidemiology, conservation, and more.

Use Cases

Evolution: Relationships. Epidemiology: Outbreaks. Conservation: Diversity. Taxonomy: Species. Genes: Families. Cancer: Clonal.

๐Ÿ’ผ Evolution๐Ÿ’ผ Epidemiology๐Ÿ’ผ Conservation๐Ÿ’ผ Taxonomy
# Use Cases print("=== 1. Species Phylogeny ===") print(""" Use case: - Evolutionary relationships - Classification - Divergence times Workflow: 1. Collect sequences 2. MSA (MAFFT) 3. Trim (Gblocks) 4. Model selection 5. Tree (IQ-TREE) 6. Dating (BEAST) 7. Visualize (FigTree) Examples: - Human evolution - Darwin's finches - Mammals - Plants Tools: - IQ-TREE - BEAST - FigTree """) print("\n=== 2. Viral Epidemiology ===") print(""" Use case: - Outbreak tracking - Transmission - Origin Workflow: 1. Sequence 2. Align 3. Tree 4. Phylodynamics 5. Report Examples: - SARS-CoV-2 - Ebola - Influenza - HIV Tools: - Nextstrain - BEAST - TreeTime - IQ-TREE """) print("\n=== 3. Conservation Genetics ===") print(""" Use case: - Genetic diversity - ESUs - Management Workflow: 1. Sample populations 2. Sequence 3. Tree 4. Diversity 5. Management Examples: - Endangered species - Population structure - Connectivity Tools: - BEAST - Structure - DIYABC """) print("\n=== 4. DNA Barcoding ===") print(""" Use case: - Species identification - Cryptic species - Biodiversity Workflow: 1. Sequence COI 2. Align 3. Tree 4. Identify 5. Barcode Examples: - Animals - Plants - Fungi - Microbes Tools: - MEGA - BOLD - IQ-TREE """) print("\n=== 5. Gene Family Evolution ===") print(""" Use case: - Gene duplication - Orthologs - Paralogs Workflow: 1. Identify genes 2. Align 3. Tree 4. Reconcile 5. Analyze Examples: - Olfactory receptors - Immune genes - Hox genes Tools: - OrthoFinder - IQ-TREE - CAFE """) print("\n=== 6. Cancer Evolution ===") print(""" Use case: - Clonal evolution - Driver mutations - Metastasis Workflow: 1. Sequence tumor 2. Variants 3. Tree 4. Clonal 5. Treatment Examples: - Leukemia - Breast cancer - Lung cancer Tools: - BEAST - PyClone - SciClone """) print("\n=== 7. Horizontal Gene Transfer ===") print(""" Use case: - HGT - Microbial evolution - Antibiotic resistance Workflow: 1. Sequence 2. Tree 3. Compare 4. HGT 5. Analyze Examples: - Antibiotic resistance - Pathogenicity islands - Symbiosis Tools: - IQ-TREE - RANGER-DTL - Notung """) print("\n=== 8. Drug Discovery ===") print(""" Use case: - Target identification - Conservation - Resistance Workflow: 1. Tree 2. Conserved targets 3. Drug design 4. Resistance Examples: - Antibiotics - Antivirals - Cancer drugs Tools: - IQ-TREE - MEGA """) print("\n=== Comparison ===") print(f"{'Use Case':<25} {'Tool':<20} {'Output':<20}") print("-" * 65) print(f"{'Species phylogeny':<25} {'IQ-TREE + BEAST':<20} {'Time tree':<20}") print(f"{'Viral epidemiology':<25} {'Nextstrain':<20} {'Spread':<20}") print(f"{'Conservation':<25} {'BEAST':<20} {'ESUs':<20}") print(f"{'DNA barcoding':<25} {'MEGA':<20} {'Species ID':<20}") print(f"{'Gene family':<25} {'OrthoFinder':<20} {'Orthologs':<20}") print(f"{'Cancer':<25} {'PyClone':<20} {'Clones':<20}") print(f"{'HGT':<25} {'RANGER-DTL':<20} {'Transfers':<20}") print(f"{'Drug discovery':<25} {'IQ-TREE':<20} {'Targets':<20}")

โ“ FAQ

๐ŸŽฏ Frequently Asked Questions

Answers to common questions about ML and Bayesian phylogenetics.

What is Maximum Likelihood in phylogenetics?

Maximum Likelihood (ML) is a statistical method that finds the tree topology and branch lengths that maximize the probability of observing the sequence data given an explicit evolutionary model. It uses a substitution model (e.g., GTR+G) and searches tree space for the tree with the highest likelihood.

What is Bayesian inference in phylogenetics?

Bayesian inference estimates the posterior probability distribution of trees using Bayes' theorem and Markov Chain Monte Carlo (MCMC). It combines the likelihood with prior distributions and produces posterior probabilities for branches, offering a natural measure of uncertainty. Tools include MrBayes and BEAST.

What is the difference between ML and Bayesian phylogenetics?

ML finds the single best tree (point estimate) and uses bootstrap for support. Bayesian inference samples many trees from the posterior distribution, providing posterior probabilities and credible intervals. Bayesian methods allow prior information, handle complex models, and are often slower but more informative.

Which tool should I use for ML phylogenetics?

Use IQ-TREE for fast ML with ModelFinder and ultrafast bootstrap (recommended for most analyses), RAxML or RAxML-NG for established workflows and large datasets, PhyML for a simple GUI/CLI alternative, and FastTree for very large datasets where speed is critical.

What is MCMC convergence and why does it matter?

MCMC convergence means the Markov chains have explored the posterior distribution and are sampling from it. It's assessed using Effective Sample Size (ESS > 200), Potential Scale Reduction Factor (PSRF ~ 1.0), trace plots, and autocorrelation. Without convergence, posterior estimates are unreliable.

How do I choose the right substitution model?

Use ModelFinder (IQ-TREE), jModelTest, or Modeltest-NG to select the best model based on AIC/BIC. For DNA, start with GTR+F+I+G4; for protein, use LG or WAG. Always report the selected model and consider partitioning for multi-gene datasets.

What is the difference between bootstrap and posterior probability?

Bootstrap (ML) resamples columns and counts how often a branch appears; values > 70% indicate support. Posterior probability (Bayesian) is the frequency of a branch in the posterior distribution; values > 0.95 indicate support. PP tends to be higher and less conservative than bootstrap.

What is the difference between ML and Bayesian for time trees?

For time-calibrated trees, BEAST (Bayesian) is the standard tool, using relaxed clocks and fossil calibrations. MCMCtree (PAML) and TreeTime offer ML-based alternatives. Bayesian methods naturally provide credible intervals for divergence times.

What is long-branch attraction?

Long-branch attraction (LBA) is an artifact where rapidly evolving lineages are incorrectly grouped together because they share many convergent changes. It affects parsimony and distance methods more than ML. Mitigate by using ML with appropriate models, adding taxa, or removing fast-evolving sites.

How many bootstrap replicates do I need?

Use 1000 replicates for standard bootstrap, or 1000 ultrafast bootstrap (UFBoot) replicates in IQ-TREE. UFBoot is much faster and equally accurate. For SH-aLRT, use 1000 replicates. Report the number and method used.

# Quick Reference print("=== Quick Answers ===") print(""" Q: What is ML? A: Find tree maximizing likelihood. Q: What is Bayesian? A: Sample posterior distribution. Q: Difference? A: ML point estimate; Bayesian distribution. Q: Best ML tool? A: IQ-TREE. Q: Best Bayesian tool? A: MrBayes, BEAST. Q: Model selection? A: ModelFinder, jModelTest. Q: MCMC convergence? A: ESS > 200, PSRF ~ 1.0. Q: Support? A: Bootstrap (ML), PP (Bayesian). Q: Time trees? A: BEAST. Q: Free tools? A: Yes โ€” all major tools are free. """)

๐Ÿš€ Future

๐ŸŽฏ Where ML & Bayesian Are Going

The future is phylogenomic, AI-augmented, real-time, integrative, and scalable.

Future Directions

Phylogenomics: Whole genomes. AI: Deep learning. Real-time: Epidemiology. Coalescent: Species trees. Integration: Multi-omics. Scalable: Millions of taxa.

๐Ÿš€ Phylogenomics๐Ÿš€ AI๐Ÿš€ Real-time๐Ÿš€ Coalescent
# Future of ML & Bayesian Phylogenetics print("=== 1. Phylogenomics ===") print(""" Trend: Whole genomes Current: - Few genes - Concatenation Phylogenomics: - Whole genomes - Thousands of genes - Coalescent methods Examples: - 10K genomes - Bird phylogeny - Mammal phylogeny Tools: - ASTRAL - IQ-TREE - RAxML-NG - PhyloBayes """) print("\n=== 2. AI-Augmented Phylogenetics ===") print(""" Trend: Deep learning Ideas: - Learned models - Neural networks - Transformer - Graph neural networks Examples: - PhyloNet - Deep learning for tree inference - CNN for model selection Future: - Learned representations - Faster - More accurate - Complex models """) print("\n=== 3. Real-Time Phylogenetics ===") print(""" Trend: Real-time Current: - Batch - Slow Real-time: - During outbreak - Continuous - Dashboard Examples: - Nextstrain - GISAID - COVID-19 Tools: - Nextstrain - TreeTime - BEAST """) print("\n=== 4. Coalescent Methods ===") print(""" Trend: Species trees Current: - Concatenation - Gene trees Coalescent: - Incomplete lineage sorting - Species tree - Multi-species coalescent Tools: - ASTRAL - BPP - SNAPP - StarBEAST """) print("\n=== 5. Scalable Bayesian ===") print(""" Trend: Large-scale Bayesian Current: - Small datasets - Slow Future: - Millions of taxa - Fast MCMC - Variational inference - GPU Tools: - MrBayes - RevBayes - PhyloBayes - BEAST """) print("\n=== 6. Integration ===") print(""" Trend: Integrate everything Current: - Single data type - Separate analysis Future: - Multi-omics - Integration - Systems biology Examples: - Genomics + transcriptomics - Proteomics + phylogenetics - Metabolomics + evolution Tools: - BEAST - RevBayes - MrBayes """) # TIMELINE print("\n=== Timeline ===") print(""" Past: 1981: ML (Felsenstein) 1990s: Bayesian 1996: MrBayes 2000s: RAxML, PhyML 2010s: IQ-TREE, BEAST 2020s: ModelFinder, UFBoot Present: 2025: Phylogenomics 2026: AI-augmented Future: 2030: Real-time? 2035: Scalable Bayesian? 2040: Predictive phylogenetics? """) print("\n=== Final Thoughts ===") print(""" ML & Bayesian are: - Statistical - Model-based - Accurate - Publication standard The future is: - Phylogenomics - AI-augmented - Real-time - Coalescent - Scalable - Integrative "Nothing in biology makes sense except in the light of evolution." โ€” Theodosius Dobzhansky Keep exploring. Keep building. """)