Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commitb99abb4a606958be17f19e88a79884e80435e030 (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-01-05 20:22:56 +0200
Committer
 Syndamia <kamen@syndamia.com>
2025-01-05 20:22:56 +0200
Files1d27010870796ce803a4f554225e2f2fc0c1bb48
uni-projects-b99abb4a606958be17f19e88a79884e80435e030.tar
uni-projects-b99abb4a606958be17f19e88a79884e80435e030.tar.gz
uni-projects-b99abb4a606958be17f19e88a79884e80435e030.zip
Parent79302b63a160c7c6360ac1db773351fcdb909792 (diff)
hw(AT/5): Implement cross validation
diff --git a/Year 4/Artificial Intelligence/hw05/src/data.rs b/Year 4/Artificial Intelligence/hw05/src/data.rs
index 7569b2c..fb425b1 100644
--- a/Year 4/Artificial Intelligence/hw05/src/data.rs
+++ b/Year 4/Artificial Intelligence/hw05/src/data.rs
@@ -133,6 +133,23 @@ pub fn get_data() -> (Vec<Person>, Vec<Person>) {
(a, b)
}
+pub fn get_dataset() -> Vec<Person> {
+ let mut ret = dataset.to_vec();
+ ret.shuffle(&mut thread_rng());
+ ret
+}
+
+/// Returns (training, testing)
+pub fn get_data_fold(fold: usize, total_folds: usize, ds: &Vec<Person>) -> (Vec<Person>, Vec<Person>) {
+ let length = (ds.len() as f64 / total_folds as f64) as usize;
+ let start = fold * length;
+ let end = start + length;
+
+ let mut training = ds[..start].to_vec();
+ training.append(&mut ds[end..].to_vec());
+ (training, ds[start..end].to_vec())
+}
+
static dataset: [Person; 435] = [
Person::new(democrat,n,n,n,n,n,n,y,y,y,y,n,y,y,y,y,y),
Person::new(democrat,n,n,n,n,n,y,n,y,y,n,y,y,y,y,y,n),
diff --git a/Year 4/Artificial Intelligence/hw05/src/main.rs b/Year 4/Artificial Intelligence/hw05/src/main.rs
index 6a53ee8..2ba3980 100644
--- a/Year 4/Artificial Intelligence/hw05/src/main.rs
+++ b/Year 4/Artificial Intelligence/hw05/src/main.rs
@@ -20,6 +20,8 @@ fn test(prob: &PMaps, people: &Vec<Person>) -> f64 {
count_succ / people.len() as f64
}
+static folds: usize = 10;
+
fn main() {
let fill: u8 = read!();
let fill = fill == 1;
@@ -34,7 +36,22 @@ fn main() {
// No laplace, so that's probably why it's not 92.80%
println!("1. Train Set Accuracy:");
println!(" Accuracy: {:.2}%", test(&prob, &training) * 100.0);
+ println!("");
+
+ println!("{}-Fold Cross-Validation Results:", folds);
+ let mut accuracy = Vec::new();
+ for i in 1..=folds {
+ let (training, testing) = data::get_data_fold(i-1, folds, &training);
+ accuracy.push(test(&prob, &testing));
+ println!(" Accuracy Fold {}: {:.2}%", i, accuracy.last().unwrap() * 100.0);
+ }
+ println!("");
+
+ let avg = accuracy.clone().into_iter().sum::<f64>();
+ println!(" Average Accuracy: {:.2}%", avg / folds as f64 * 100.0);
+ println!(" Standard Deviation: {:.2}%", (accuracy.into_iter().map(|x| (x - avg).powi(2)).sum::<f64>() / folds as f64).sqrt());
+ println!("");
println!("2. Test Set Accuracy:");
println!(" Accuracy: {:.2}%", test(&prob, &testing) * 100.0);
}
diff --git a/Year 4/Artificial Intelligence/hw05/src/probabilities.rs b/Year 4/Artificial Intelligence/hw05/src/probabilities.rs
index bf696e3..7468bdb 100644
--- a/Year 4/Artificial Intelligence/hw05/src/probabilities.rs
+++ b/Year 4/Artificial Intelligence/hw05/src/probabilities.rs
@@ -72,7 +72,7 @@ pub fn value_3_probabilities(dataset: &Vec<Person>) -> PMaps {
ret_y.insert(name.to_string(), count_y / len);
ret_n.insert(name.to_string(), count_n / len);
ret_q.insert(name.to_string(), count_q / len);
- assert_eq!(count_y + count_n + count_q, len);
+ // assert_eq!(count_y + count_n + count_q, len);
}
let mut simple_p = HashMap::new();
@@ -80,12 +80,12 @@ pub fn value_3_probabilities(dataset: &Vec<Person>) -> PMaps {
simple_p.insert(Value::n, ret_n);
simple_p.insert(Value::q, ret_q);
- assert_eq!(
- simple_p[&Value::y]["crime"] +
- simple_p[&Value::n]["crime"] +
- simple_p[&Value::q]["crime"],
- 1.0,
- );
+ // assert_eq!(
+ // simple_p[&Value::y]["crime"] +
+ // simple_p[&Value::n]["crime"] +
+ // simple_p[&Value::q]["crime"],
+ // 1.0,
+ // );
// P(Value[attr]|Party)
let mut complex_p = HashMap::new();
@@ -114,7 +114,7 @@ pub fn value_3_probabilities(dataset: &Vec<Person>) -> PMaps {
ret_y.insert(name.to_string(), count_y / len);
ret_n.insert(name.to_string(), count_n / len);
ret_q.insert(name.to_string(), count_q / len);
- assert_eq!(count_y + count_n + count_q, 214.0);
+ // assert_eq!(count_y + count_n + count_q, 214.0);
}
let mut party_p = HashMap::new();
@@ -148,7 +148,7 @@ pub fn value_3_probabilities(dataset: &Vec<Person>) -> PMaps {
ret_y.insert(name.to_string(), count_y / len);
ret_n.insert(name.to_string(), count_n / len);
ret_q.insert(name.to_string(), count_q / len);
- assert_eq!(count_y + count_n + count_q, 134.0);
+ // assert_eq!(count_y + count_n + count_q, 134.0);
}
let mut party_p = HashMap::new();
@@ -158,12 +158,12 @@ pub fn value_3_probabilities(dataset: &Vec<Person>) -> PMaps {
complex_p.insert(Party::republican, party_p);
- assert_eq!(
- complex_p[&Party::republican][&Value::y]["crime"] +
- complex_p[&Party::republican][&Value::n]["crime"] +
- complex_p[&Party::republican][&Value::q]["crime"],
- 1.0,
- );
+ // assert_eq!(
+ // complex_p[&Party::republican][&Value::y]["crime"] +
+ // complex_p[&Party::republican][&Value::n]["crime"] +
+ // complex_p[&Party::republican][&Value::q]["crime"],
+ // 1.0,
+ // );
(simple_p, complex_p)
}