dataset_ml/lib.rs
1//! Built-in dataset implementations for machine learning.
2//!
3//! `dataset-ml` provides ready-to-use loaders for classic ML datasets, built on top
4//! of [`dataset_core::Dataset`]. Each module is a worked example that shows how to
5//! wrap `Dataset<T, E>` for one data source. The steps are the same each time:
6//!
7//! 1. Download from a URL.
8//! 2. Verify a SHA-256 hash.
9//! 3. Parse CSV records, or extract raw documents from an archive.
10//! 4. Expose typed accessors backed by [`ndarray`].
11//!
12//! # Datasets
13//!
14//! | Module | Samples | Features | Task Type |
15//! |-------------------------------------------------------|---------|----------|----------------|
16//! | [`abalone`] | 4,177 | 8 | Regression |
17//! | [`adult`] | 32,561 | 14 | Classification |
18//! | [`bank_marketing`] | 45,211 | 16 | Classification |
19//! | [`banknote_authentication`] | 1,372 | 4 | Classification |
20//! | [`iris`] | 150 | 4 | Classification |
21//! | [`breast_cancer`] | 569 | 30 | Classification |
22//! | [`boston_housing`] | 506 | 13 | Regression |
23//! | [`california_housing`] | 20,640 | 8 | Regression |
24//! | [`car_evaluation`] | 1,728 | 6 | Classification |
25//! | [`covtype`] | 581,012 | 54 | Classification |
26//! | [`diabetes`] | 442 | 10 | Regression |
27//! | [`digits`] | 1,797 | 64 | Classification |
28//! | [`heart_disease`] | 303 | 13 | Classification |
29//! | [`ionosphere`] | 351 | 34 | Classification |
30//! | [`kddcup99`] | 494,021 / 4,898,431 | 41 | Classification |
31//! | [`letter_recognition`] | 20,000 | 16 | Classification (26 classes) |
32//! | [`linnerud`] | 20 | 3 | Regression (multi-output) |
33//! | [`mushroom`] | 8,124 | 22 | Classification |
34//! | [`spambase`] | 4,601 | 57 | Classification |
35//! | [`titanic`] | 891 | 11 | Classification |
36//! | [`palmer_penguins`] | 344 | 7 | Classification |
37//! | [`sms_spam`] | 5,574 | text | Classification |
38//! | [`wine_recognition`] | 178 | 13 | Classification |
39//! | [`wine_quality::red_wine_quality`] | 1,599 | 11 | Regression |
40//! | [`wine_quality::white_wine_quality`] | 4,898 | 11 | Regression |
41//! | [`youtube_spam`] | 1,956 | text | Classification |
42//! | [`sentiment_sentences`] | 3,000 | text | Classification |
43//! | [`newsgroups20`] | 11,314 / 18,846 | text | Classification |
44//! | [`movie_review_polarity`] | 2,000 | text | Classification |
45//!
46//! # Example
47//!
48//! ```no_run
49//! use dataset_ml::iris::Iris;
50//!
51//! let iris = Iris::new("./data");
52//! let (features, labels) = iris.data().unwrap();
53//! assert_eq!(features.shape(), &[150, 4]);
54//! ```
55//!
56//! All loaders are lazy: the first call downloads and parses the file, every
57//! subsequent call returns a cached reference. See the individual module docs
58//! for features, target, sample count, and source.
59//!
60//! # Beyond the loaders
61//!
62//! Two modules apply to every dataset here rather than to one of them:
63//!
64//! - [`preprocessing`]: seeded train/test and k-fold splits (plain or
65//! class-stratified), feature scaling, one-hot encoding, and label encoding. You
66//! can feed the arrays a loader returns straight to a model, without writing
67//! that glue code by hand.
68//! - [`traits`]: the [`MlDataset`] trait every loader implements. It lets you
69//! write code generically over "some dataset": cache inspection and
70//! invalidation, plus a uniform `n_samples()`.
71//!
72//! ```no_run
73//! use dataset_ml::preprocessing::{stratified_split, standardize};
74//! use dataset_ml::traits::MlDataset;
75//! use dataset_ml::Iris;
76//! use ndarray::Axis;
77//!
78//! let iris = Iris::new("./data");
79//! let (features, labels) = iris.data().unwrap();
80//!
81//! // Split with each species proportionally represented on both sides.
82//! let (train, test) = stratified_split(labels.as_slice().unwrap(), 0.2, 42).unwrap();
83//! let (scaled_train, scaler) = standardize(&features.select(Axis(0), &train)).unwrap();
84//!
85//! assert_eq!(scaled_train.nrows(), 120);
86//! assert_eq!(iris.n_samples().unwrap(), 150); // from the `MlDataset` trait
87//! ```
88
89/// How many extra download attempts every loader in this crate makes before it
90/// stops retrying.
91///
92/// The datasets are hosted on university archives and personal pages that
93/// intermittently time out or reset a connection. A run that fails for that
94/// reason is not a bug in the data. Every loader therefore fetches through
95/// [`download_to_with_retries`](dataset_core::download_to_with_retries) with this
96/// many retries, waiting 500 ms then 1 s between attempts. A single blip does
97/// not surface as a `DownloadError`.
98///
99/// The loader returns errors that retrying cannot fix right away, and a
100/// genuinely unreachable host costs at most 1.5 s of waiting before it fails.
101pub const DOWNLOAD_RETRIES: u32 = 2;
102
103/// Abalone dataset module.
104///
105/// Contains the Abalone dataset (UCI, Nash et al. 1994) for **regression**. It
106/// predicts an abalone's `rings` (age in years is `rings + 1.5`) from 8 mixed
107/// features: 1 categorical `sex` feature and 7 numeric physical measurements.
108/// Unlike the other mixed-type loaders (which are classification tasks), its
109/// target is an `Array1<f64>` regression target via `targets()`.
110pub mod abalone;
111
112/// Adult / Census Income dataset module.
113///
114/// Contains the Adult dataset (also called "Census Income") for binary
115/// classification. It predicts whether a person earns over $50K/year from 14
116/// mixed features: 8 categorical and 6 numeric, covering demographic and
117/// employment attributes. Extracted from the 1994 US Census. Uses the canonical
118/// `adult.data` training partition.
119pub mod adult;
120
121/// Bank Marketing dataset module.
122///
123/// Contains the Bank Marketing dataset for binary classification. It predicts
124/// whether a client subscribes to a term deposit from 16 mixed features: 9
125/// categorical and 7 numeric, covering client, contact, and campaign attributes.
126/// Recorded from a Portuguese bank's phone campaigns. Uses the full
127/// `bank-full.csv` partition. Sourced from a ZIP archive (like `digits`).
128pub mod bank_marketing;
129
130/// Banknote Authentication dataset module.
131///
132/// Contains the Banknote Authentication dataset (UCI, Lohweg 2012) for binary
133/// classification. It tells genuine banknote specimens from forged ones, using 4
134/// continuous statistics (variance, skewness, curtosis, entropy) of
135/// Wavelet-transformed banknote images. This is the crate's most compact
136/// pure-numeric benchmark. Its target is the source's raw `0`/`1` code as an
137/// `Array1<u8>`, because UCI does not document which code means which.
138pub mod banknote_authentication;
139
140/// Boston Housing dataset module.
141///
142/// Contains the Boston Housing dataset for predicting median house values
143/// in Boston suburbs, based on features like crime rate, room count,
144/// and accessibility to highways.
145pub mod boston_housing;
146
147/// Breast Cancer Wisconsin (Diagnostic) dataset module.
148///
149/// Contains the Breast Cancer Wisconsin dataset for binary classification of
150/// tumors as malignant or benign. It uses 30 features computed from digitized
151/// images of cell nuclei.
152pub mod breast_cancer;
153
154/// California Housing dataset module.
155///
156/// Contains the California Housing dataset for predicting median house values
157/// in California districts. Reproduces the eight derived features of
158/// scikit-learn's `fetch_california_housing`. A modern replacement for Boston
159/// Housing.
160pub mod california_housing;
161
162/// Car Evaluation dataset module.
163///
164/// Contains the Car Evaluation dataset (UCI, Bohanec 1988) for multi-class
165/// classification. It predicts a car's overall acceptability (`unacc`, `acc`,
166/// `good`, `vgood`) from 6 categorical price and technical attributes. Like
167/// [`mushroom`], it is **all-categorical**: `features()` returns a single
168/// `Array2<String>`.
169pub mod car_evaluation;
170
171/// Forest Cover Type dataset module.
172///
173/// Contains the scikit-learn Forest CoverType dataset (`fetch_covtype`) for
174/// multi-class classification: predicting one of seven forest cover types from 54
175/// cartographic features of 30×30 metre cells. Sourced from a gzip-compressed file,
176/// it is the first loader to decompress its source with `gunzip`.
177pub mod covtype;
178
179/// Diabetes dataset module.
180///
181/// Contains the scikit-learn diabetes dataset (`load_diabetes`) for regression:
182/// predicting disease progression from 10 standardized physiological features.
183pub mod diabetes;
184
185/// Optical Recognition of Handwritten Digits dataset module.
186///
187/// Contains the scikit-learn digits dataset (`load_digits`) for multi-class
188/// classification: recognizing handwritten digits (`0`–`9`) from 8×8 grayscale
189/// images flattened into 64 integer pixel intensities.
190pub mod digits;
191
192/// Heart Disease (Cleveland) dataset module.
193///
194/// Contains the Cleveland Heart Disease dataset (UCI, Janosi et al. 1988) for
195/// classification: predicting the presence of heart disease (`num`, `0`–`4`) from
196/// 13 clinical features. The loader maps the `?` missing values in `ca`/`thal` to
197/// `NaN` (like [`titanic`]/[`palmer_penguins`]). The target is an `Array1<u8>`.
198pub mod heart_disease;
199
200/// Ionosphere dataset module.
201///
202/// Contains the Ionosphere dataset (UCI, Sigillito et al. 1989) for binary
203/// classification. It predicts whether a radar return shows structure in the
204/// ionosphere (`good`) or passes through it (`bad`), from 34 continuous
205/// autocorrelation features. A compact pure-numeric benchmark like
206/// [`breast_cancer`].
207pub mod ionosphere;
208
209/// Iris flower dataset module.
210///
211/// Contains the classic Iris dataset for classifying iris flowers into
212/// three species (setosa, versicolor, virginica) based on sepal and petal
213/// measurements.
214pub mod iris;
215
216/// KDD Cup 1999 network-intrusion dataset module.
217///
218/// Contains the scikit-learn KDD Cup 1999 dataset (`fetch_kddcup99`) for
219/// multi-class classification: detecting network intrusions from 41 mixed
220/// (3 categorical + 38 numeric) connection features. `Kddcup99::new` loads the
221/// default 10% subset (494,021 samples) and `Kddcup99::new_full` the full set
222/// (4,898,431 samples). Like `covtype`, it is sourced from a gzip-compressed file
223/// and decompressed with `gunzip`.
224pub mod kddcup99;
225
226/// Letter Recognition dataset module.
227///
228/// Contains the Letter Recognition dataset (UCI, Slate 1991) for multi-class
229/// classification. It identifies which of the 26 capital letters a distorted
230/// glyph shows, from 16 integer statistics of its pixel image. This is the
231/// crate's widest classification problem by class count, and the only loader
232/// whose label is an `Array1<char>`. A one-letter class is naturally a `char`,
233/// so it needs no lookup table.
234pub mod letter_recognition;
235
236/// Linnerud dataset module.
237///
238/// Contains the scikit-learn Linnerud dataset (`load_linnerud`) for multi-output
239/// regression. It predicts three physiological variables (`Weight`, `Waist`,
240/// `Pulse`) from three exercise variables (`Chins`, `Situps`, `Jumps`), measured
241/// on 20 middle-aged men.
242pub mod linnerud;
243
244/// Movie Review Polarity dataset module.
245///
246/// Contains the Cornell Movie Review Polarity dataset (Pang and Lee 2004,
247/// polarity dataset v2.0) for binary **text** classification. It labels 2,000
248/// full IMDb movie reviews as `positive` or `negative` (1,000 each). Like
249/// [`sms_spam`], it is a text-modality loader (document accessor `texts()`, not
250/// `features()`) and complements the sentence-level [`sentiment_sentences`] with
251/// full-document reviews. Sourced from a `.tar.gz` archive (decompressed with
252/// `untar_gz`).
253pub mod movie_review_polarity;
254
255/// Mushroom dataset module.
256///
257/// Contains the Mushroom dataset (UCI `agaricus-lepiota`) for binary
258/// classification: predicting whether a mushroom is edible or poisonous from 22
259/// categorical attributes. This is the first **all-categorical** loader: every
260/// feature is a single-letter string code, so `features()` returns a single
261/// `Array2<String>`.
262pub mod mushroom;
263
264/// 20 Newsgroups dataset module.
265///
266/// Contains the classic 20 Newsgroups dataset (Lang 1995, the `bydate` version)
267/// for multi-class **text** classification: labeling ~18,846 Usenet posts with
268/// one of 20 newsgroups. It is the framework-agnostic analogue of scikit-learn's
269/// `fetch_20newsgroups`, and the crate's first **multi-class** text loader. Like
270/// [`sms_spam`], it is a text-modality loader (document accessor `texts()`, not
271/// `features()`). `new`/`new_test`/`new_all` mirror scikit-learn's train/test/all
272/// subsets. Sourced from a `.tar.gz` archive (decompressed with `untar_gz`).
273pub mod newsgroups20;
274
275/// Preprocessing helpers.
276///
277/// Turns what the loaders return into what a model consumes. It covers seeded
278/// train/test and k-fold splits (plain or class-stratified), feature scaling,
279/// one-hot encoding of the categorical matrices, and label encoding. Everything
280/// is deterministic given a seed and depends on no extra crates.
281pub mod preprocessing;
282
283/// Palmer Penguins dataset module.
284///
285/// Contains the Palmer Penguins dataset for classifying penguins into three
286/// species (Adelie, Chinstrap, Gentoo). It uses bill and flipper measurements,
287/// body mass, and categorical island/sex features. A modern alternative to Iris.
288pub mod palmer_penguins;
289
290/// Sentiment Labelled Sentences dataset module.
291///
292/// Contains the Sentiment Labelled Sentences dataset (UCI, Kotzias et al. 2015)
293/// for binary **text** classification. It labels 3,000 review sentences from
294/// three sites (Amazon, IMDb, Yelp) as `positive` or `negative`. Like
295/// [`sms_spam`] and [`youtube_spam`], it is a text-modality loader (document
296/// accessor `texts()`, not `features()`). It also carries per-sample
297/// **metadata**, which site each sentence came from, via a `sources()` accessor.
298/// This makes `SentimentSentencesData` a `(texts, sources, labels)` triple.
299/// Sourced from a ZIP archive of three per-site files.
300pub mod sentiment_sentences;
301
302/// SMS Spam Collection dataset module.
303///
304/// Contains the SMS Spam Collection dataset (UCI, Almeida and Hidalgo 2011) for
305/// binary **text** classification: labeling 5,574 SMS messages as `ham` or
306/// `spam`. This is the crate's first text-modality loader. There is no feature
307/// matrix, so the document accessor is `texts()` (an `Array1<String>` of raw
308/// messages) rather than `features()`. Sourced from a ZIP archive.
309pub mod sms_spam;
310
311/// Spambase dataset module.
312///
313/// Contains the Spambase dataset (UCI, Hopkins et al. 1999) for binary
314/// classification. It labels 4,601 emails as `ham` or `spam` from 57 numeric
315/// features: word and character frequencies, plus capital-run-length statistics.
316/// This is the feature-engineered counterpart to the crate's raw-text spam
317/// corpora ([`sms_spam`], [`youtube_spam`]). Those loaders leave vectorization to
318/// you, but Spambase already does it, so it drops straight into a numeric model.
319pub mod spambase;
320
321/// Titanic dataset module.
322///
323/// Contains data about Titanic passengers for predicting survival based
324/// on features like passenger class, sex, age, and fare.
325pub mod titanic;
326
327/// The [`traits::MlDataset`] trait implemented by every loader in this crate.
328///
329/// Provides the container operations that stay the same whatever a loader parses
330/// into: lazy access, cache inspection, cache invalidation, and a uniform sample
331/// count. With it, you can write code generically over "some dataset" instead of
332/// one concrete struct.
333pub mod traits;
334
335/// Wine Quality dataset module.
336///
337/// Contains wine quality assessment data for predicting quality scores
338/// based on physicochemical properties like acidity, sugar content, and
339/// alcohol percentage.
340pub mod wine_quality;
341
342/// Wine Recognition dataset module.
343///
344/// Contains the scikit-learn Wine recognition dataset for classifying wines
345/// into three cultivars based on 13 chemical constituents. Distinct from
346/// [`wine_quality`], which is a regression task on quality scores.
347pub mod wine_recognition;
348
349/// YouTube Spam Collection dataset module.
350///
351/// Contains the YouTube Spam Collection dataset (UCI, Alberto, Lochter, and
352/// Almeida 2017) for binary **text** classification. It labels 1,956 comments
353/// from five popular music videos as `ham` or `spam`. Like [`sms_spam`] (a
354/// sibling by the same authors), it is a text-modality loader. There is no
355/// feature matrix, so the document accessor is `texts()` (an `Array1<String>` of
356/// raw comments) rather than `features()`. Sourced from a ZIP archive of five
357/// per-video CSVs.
358pub mod youtube_spam;
359
360pub use abalone::Abalone;
361pub use adult::Adult;
362pub use bank_marketing::BankMarketing;
363pub use banknote_authentication::BanknoteAuthentication;
364pub use boston_housing::BostonHousing;
365pub use breast_cancer::BreastCancer;
366pub use california_housing::CaliforniaHousing;
367pub use car_evaluation::CarEvaluation;
368pub use covtype::Covtype;
369pub use diabetes::Diabetes;
370pub use digits::Digits;
371pub use heart_disease::HeartDisease;
372pub use ionosphere::Ionosphere;
373pub use iris::Iris;
374pub use kddcup99::Kddcup99;
375pub use letter_recognition::LetterRecognition;
376pub use linnerud::Linnerud;
377pub use movie_review_polarity::MovieReviewPolarity;
378pub use mushroom::Mushroom;
379pub use newsgroups20::Newsgroups20;
380pub use palmer_penguins::PalmerPenguins;
381pub use sentiment_sentences::SentimentSentences;
382pub use sms_spam::SmsSpam;
383pub use spambase::Spambase;
384pub use titanic::Titanic;
385pub use traits::{MlDataset, NumSamples};
386pub use wine_quality::{red_wine_quality::RedWineQuality, white_wine_quality::WhiteWineQuality};
387pub use wine_recognition::WineRecognition;
388pub use youtube_spam::YoutubeSpam;