pub mod red_wine_quality;
pub mod white_wine_quality;
use csv::ReaderBuilder;
use dataset_core::DatasetError;
use ndarray::{Array1, Array2};
use serde::Deserialize;
pub(crate) type WineData = (Array2<f64>, Array1<f64>);
#[derive(Deserialize)]
struct WineRecord {
fixed_acidity: f64,
volatile_acidity: f64,
citric_acid: f64,
residual_sugar: f64,
chlorides: f64,
free_sulfur_dioxide: f64,
total_sulfur_dioxide: f64,
density: f64,
ph: f64,
sulphates: f64,
alcohol: f64,
quality: f64,
}
fn parse_wine_data_to_array<R: std::io::Read>(
dataset_name: &str,
reader: R,
) -> Result<WineData, DatasetError> {
let mut rdr = ReaderBuilder::new()
.delimiter(b';')
.has_headers(false)
.from_reader(reader);
let mut features_array = Vec::new();
let mut target_array = Vec::new();
for result in rdr.deserialize::<WineRecord>().skip(1) {
let WineRecord {
fixed_acidity,
volatile_acidity,
citric_acid,
residual_sugar,
chlorides,
free_sulfur_dioxide,
total_sulfur_dioxide,
density,
ph,
sulphates,
alcohol,
quality,
} = result.map_err(|e| DatasetError::csv_read_error(dataset_name, e))?;
features_array.extend_from_slice(&[
fixed_acidity,
volatile_acidity,
citric_acid,
residual_sugar,
chlorides,
free_sulfur_dioxide,
total_sulfur_dioxide,
density,
ph,
sulphates,
alcohol,
]);
target_array.push(quality);
}
let n_samples = target_array.len();
if n_samples == 0 {
return Err(DatasetError::empty_dataset(dataset_name));
}
let features_array = Array2::from_shape_vec((n_samples, 11), features_array)
.map_err(|e| DatasetError::array_shape_error(dataset_name, "features", e))?;
let target_array = Array1::from_vec(target_array);
Ok((features_array, target_array))
}