Moral88 0.3.0__py3-none-any.whl → 0.5.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Moral88/__init__.py CHANGED
@@ -0,0 +1 @@
1
+ from .regression import mean_absolute_error, mean_squared_error, r_squared
Moral88/regression.py CHANGED
@@ -1,145 +1,4 @@
1
1
  import numpy as np
2
-
3
- def validate_inputs(y_true, y_pred):
4
- """
5
- Validate the inputs for type and length.
6
- """
7
- if not isinstance(y_true, (list, tuple, np.ndarray)) or not isinstance(y_pred, (list, tuple, np.ndarray)):
8
- raise TypeError("Both y_true and y_pred must be lists, tuples, or numpy arrays.")
9
-
10
- y_true = np.array(y_true)
11
- y_pred = np.array(y_pred)
12
-
13
- if y_true.shape != y_pred.shape:
14
- raise ValueError("Shapes of y_true and y_pred must be the same.")
15
-
16
- if not np.issubdtype(y_true.dtype, np.number) or not np.issubdtype(y_pred.dtype, np.number):
17
- raise TypeError("All elements in y_true and y_pred must be numeric.")
18
-
19
- def mean_absolute_error(y_true, y_pred, normalize=True, threshold=None, method='mean', library='Moral88', flatten=True):
20
- """
21
- Calculate Mean Absolute Error (MAE) for single or multi-dimensional data.
22
- """
23
- validate_inputs(y_true, y_pred)
24
-
25
- # y_true = np.array(y_true)
26
- # y_pred = np.array(y_pred)
27
-
28
- if flatten:
29
- y_true = y_true.ravel()
30
- y_pred = y_pred.ravel()
31
-
32
- if library == 'Moral88':
33
- if threshold is not None:
34
- y_pred = np.clip(y_pred, threshold[0], threshold[1])
35
-
36
- absolute_errors = np.abs(y_true - y_pred)
37
-
38
- if method == 'mean':
39
- result = np.mean(absolute_errors)
40
- elif method == 'sum':
41
- result = np.sum(absolute_errors)
42
- elif method == 'none':
43
- result = absolute_errors
44
- else:
45
- raise ValueError("Invalid method. Choose from {'mean', 'sum', 'none'}.")
46
-
47
- if normalize and method != 'none':
48
- range_y = np.ptp(y_true)
49
- result = result / max(abs(range_y), 1)
50
-
51
- return result
52
-
53
- elif library == 'sklearn':
54
- from sklearn.metrics import mean_absolute_error as sklearn_mae
55
- return sklearn_mae(y_true, y_pred)
56
-
57
- elif library == 'torch':
58
- import torch
59
- y_true_tensor = torch.tensor(y_true, dtype=torch.float32)
60
- y_pred_tensor = torch.tensor(y_pred, dtype=torch.float32)
61
- return torch.mean(torch.abs(y_true_tensor - y_pred_tensor)).item()
62
-
63
- elif library == 'tensorflow':
64
- import tensorflow as tf
65
- y_true_tensor = tf.convert_to_tensor(y_true, dtype=tf.float32)
66
- y_pred_tensor = tf.convert_to_tensor(y_pred, dtype=tf.float32)
67
- return tf.reduce_mean(tf.abs(y_true_tensor - y_pred_tensor)).numpy()
68
-
69
- else:
70
- raise ValueError(f"Invalid library: {library}. Choose from {'Moral88', 'sklearn', 'torch', 'tensorflow'}.")
71
-
72
- def mean_squared_error(y_true, y_pred, normalize=True, threshold=None, method='mean', library='Moral88', flatten=True):
73
- """
74
- Calculate Mean Squared Error (MSE) for single or multi-dimensional data.
75
- """
76
- validate_inputs(y_true, y_pred)
77
-
78
- # y_true = np.array(y_true)
79
- # y_pred = np.array(y_pred)
80
-
81
- if flatten:
82
- y_true = y_true.ravel()
83
- y_pred = y_pred.ravel()
84
-
85
- if library == 'Moral88':
86
- if threshold is not None:
87
- y_pred = np.clip(y_pred, threshold[0], threshold[1])
88
-
89
- squared_errors = (y_true - y_pred) ** 2
90
-
91
- if method == 'mean':
92
- result = np.mean(squared_errors)
93
- elif method == 'sum':
94
- result = np.sum(squared_errors)
95
- elif method == 'none':
96
- result = squared_errors
97
- else:
98
- raise ValueError("Invalid method. Choose from {'mean', 'sum', 'none'}.")
99
-
100
- if normalize and method != 'none':
101
- range_y = np.ptp(y_true)
102
- result = result / max(abs(range_y), 1)
103
-
104
- return result
105
-
106
- elif library == 'sklearn':
107
- from sklearn.metrics import mean_squared_error as sklearn_mse
108
- return sklearn_mse(y_true, y_pred)
109
-
110
- elif library == 'torch':
111
- import torch
112
- y_true_tensor = torch.tensor(y_true, dtype=torch.float32)
113
- y_pred_tensor = torch.tensor(y_pred, dtype=torch.float32)
114
- return torch.mean((y_true_tensor - y_pred_tensor) ** 2).item()
115
-
116
- elif library == 'tensorflow':
117
- import tensorflow as tf
118
- y_true_tensor = tf.convert_to_tensor(y_true, dtype=tf.float32)
119
- y_pred_tensor = tf.convert_to_tensor(y_pred, dtype=tf.float32)
120
- return tf.reduce_mean(tf.square(y_true_tensor - y_pred_tensor)).numpy()
121
-
122
- else:
123
- raise ValueError(f"Invalid library: {library}. Choose from {'Moral88', 'sklearn', 'torch', 'tensorflow'}.")
124
-
125
- def r_squared(y_true, y_pred, flatten=True):
126
- """
127
- Compute R-Squared for single or multi-dimensional data.
128
- """
129
- validate_inputs(y_true, y_pred)
130
-
131
- y_true = np.array(y_true)
132
- y_pred = np.array(y_pred)
133
-
134
- if flatten:
135
- y_true = y_true.ravel()
136
- y_pred = y_pred.ravel()
137
-
138
- ss_total = np.sum((y_true - np.mean(y_true)) ** 2)
139
- ss_residual = np.sum((y_true - y_pred) ** 2)
140
- return 1 - (ss_residual / ss_total)
141
-
142
- import numpy as np
143
2
  import warnings
144
3
  from typing import Union, List, Tuple
145
4
  from scipy import sparse
@@ -231,17 +90,61 @@ class DataValidator:
231
90
  sample_weight = self.is_1d_array(sample_weight)
232
91
  return y_true, y_pred, sample_weight
233
92
 
93
+ def validate_mae_mse_inputs(self, y_true, y_pred, library=None):
94
+ """
95
+ Ensures inputs for MAE and MSE computation are valid.
96
+ """
97
+ y_true, y_pred = self.validate_regression_targets(y_true, y_pred)
98
+ if library not in {None, 'sklearn', 'torch', 'tensorflow', 'Moral88'}:
99
+ raise ValueError(f"Invalid library: {library}. Choose from {{'Moral88', 'sklearn', 'torch', 'tensorflow'}}.")
100
+ return y_true, y_pred
101
+
234
102
 
235
103
  class Metrics:
104
+ def mean_bias_deviation(self, y_true, y_pred, library=None):
105
+ """
106
+ Computes Mean Bias Deviation (MBD).
107
+ """
108
+ y_true, y_pred = self.validator.validate_mae_mse_inputs(y_true, y_pred, library)
109
+
110
+ if library == 'sklearn':
111
+ # Sklearn does not have a direct implementation for MBD
112
+ raise NotImplementedError("Mean Bias Deviation is not implemented in sklearn.")
113
+
114
+ if library == 'torch':
115
+ import torch
116
+ y_true_tensor = torch.tensor(y_true, dtype=torch.float32)
117
+ y_pred_tensor = torch.tensor(y_pred, dtype=torch.float32)
118
+ bias = torch.mean(y_pred_tensor - y_true_tensor).item()
119
+ return bias
120
+
121
+ if library == 'tensorflow':
122
+ import tensorflow as tf
123
+ y_true_tensor = tf.convert_to_tensor(y_true, dtype=tf.float32)
124
+ y_pred_tensor = tf.convert_to_tensor(y_pred, dtype=tf.float32)
125
+ bias = tf.reduce_mean(y_pred_tensor - y_true_tensor).numpy()
126
+ return bias
127
+
128
+ # Default implementation
129
+ return np.mean(y_pred - y_true)
236
130
  def __init__(self):
237
131
  self.validator = DataValidator()
238
132
 
239
- def r2_score(self, y_true, y_pred, sample_weight=None):
133
+ def r2_score(self, y_true, y_pred, sample_weight=None, library=None):
240
134
  """
241
135
  Computes R2 score.
242
136
  """
243
137
  y_true, y_pred, sample_weight = self.validator.validate_r2_score_inputs(y_true, y_pred, sample_weight)
244
138
 
139
+ if library == 'sklearn':
140
+ from sklearn.metrics import r2_score as sklearn_r2
141
+ return sklearn_r2(y_true, y_pred, sample_weight=sample_weight)
142
+
143
+ if library == 'statsmodels':
144
+ import statsmodels.api as sm
145
+ model = sm.OLS(y_true, sm.add_constant(y_pred)).fit()
146
+ return model.rsquared
147
+
245
148
  numerator = np.sum((y_true - y_pred) ** 2)
246
149
  denominator = np.sum((y_true - np.mean(y_true)) ** 2)
247
150
 
@@ -249,6 +152,179 @@ class Metrics:
249
152
  return 0.0
250
153
  return 1 - (numerator / denominator)
251
154
 
155
+ def mean_absolute_error(self, y_true, y_pred, normalize=True, threshold=None, method='mean', library='Moral88', flatten=True):
156
+ """
157
+ Computes Mean Absolute Error (MAE).
158
+ """
159
+ y_true, y_pred = self.validator.validate_mae_mse_inputs(y_true, y_pred, library)
160
+
161
+ if flatten:
162
+ y_true = y_true.ravel()
163
+ y_pred = y_pred.ravel()
164
+
165
+ if library == 'Moral88':
166
+ if threshold is not None:
167
+ y_pred = np.clip(y_pred, threshold[0], threshold[1])
168
+
169
+ absolute_errors = np.abs(y_true - y_pred)
170
+
171
+ if method == 'mean':
172
+ result = np.mean(absolute_errors)
173
+ elif method == 'sum':
174
+ result = np.sum(absolute_errors)
175
+ elif method == 'none':
176
+ result = absolute_errors
177
+ else:
178
+ raise ValueError("Invalid method. Choose from {'mean', 'sum', 'none'}.")
179
+
180
+ if normalize and method != 'none':
181
+ range_y = np.ptp(y_true)
182
+ result = result / max(abs(range_y), 1)
183
+
184
+ return result
185
+
186
+ elif library == 'sklearn':
187
+ from sklearn.metrics import mean_absolute_error as sklearn_mae
188
+ return sklearn_mae(y_true, y_pred)
189
+
190
+ elif library == 'torch':
191
+ import torch
192
+ y_true_tensor = torch.tensor(y_true, dtype=torch.float32)
193
+ y_pred_tensor = torch.tensor(y_pred, dtype=torch.float32)
194
+ return torch.mean(torch.abs(y_true_tensor - y_pred_tensor)).item()
195
+
196
+ elif library == 'tensorflow':
197
+ import tensorflow as tf
198
+ y_true_tensor = tf.convert_to_tensor(y_true, dtype=tf.float32)
199
+ y_pred_tensor = tf.convert_to_tensor(y_pred, dtype=tf.float32)
200
+ return tf.reduce_mean(tf.abs(y_true_tensor - y_pred_tensor)).numpy()
201
+
202
+ def mean_squared_error(self, y_true, y_pred, normalize=True, threshold=None, method='mean', library='Moral88', flatten=True):
203
+ """
204
+ Computes Mean Squared Error (MSE).
205
+ """
206
+ y_true, y_pred = self.validator.validate_mae_mse_inputs(y_true, y_pred, library)
207
+
208
+ if flatten:
209
+ y_true = y_true.ravel()
210
+ y_pred = y_pred.ravel()
211
+
212
+ if library == 'Moral88':
213
+ if threshold is not None:
214
+ y_pred = np.clip(y_pred, threshold[0], threshold[1])
215
+
216
+ squared_errors = (y_true - y_pred) ** 2
217
+
218
+ if method == 'mean':
219
+ result = np.mean(squared_errors)
220
+ elif method == 'sum':
221
+ result = np.sum(squared_errors)
222
+ elif method == 'none':
223
+ result = squared_errors
224
+ else:
225
+ raise ValueError("Invalid method. Choose from {'mean', 'sum', 'none'}.")
226
+
227
+ if normalize and method != 'none':
228
+ range_y = np.ptp(y_true)
229
+ result = result / max(abs(range_y), 1)
230
+
231
+ return result
232
+
233
+ elif library == 'sklearn':
234
+ from sklearn.metrics import mean_squared_error as sklearn_mse
235
+ return sklearn_mse(y_true, y_pred)
236
+
237
+ elif library == 'torch':
238
+ import torch
239
+ y_true_tensor = torch.tensor(y_true, dtype=torch.float32)
240
+ y_pred_tensor = torch.tensor(y_pred, dtype=torch.float32)
241
+ return torch.mean((y_true_tensor - y_pred_tensor) ** 2).item()
242
+
243
+ elif library == 'tensorflow':
244
+ import tensorflow as tf
245
+ y_true_tensor = tf.convert_to_tensor(y_true, dtype=tf.float32)
246
+ y_pred_tensor = tf.convert_to_tensor(y_pred, dtype=tf.float32)
247
+ return tf.reduce_mean(tf.square(y_true_tensor - y_pred_tensor)).numpy()
248
+
249
+ def root_mean_squared_error(self, y_true, y_pred, library=None):
250
+ """
251
+ Computes Root Mean Squared Error (RMSE).
252
+ """
253
+ y_true, y_pred = self.validator.validate_mae_mse_inputs(y_true, y_pred, library)
254
+
255
+ if library == 'sklearn':
256
+ from sklearn.metrics import mean_squared_error as sklearn_mse
257
+ return np.sqrt(sklearn_mse(y_true, y_pred))
258
+
259
+ if library == 'torch':
260
+ import torch
261
+ y_true_tensor = torch.tensor(y_true, dtype=torch.float32)
262
+ y_pred_tensor = torch.tensor(y_pred, dtype=torch.float32)
263
+ return torch.sqrt(torch.mean((y_true_tensor - y_pred_tensor) ** 2)).item()
264
+
265
+ if library == 'tensorflow':
266
+ import tensorflow as tf
267
+ y_true_tensor = tf.convert_to_tensor(y_true, dtype=tf.float32)
268
+ y_pred_tensor = tf.convert_to_tensor(y_pred, dtype=tf.float32)
269
+ return tf.sqrt(tf.reduce_mean(tf.square(y_true_tensor - y_pred_tensor))).numpy()
270
+
271
+ mse = self.mean_squared_error(y_true, y_pred)
272
+ return np.sqrt(mse)
273
+
274
+ def mean_absolute_percentage_error(self, y_true, y_pred, library=None):
275
+ """
276
+ Computes Mean Absolute Percentage Error (MAPE).
277
+ """
278
+ y_true, y_pred = self.validator.validate_regression_targets(y_true, y_pred)
279
+ y_true, y_pred = self.validator.validate_mae_mse_inputs(y_true, y_pred, library)
280
+
281
+ if library == 'sklearn':
282
+ from sklearn.metrics import mean_absolute_percentage_error as sklearn_mape
283
+ return sklearn_mape(y_true, y_pred) * 100
284
+
285
+ if library == 'torch':
286
+ import torch
287
+ y_true_tensor = torch.tensor(y_true, dtype=torch.float32)
288
+ y_pred_tensor = torch.tensor(y_pred, dtype=torch.float32)
289
+ return torch.mean(torch.abs((y_true_tensor - y_pred_tensor) / torch.clamp(y_true_tensor, min=1e-8))).item() * 100
290
+
291
+ if library == 'tensorflow':
292
+ import tensorflow as tf
293
+ y_true_tensor = tf.convert_to_tensor(y_true, dtype=tf.float32)
294
+ y_pred_tensor = tf.convert_to_tensor(y_pred, dtype=tf.float32)
295
+ return tf.reduce_mean(tf.abs((y_true_tensor - y_pred_tensor) / tf.clip_by_value(y_true_tensor, 1e-8, tf.float32.max))).numpy() * 100
296
+
297
+ return np.mean(np.abs((y_true - y_pred) / np.clip(y_true, 1e-8, None))) * 100
298
+
299
+ def explained_variance_score(self, y_true, y_pred, library=None):
300
+ """
301
+ Computes Explained Variance Score.
302
+ """
303
+ y_true, y_pred = self.validator.validate_mae_mse_inputs(y_true, y_pred, library)
304
+
305
+ if library == 'sklearn':
306
+ from sklearn.metrics import explained_variance_score as sklearn_evs
307
+ return sklearn_evs(y_true, y_pred)
308
+
309
+ if library == 'torch':
310
+ import torch
311
+ y_true_tensor = torch.tensor(y_true, dtype=torch.float32)
312
+ y_pred_tensor = torch.tensor(y_pred, dtype=torch.float32)
313
+ variance_residual = torch.var(y_true_tensor - y_pred_tensor)
314
+ variance_y = torch.var(y_true_tensor)
315
+ return 1 - variance_residual / variance_y if variance_y != 0 else 0
316
+
317
+ if library == 'tensorflow':
318
+ import tensorflow as tf
319
+ y_true_tensor = tf.convert_to_tensor(y_true, dtype=tf.float32)
320
+ y_pred_tensor = tf.convert_to_tensor(y_pred, dtype=tf.float32)
321
+ variance_residual = tf.math.reduce_variance(y_true_tensor - y_pred_tensor)
322
+ variance_y = tf.math.reduce_variance(y_true_tensor)
323
+ return 1 - variance_residual / variance_y if variance_y != 0 else 0
324
+
325
+ numerator = np.var(y_true - y_pred)
326
+ denominator = np.var(y_true)
327
+ return 1 - numerator / denominator if denominator != 0 else 0
252
328
 
253
329
  if __name__ == '__main__':
254
330
  # Example usage
@@ -264,3 +340,7 @@ if __name__ == '__main__':
264
340
  y_true = [3, -0.5, 2, 7]
265
341
  y_pred = [2.5, 0.0, 2, 8]
266
342
  print("R2 Score:", metrics.r2_score(y_true, y_pred))
343
+
344
+ # Test MAE and MSE
345
+ print("Mean Absolute Error:", metrics.mean_absolute_error(y_true, y_pred))
346
+ print("Mean Squared Error:", metrics.mean_squared_error(y_true, y_pred))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Moral88
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: A library for regression evaluation metrics.
5
5
  Author: Morteza Alizadeh
6
6
  Author-email: alizadeh.c2m@gmail.com
@@ -0,0 +1,8 @@
1
+ Moral88/__init__.py,sha256=vb-aPc9ZbnYNSy9qq2fVESI63E10pYsCrDpnV8OHWkg,74
2
+ Moral88/regression.py,sha256=MjM3R1oqRWdlfo6Goc2NOT0UHeKGcQfdMyriqSvS5q4,14127
3
+ Moral88/segmentation.py,sha256=v0yqxdrKbM9LM7wVKLjJ4HrhrSrilNNeWS6-oK_27Ag,1363
4
+ Moral88-0.5.0.dist-info/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ Moral88-0.5.0.dist-info/METADATA,sha256=7_93ZrGO0rFBargNBBe7qvQzQnFi2BFN7RGss26ux3I,407
6
+ Moral88-0.5.0.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
7
+ Moral88-0.5.0.dist-info/top_level.txt,sha256=-dyn5iTprnSUHbtMpvRO-prJsIoaRxao7wlfCHLSsv4,8
8
+ Moral88-0.5.0.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- Moral88/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- Moral88/regression.py,sha256=kfWQcdtdZVlHW_iIRbS9_rNrKJOYNiT9RaeYpVIvl7I,9355
3
- Moral88/segmentation.py,sha256=v0yqxdrKbM9LM7wVKLjJ4HrhrSrilNNeWS6-oK_27Ag,1363
4
- Moral88-0.3.0.dist-info/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- Moral88-0.3.0.dist-info/METADATA,sha256=rKJtI5aX0pT3DSORLtFmsMPYB8fiAbGNQKmEndRNPtI,407
6
- Moral88-0.3.0.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
7
- Moral88-0.3.0.dist-info/top_level.txt,sha256=-dyn5iTprnSUHbtMpvRO-prJsIoaRxao7wlfCHLSsv4,8
8
- Moral88-0.3.0.dist-info/RECORD,,