#![cfg(all(feature = "eda", feature = "smartcore-backend"))]
use millwright::prelude::*;
const PLAY_TENNIS: &str = "\
outlook,temperature,humidity,windy,play
sunny,hot,high,false,no
sunny,hot,high,true,no
overcast,hot,high,false,yes
rainy,mild,high,false,yes
rainy,cool,normal,false,yes
rainy,cool,normal,true,no
overcast,cool,normal,true,yes
sunny,mild,high,false,no
sunny,cool,normal,false,yes
rainy,mild,normal,false,yes
sunny,mild,normal,true,yes
overcast,mild,high,true,yes
overcast,hot,normal,false,yes
rainy,mild,high,true,no
";
fn write_csv() -> std::path::PathBuf {
let path = std::env::temp_dir().join(format!("mw_playtennis_{}.csv", std::process::id()));
std::fs::write(&path, PLAY_TENNIS).unwrap();
path
}
#[test]
fn play_tennis_end_to_end() {
let path = write_csv();
let table = Table::from_csv(&path).unwrap();
assert_eq!(table.shape(), (14, 5));
for col in ["outlook", "temperature", "humidity", "play"] {
assert_eq!(table.kind(col).unwrap(), ColKind::Categorical, "{col}");
}
assert_eq!(table.kind("windy").unwrap(), ColKind::Boolean);
let profile = Profile::of_with_target(&table, "play").unwrap();
match &profile.target().unwrap().kind {
TargetKind::Classification { classes } => {
assert_eq!(classes.len(), 2);
assert_eq!(classes.iter().map(|(_, n)| n).sum::<usize>(), 14);
}
_ => panic!("expected a classification target"),
}
let train = table.into_dataset("play").unwrap();
assert_eq!(train.features().shape(), (14, 4));
assert_eq!(train.features().categorical_columns().len(), 3);
let mut pipe = profile
.suggest_pipeline()
.estimator("lr", LogisticRegression::new().epochs(2000));
assert!(pipe.step_names().contains(&"encode"));
assert!(!pipe.step_names().contains(&"scale")); pipe.fit(&train).unwrap();
let preds = pipe.predict(train.features()).unwrap();
let correct = preds
.iter()
.zip(train.target())
.filter(|(p, t)| (**p - **t).abs() < 0.5)
.count();
let accuracy = correct as f64 / preds.len() as f64;
assert!(
accuracy >= 0.85,
"train accuracy on PlayTennis was {accuracy}"
);
let _ = std::fs::remove_file(&path);
}