Training pipeline¶
How pathotypr turns a labeled multi-FASTA into a serialized random-forest classifier — from k-mer feature hashing through accuracy estimation, final training, and interpretable feature-importance export.
The train subcommand runs a six-step pipeline: it vectorizes labeled sequences with feature hashing, estimates accuracy, trains a final ensemble on all data, and writes a compressed model bundle alongside feature-importance reports. Each step below maps directly to pathotypr-core/src/train.rs.
End-to-end flow¶
Labeled FASTA ──→ Feature Hashing ──→ Accuracy Estimation ──→ Train Final Model ──→ OOB ──→ Save
(k-mer → sparse) (CV or single split) (all data, 100 trees) (bincode+zstd)
│
↓
Feature Importance
(reverse map k-mers + coords)
Step 1: Data preparation¶
Input format¶
Labeled multi-FASTA where the first token in each header is the class label:
Vectorization¶
Each sequence is transformed into a sparse feature vector via feature hashing:
- Extract all k-mers (default k=21) using needletail's 2-bit encoding
- Hash each k-mer into one of 2^20 buckets via bitmask
- Count occurrences per bucket
- Output: sorted sparse vector
Vec<(bucket_idx, count)>
Label encoding¶
Class labels (strings) are mapped to integers via LabelEncoder:
fit(): Builds bidirectional mapping (label ↔ integer)transform(): Converts label strings to integer indices- Minimum 2 distinct classes required
Step 2: Accuracy estimation¶
Two modes, controlled by --cv-folds:
Single train/test split (default)¶
- Shuffle indices with seed=42
- Hold out
test_splitfraction (default 20%) - Train a temporary 100-tree ensemble on the training portion
- Evaluate on the held-out test set
- Report accuracy percentage
Stratified k-fold cross-validation (--cv-folds k)¶
- Group sample indices by class
- Shuffle within each class (seed=42)
- Assign to folds round-robin → preserves class proportions
- For each fold:
- Train 100-tree ensemble on k-1 folds
- Evaluate on the held-out fold
- Report: mean accuracy ± standard deviation (Bessel's correction: divide by n-1)
Estimation uses throwaway models
The accuracy estimation step trains throwaway ensembles. The final model is always trained on all data.
Step 3: Final model training¶
- Uses all samples (no held-out set)
- Trains 100 trees in parallel via rayon (see random-forest.md)
- Returns both trees and their bootstrap seeds (for OOB computation)
Step 4: Out-of-bag accuracy¶
Always computed on the final model (see random-forest.md):
- Regenerates each tree's bootstrap from its seed
- For each sample, collects votes only from trees where it was OOB (~37% of trees)
- Reports majority-vote accuracy across all samples
Free accuracy estimate
OOB provides a nearly unbiased accuracy estimate at zero additional cost.
Step 5: Model serialization¶
Format¶
ModelBundle {
config: ModelConfig {
pathotypr_version, // e.g., "0.2.0"
kmer_size, // e.g., 21
n_trees, // 100
format_version, // 3 (current)
},
vectorizer: FeatureHasher { num_buckets },
label_encoder: LabelEncoder { maps },
trees: Vec<SparseDecisionTree>,
}
Compression pipeline¶
Memory-efficient streaming
Streaming serialization: bincode writes directly into the zstd compressor, which writes to a buffered file. Never holds the full uncompressed + compressed model in memory simultaneously.
Typical sizes: 5–50 MB compressed for real bacterial genomes; <3 KB for synthetic benchmarks.
Step 6: Feature importance export¶
Importance TSV (model.importance.tsv)¶
Top 500 features ranked by split count:
rank bucket split_count importance_pct kmers
1 42 87 2.31 ACTGACTGCTAGCTGATCGATC,GATCGATCGATCGATCGATCG
2 1087 73 1.94 ...
importance_pct = split_count / total_splits_across_all_features × 100
Genomic coordinates TSV (model.importance.coords.tsv)¶
Maps each discriminant k-mer back to its physical location in the training sequences:
rank bucket split_count importance_pct kmer sequence lineage position
1 42 87 2.31 ACTG... seq_header L4 1234567
This enables researchers to identify which genomic regions drive classification — linking ML features to biology.
Computational cost¶
| Dataset | Training Time | Model Size |
|---|---|---|
| 100 bacterial genomes | ~10 s | ~10 MB |
| 500 bacterial genomes | ~30 s | ~20 MB |
| 4000 synthetic sequences | ~2 s | ~2.5 KB |
Times measured on Apple M4 (4 cores). Training scales approximately linearly with dataset size due to the tree construction dominating.