feat: seeded transcription-error injection + Recall@k

This commit is contained in:
2026-05-18 18:26:43 +02:00
parent 079ecea2a3
commit 377fc84875
2 changed files with 56 additions and 1 deletions
+39 -1
View File
@@ -1 +1,39 @@
// implemented in a later task
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};
/// Inject realistic transcription errors deterministically (seeded):
/// char drop, adjacent swap, umlaut flattening, digit transposition.
pub fn inject_errors(text: &str, rate: f64, seed: u64) -> String {
let mut rng = StdRng::seed_from_u64(seed);
let mut chars: Vec<char> = text.chars().collect();
let n = chars.len();
let mut i = 0;
while i < chars.len() {
if rng.gen::<f64>() < rate {
match rng.gen_range(0..4) {
0 => { chars.remove(i); continue; } // drop
1 => { if i + 1 < chars.len() { chars.swap(i, i + 1); } } // swap
2 => { // flatten umlaut
chars[i] = match chars[i] {
'ä' => 'a', 'ö' => 'o', 'ü' => 'u', 'ß' => 's',
other => other,
};
}
_ => { // digit transpose
if chars[i].is_ascii_digit() && i + 1 < chars.len()
&& chars[i + 1].is_ascii_digit() {
chars.swap(i, i + 1);
}
}
}
}
i += 1;
}
let _ = n;
chars.into_iter().collect()
}
/// 1.0 if `expected` appears in the first k predictions, else 0.0.
pub fn recall_at_k(predicted: &[String], expected: &str, k: usize) -> f64 {
if predicted.iter().take(k).any(|p| p == expected) { 1.0 } else { 0.0 }
}