1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//! Built-in dataset implementations for machine learning.
//!
//! `dataset-ml` provides ready-to-use loaders for classic ML datasets, built on top
//! of [`dataset_core::Dataset`]. Every loader lives in a module under `dataset`.
//! Each one is a worked example that shows how to wrap `Dataset<T, E>` for one
//! data source. The steps are the same each time:
//!
//! 1. Download from a URL.
//! 2. Verify a SHA-256 hash.
//! 3. Parse the source: CSV records, raw documents from an archive, or binary IDX images.
//! 4. Return a [`Table`] of named, typed columns.
//!
//! # Feature flags
//!
//! Both features are on by default. Turn one off to leave out what you do not use.
//!
//! | Feature | What it enables |
//! |-----------------|-----------------|
//! | `dataset` | The `dataset` module and its loaders, the crate-root re-export of every loader struct, and `DOWNLOAD_RETRIES`. It adds the `csv`, `serde`, and `tempfile` dependencies. |
//! | `preprocessing` | The `preprocessing` module: seeded train/test and k-fold splits, feature scaling, one-hot encoding, and label encoding. It adds no dependencies. |
//!
//! The `table` and `traits` modules are always available, whichever features you
//! pick. They hold [`Table`] and [`MlDataset`], so you can write a loader of your
//! own against the same interface with both features off.
//!
//! The `dataset` module lists every built-in dataset with its sample count,
//! feature count, and task type.
//!
//! # Example
//!
//! This example needs the `dataset` feature.
//!
//! ```no_run
//! use dataset_ml::Iris;
//!
//! let iris = Iris::new("./data");
//! let table = iris.data().unwrap();
//!
//! // Every loader returns a `Table`. Name the columns you want in the matrix.
//! let features = table.numeric_matrix(&Iris::FEATURE_NAMES).unwrap();
//! assert_eq!(features.shape(), &[150, 4]);
//!
//! // Or reach one column by name.
//! let species = table.column(Iris::TARGET).unwrap().as_string().unwrap();
//! assert_eq!(species.len(), 150);
//! ```
//!
//! The crate root re-exports every loader struct, so `dataset_ml::Iris` and
//! `dataset_ml::dataset::iris::Iris` name the same type. Use whichever path reads
//! better.
//!
//! All loaders are lazy. The first call downloads and parses the file. Every
//! later call returns a cached reference. See the individual module docs for
//! features, target, sample count, and source.
//!
//! # Beyond the loaders
//!
//! Two modules apply to every dataset here rather than to one of them:
//!
//! - `preprocessing`: seeded train/test and k-fold splits (plain or
//! class-stratified), feature scaling, one-hot encoding, and label encoding. You
//! can feed the arrays a loader returns straight to a model, without writing
//! that glue code by hand.
//! - [`table`]: the [`Table`] every loader returns, and the `Column` and
//! `ColumnData` types it holds.
//! - [`traits`]: the [`MlDataset`] trait every loader implements. It lets you
//! write code generically over "some dataset": cache inspection and
//! invalidation, plus a uniform `n_samples()`.
//!
//! This example needs the `dataset` and `preprocessing` features.
//!
//! ```no_run
//! use dataset_ml::preprocessing::{standardize, stratified_split};
//! use dataset_ml::traits::MlDataset;
//! use dataset_ml::Iris;
//! use ndarray::Axis;
//!
//! let iris = Iris::new("./data");
//! let table = iris.data().unwrap();
//!
//! let features = table.numeric_matrix(&Iris::FEATURE_NAMES).unwrap();
//! let species = table.column(Iris::TARGET).unwrap().as_string().unwrap();
//!
//! // Split with each species proportionally represented on both sides.
//! let (train, test) = stratified_split(species.as_slice().unwrap(), 0.2, 42).unwrap();
//! let (scaled_train, scaler) = standardize(&features.select(Axis(0), &train)).unwrap();
//!
//! assert_eq!(scaled_train.nrows(), 120);
//! assert_eq!(iris.n_samples().unwrap(), 150); // from the `MlDataset` trait
//! ```
/// How many extra download tries every loader in this crate makes before it
/// stops retrying.
///
/// The datasets are hosted on university archives and personal pages that
/// intermittently time out or reset a connection. A run that fails for that
/// reason is not a bug in the data. Every loader therefore fetches through
/// [`download_to_with_retries`](dataset_core::download_to_with_retries) with
/// this many retries. It waits 500 ms, then 1 s, between tries. A single blip
/// does not surface as a `DownloadError`.
///
/// The loader returns errors that retrying cannot fix right away. A genuinely
/// unreachable host costs at most 1.5 s of waiting before it fails.
pub const DOWNLOAD_RETRIES: u32 = 2;
/// Every built-in dataset loader, one module per data source.
///
/// The modules run from [`iris`](dataset::iris), the smallest, to
/// [`kddcup99`](dataset::kddcup99), the largest. Each one documents its features,
/// target, sample count, and source.
///
/// The crate root re-exports every loader struct, so `dataset_ml::Iris` is a
/// shorter name for `dataset_ml::dataset::iris::Iris`.
///
/// Needs the `dataset` feature, which is on by default.
/// Preprocessing helpers.
///
/// Turns what the loaders return into what a model consumes. It covers seeded
/// train/test and k-fold splits (plain or class-stratified), feature scaling,
/// one-hot encoding of the categorical matrices, and label encoding. Everything
/// is deterministic given a seed and depends on no extra crates.
///
/// Needs the `preprocessing` feature, which is on by default.
/// The [`Table`](table::Table) every loader parses into.
///
/// A `Table` holds one named, typed `Column` per source column. It materializes
/// a matrix out of the columns the caller names.
///
/// This module is always available, whichever features you pick.
/// The [`traits::MlDataset`] trait implemented by every loader in this crate.
///
/// Provides the container operations that stay the same whatever a loader parses
/// into: lazy access, cache inspection, cache invalidation, and a uniform sample
/// count. With it, you can write code generically over "some dataset" instead of
/// one concrete struct.
pub use ;
pub use ;
pub use MlDataset;