radiate_gp/regression/
data.rs1use 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}