Files
kickscore/examples/nba-history.rs
2020-09-08 15:32:29 +02:00

104 lines
2.6 KiB
Rust

extern crate openblas_src;
use std::collections::HashSet;
use std::fs;
use std::io::{self, BufRead};
use kickscore as ks;
use time::Date;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let reader = fs::File::open("examples/nba.csv").map(io::BufReader::new)?;
let mut teams = HashSet::new();
let mut observations = Vec::new();
let cutoff = time::date!(2019 - 06 - 01);
for line in reader.lines() {
let line = line?;
let data = line.split(',').collect::<Vec<_>>();
assert!(data.len() == 5);
let t = Date::parse(data[0], "%F")?;
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().timestamp() as f64;
let score_1: u16 = data[3].parse()?;
let score_2: u16 = data[4].parse()?;
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<Box<dyn ks::Kernel>> = 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();
println!("Probability that CHI beats BOS...");
let (p_win, _) = model.probabilities(
&[&"CHI"],
&[&"BOS"],
time::date!(1996 - 01 - 01)
.midnight()
.assume_utc()
.timestamp() as f64,
);
println!(" ... in 1996: {:.2}%", 100.0 * p_win);
let (p_win, _) = model.probabilities(
&[&"CHI"],
&[&"BOS"],
time::date!(2001 - 01 - 01)
.midnight()
.assume_utc()
.timestamp() as f64,
);
println!(" ... in 2001: {:.2}%", 100.0 * p_win);
let (p_win, _) = model.probabilities(
&[&"CHI"],
&[&"BOS"],
time::date!(2020 - 01 - 01)
.midnight()
.assume_utc()
.timestamp() as f64,
);
println!(" ... in 2020: {:.2}%", 100.0 * p_win);
Ok(())
}