extern crate intel_mkl_src; use std::collections::HashSet; use std::fs; use std::io::{self, BufRead}; use approx::assert_abs_diff_eq; use kickscore as ks; use time::Date; #[test] fn nba_history() { let reader = fs::File::open("data/nba.csv") .map(io::BufReader::new) .unwrap(); let mut teams = HashSet::new(); let mut observations = Vec::new(); let cutoff = time::date!(2019 - 06 - 01); for line in reader.lines().skip(1) { let line = line.unwrap(); let data = line.split(',').collect::>(); assert!(data.len() == 5); let t = Date::parse(data[0], "%F").unwrap(); if t > cutoff { break; } teams.insert(data[1].to_string()); teams.insert(data[2].to_string()); if data[3].is_empty() || data[4].is_empty() { continue; } let t = t.midnight().assume_utc().unix_timestamp() as f64; let score_1: u16 = data[3].parse().unwrap(); let score_2: u16 = data[4].parse().unwrap(); if score_1 > score_2 { observations.push((data[1].to_string(), data[2].to_string(), t)); } else if score_1 < score_2 { observations.push((data[2].to_string(), data[1].to_string(), t)); } else { panic!("there shouldn't be any tie games"); } } let seconds_in_year = 365.25 * 24.0 * 60.0 * 60.0; let mut model = ks::BinaryModel::new(ks::BinaryModelObservation::Probit); for team in teams { let kernel: Vec> = vec![ Box::new(ks::kernel::Constant::new(0.03)), Box::new(ks::kernel::Matern32::new(0.138, 1.753 * seconds_in_year)), ]; model.add_item(&team, Box::new(kernel)); } for (winner, loser, t) in observations { model.observe(&[&winner], &[&loser], t); } model.fit(); let (p_win, _) = model.probabilities( &[&"CHI"], &[&"BOS"], time::date!(1996 - 01 - 01) .midnight() .assume_utc() .unix_timestamp() as f64, ); assert_abs_diff_eq!(p_win, 0.9002599772490479, epsilon = f64::EPSILON); let (p_win, _) = model.probabilities( &[&"CHI"], &[&"BOS"], time::date!(2001 - 01 - 01) .midnight() .assume_utc() .unix_timestamp() as f64, ); assert_abs_diff_eq!(p_win, 0.22837870685441986, epsilon = f64::EPSILON); let (p_win, _) = model.probabilities( &[&"CHI"], &[&"BOS"], time::date!(2020 - 01 - 01) .midnight() .assume_utc() .unix_timestamp() as f64, ); assert_abs_diff_eq!(p_win, 0.2748029998412422, epsilon = f64::EPSILON); }