1pub use iris::{
2 classified::ClassifiedIris, params::IrisParams, species::IrisSpecies,
3 unclassified::UnclassifiedIris, Iris,
4};
5pub mod iris;
6
7pub use paths::*;
8pub mod paths {
9 pub const PATH_TO_TRAINING_IRISES: &str = "./data/training_irises.csv";
12 pub const PATH_TO_TESTING_IRISES: &str = "./data/testing_irises.csv";
13}
14
15pub mod read;
16pub mod util;
17
18pub use app::{
19 args::AppArgs,
20 cfg::{app_cfg, AppCfg, APP_CFG},
21};
22pub mod app;
23
24use itertools::Itertools;
25
26#[macro_export]
27macro_rules! executable_desc{
28 () => {
29 "App for classifying irises into one of 3 species {Setosa, Versicolor, Virginica}.\n\
30 \n\
31 After running this app, it will:\n\
32 1. Perform an accuracy measure for the testing iris data file dwelling in the ./data folder. \
33 This can be disabled by app argument. \
34 Measure will be rendered to stderr.\n\
35 2. Read all irises from stdin untill EOF. Then classify them. \
36 This will be displayed in stdout.\
37 \n\
38 EXAMPLE usages for app is installed as `iris_classifier`:\n\
39 * `echo '1.,2,3,4' | iris_classifier`\n\
40 * `cat ./data/unclassified_irises.csv | iris_classifier`\n\
41 * `echo 'some.invalid.data' | iris_classifier --separator '.'`\n\
42 * `echo '1 2 3 4' | iris_classifier -s=' '`\n\
43 "
44 }
45}
46
47pub fn create_classifier(
51 classified_irises: Vec<ClassifiedIris>,
52 k: usize,
53) -> impl Fn(UnclassifiedIris) -> ClassifiedIris {
54 move |unclassified| {
55 let nearest_classifications = classified_irises
56 .iter()
57 .map(|classified| {
58 util::ComparedByDistSq::new(classified, classified.dist_sq(&unclassified))
59 })
60 .k_smallest(k)
61 .map(|cmpd_by_dist_sq| cmpd_by_dist_sq.val.classification);
62 let mode = util::mode(nearest_classifications).unwrap();
63
64 ClassifiedIris::new(unclassified, mode)
65 }
66}
67
68pub fn classify_irises<F>(
70 iris_classifier: F,
71 unclassified_irises: Vec<UnclassifiedIris>,
72) -> Vec<ClassifiedIris>
73where
74 F: (Fn(UnclassifiedIris) -> ClassifiedIris) + Send + Sync,
75{
76 use rayon::iter::{IntoParallelIterator, ParallelIterator};
77
78 unclassified_irises
79 .into_par_iter()
80 .map(iris_classifier)
81 .collect()
82}