Skip to main content

radiate_gp/regression/
data.rs

1use radiate_core::random_provider;
2
3#[derive(Debug, Clone, Default)]
4pub struct Row<T> {
5    input: Vec<T>,
6    output: Vec<T>,
7}
8
9impl<T> Row<T> {
10    pub fn new(input: Vec<T>, output: Vec<T>) -> Self {
11        Row { input, output }
12    }
13
14    pub fn input(&self) -> &[T] {
15        &self.input
16    }
17
18    pub fn output(&self) -> &[T] {
19        &self.output
20    }
21}
22
23impl<T> From<(Vec<T>, Vec<T>)> for Row<T> {
24    fn from(data: (Vec<T>, Vec<T>)) -> Self {
25        Row::new(data.0, data.1)
26    }
27}
28
29#[derive(Default, Clone)]
30pub struct DataSet<T> {
31    rows: Vec<Row<T>>,
32}
33
34impl<T> DataSet<T> {
35    pub fn new(inputs: Vec<Vec<T>>, outputs: Vec<Vec<T>>) -> Self {
36        let mut samples = Vec::new();
37        for (input, output) in inputs.into_iter().zip(outputs) {
38            samples.push(Row { input, output });
39        }
40
41        DataSet { rows: samples }
42    }
43
44    pub fn row(mut self, row: impl Into<Row<T>>) -> Self {
45        self.rows.push(row.into());
46        self
47    }
48
49    pub fn iter(&self) -> std::slice::Iter<'_, Row<T>> {
50        self.rows.iter()
51    }
52
53    pub fn len(&self) -> usize {
54        self.rows.len()
55    }
56
57    pub fn is_empty(&self) -> bool {
58        self.rows.is_empty()
59    }
60
61    pub fn shuffle(mut self) -> Self {
62        random_provider::shuffle(&mut self.rows);
63        self
64    }
65
66    pub fn shape(&self) -> (usize, usize, usize) {
67        let num_samples = self.rows.len();
68        let input_dim = if num_samples > 0 {
69            self.rows[0].input.len()
70        } else {
71            0
72        };
73        let output_dim = if num_samples > 0 {
74            self.rows[0].output.len()
75        } else {
76            0
77        };
78
79        (num_samples, input_dim, output_dim)
80    }
81
82    #[inline]
83    pub fn features(&self) -> Vec<Vec<T>>
84    where
85        T: Clone,
86    {
87        self.rows.iter().map(|row| row.input.clone()).collect()
88    }
89
90    #[inline]
91    pub fn labels(&self) -> Vec<Vec<T>>
92    where
93        T: Clone,
94    {
95        self.rows.iter().map(|row| row.output.clone()).collect()
96    }
97
98    #[inline]
99    pub fn split(self, ratio: f32) -> (Self, Self)
100    where
101        T: Clone,
102    {
103        let ratio = ratio.clamp(0.0, 1.0);
104        let split = (self.len() as f32 * ratio).round() as usize;
105        let (left, right) = self.rows.split_at(split);
106
107        (
108            DataSet {
109                rows: left.to_vec(),
110            },
111            DataSet {
112                rows: right.to_vec(),
113            },
114        )
115    }
116}
117
118impl DataSet<f32> {
119    pub fn standardize(mut self) -> Self {
120        let mut means = vec![0.0; self.rows[0].input.len()];
121        let mut stds = vec![0.0; self.rows[0].input.len()];
122
123        for sample in self.rows.iter() {
124            for (i, &val) in sample.input.iter().enumerate() {
125                means[i] += val;
126            }
127        }
128
129        let n = self.len() as f32;
130        for mean in means.iter_mut() {
131            *mean /= n;
132        }
133
134        for sample in self.rows.iter() {
135            for (i, &val) in sample.input.iter().enumerate() {
136                stds[i] += (val - means[i]).powi(2);
137            }
138        }
139
140        for std in stds.iter_mut() {
141            *std = (*std / n).sqrt();
142        }
143
144        for sample in self.rows.iter_mut() {
145            for (i, val) in sample.input.iter_mut().enumerate() {
146                *val = (*val - means[i]) / stds[i];
147            }
148        }
149
150        self
151    }
152
153    pub fn normalize(mut self) -> Self {
154        let mut mins = vec![f32::MAX; self.rows[0].input.len()];
155        let mut maxs = vec![f32::MIN; self.rows[0].input.len()];
156
157        for sample in self.rows.iter() {
158            for (i, &val) in sample.input.iter().enumerate() {
159                if val < mins[i] {
160                    mins[i] = val;
161                }
162
163                if val > maxs[i] {
164                    maxs[i] = val;
165                }
166            }
167        }
168
169        for sample in self.rows.iter_mut() {
170            for (i, val) in sample.input.iter_mut().enumerate() {
171                *val = (*val - mins[i]) / (maxs[i] - mins[i]);
172            }
173        }
174
175        self
176    }
177}
178
179impl<T> From<Vec<Vec<Option<T>>>> for DataSet<T>
180where
181    T: Clone,
182{
183    fn from(data: Vec<Vec<Option<T>>>) -> Self {
184        let mut rows = Vec::new();
185        for row in data.into_iter() {
186            let input = row
187                .iter()
188                .filter_map(|v| v.as_ref())
189                .cloned()
190                .collect::<Vec<T>>();
191
192            rows.push(Row {
193                input,
194                output: Vec::new(),
195            });
196        }
197
198        DataSet { rows }
199    }
200}
201
202impl<T> From<(Vec<Vec<T>>, Vec<Vec<T>>)> for DataSet<T> {
203    fn from(data: (Vec<Vec<T>>, Vec<Vec<T>>)) -> Self {
204        DataSet::new(data.0, data.1)
205    }
206}