This document details the query methods available on NgramModel.
Compute log probability of a word given context.
fn log_prob(&self, word: &str, context: &[&str]) -> f64Parameters:
word: Target word to scorecontext: Preceding words (up toorder - 1)
Returns: Log probability (base e, always negative or zero)
Example:
let prob = model.log_prob("fox", &["quick", "brown"]);
// prob ≈ -2.345 (log probability)
// Convert to probability
let p = prob.exp(); // p ≈ 0.096Behavior:
- Uses Modified Kneser-Ney smoothing
- Backs off to shorter contexts if needed
- Returns
unk_log_prob()for unknown words without context
Compute probability (not log) of a word given context.
fn prob(&self, word: &str, context: &[&str]) -> f64Convenience wrapper: self.log_prob(word, context).exp()
Compute log probability of an entire sentence.
fn sentence_log_prob(&self, tokens: &[&str]) -> f64Example:
let tokens = ["the", "quick", "brown", "fox"];
let log_prob = model.sentence_log_prob(&tokens);
// log_prob ≈ -12.456Computation:
// Equivalent to:
let mut total = 0.0;
for i in 0..tokens.len() {
let context_start = i.saturating_sub(order - 1);
total += model.log_prob(&tokens[i], &tokens[context_start..i]);
}Compute perplexity of a sentence.
fn perplexity(&self, tokens: &[&str]) -> f64Formula: exp(-log_prob / N) where N is token count
Interpretation:
- Lower perplexity = better model fit
- Perplexity of N means model is as uncertain as uniform choice from N words
Check if a word is in the model's vocabulary.
fn in_vocabulary(&self, word: &str) -> boolExample:
if model.in_vocabulary("fox") {
// Word seen during training
} else {
// OOV word
}Get vocabulary size.
fn vocab_size(&self) -> usizeReturns count of unique unigrams.
Get total n-gram count.
fn ngram_count(&self) -> usizeReturns count of all n-grams (all orders).
Get the model order.
fn order(&self) -> usizeExample:
let order = model.order(); // 3 for trigram model
let context_len = order - 1; // Maximum context lengthGet log probability for unknown words.
fn unk_log_prob(&self) -> f64Returns the probability assigned to unseen words (typically very low).
Iterate over vocabulary words.
fn iter_vocabulary(&self) -> impl Iterator<Item = &str>Example:
for word in model.iter_vocabulary() {
println!("{}: {}", word, model.prob(word, &[]));
}Iterate over all n-grams.
fn iter_ngrams(&self) -> impl Iterator<Item = (&str, &NgramEntry)>Example:
for (ngram, entry) in model.iter_ngrams() {
println!("{}: count={}", ngram, entry.count());
}Get most likely next words.
fn predict_next(&self, context: &[&str], k: usize) -> Vec<(String, f64)>Parameters:
context: Preceding wordsk: Number of predictions to return
Returns: Vector of (word, log_prob) sorted by probability descending
Example:
let predictions = model.predict_next(&["the", "quick"], 5);
for (word, log_prob) in predictions {
println!("{}: {:.4}", word, log_prob);
}
// Output:
// brown: -1.234
// fox: -2.345
// dog: -2.567
// ...Sample a word from the distribution.
fn sample(&self, context: &[&str], rng: &mut impl Rng) -> StringExample:
use rand::thread_rng;
let mut rng = thread_rng();
let word = model.sample(&["the", "quick"], &mut rng);
println!("Sampled: {}", word);Generate a sequence of words.
fn generate(&self, seed: &[&str], length: usize, rng: &mut impl Rng) -> Vec<String>Example:
let mut rng = thread_rng();
let text = model.generate(&["the"], 10, &mut rng);
println!("{}", text.join(" "));
// Output: "the quick brown fox jumps over the lazy dog and"Score multiple queries efficiently.
fn batch_log_prob(&self, queries: &[(String, Vec<String>)]) -> Vec<f64>Example:
let queries = vec![
("fox".to_string(), vec!["quick".to_string(), "brown".to_string()]),
("dog".to_string(), vec!["lazy".to_string()]),
];
let scores = model.batch_log_prob(&queries);Score sentences in parallel.
fn parallel_score_sentences(&self, sentences: &[Vec<&str>]) -> Vec<f64>Uses Rayon for parallel processing.
Get raw count for an n-gram.
fn get_count(&self, ngram: &[&str]) -> Option<u64>Example:
let count = model.get_count(&["the", "quick", "brown"]);
// count = Some(42) or None if not foundGet count of context occurrences.
fn get_context_count(&self, context: &[&str]) -> u64Example:
let count = model.get_context_count(&["the", "quick"]);
// How many times "the quick" was followed by any worduse rayon::prelude::*;
// Parallel scoring
let scores: Vec<f64> = sentences.par_iter()
.map(|s| model.sentence_log_prob(s))
.collect();// Find n-grams with low probability
let unusual: Vec<_> = test_ngrams.iter()
.filter(|ng| model.log_prob(&ng.last().unwrap(), &ng[..ng.len()-1]) < -10.0)
.collect();fn corpus_perplexity(model: &NgramModel<D>, sentences: &[Vec<&str>]) -> f64 {
let mut total_log_prob = 0.0;
let mut total_tokens = 0;
for sentence in sentences {
total_log_prob += model.sentence_log_prob(sentence);
total_tokens += sentence.len();
}
(-total_log_prob / total_tokens as f64).exp()
}- Trie Storage - Backend details
- NgramModel API - Complete API reference
- Training Guide - Training workflow