machinegnostics 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. __init__.py +0 -0
  2. machinegnostics/__init__.py +24 -0
  3. machinegnostics/magcal/__init__.py +37 -0
  4. machinegnostics/magcal/characteristics.py +460 -0
  5. machinegnostics/magcal/criteria_eval.py +268 -0
  6. machinegnostics/magcal/criterion.py +140 -0
  7. machinegnostics/magcal/data_conversion.py +381 -0
  8. machinegnostics/magcal/gcor.py +64 -0
  9. machinegnostics/magcal/gdf/__init__.py +2 -0
  10. machinegnostics/magcal/gdf/base_df.py +39 -0
  11. machinegnostics/magcal/gdf/base_distfunc.py +1202 -0
  12. machinegnostics/magcal/gdf/base_egdf.py +823 -0
  13. machinegnostics/magcal/gdf/base_eldf.py +830 -0
  14. machinegnostics/magcal/gdf/base_qgdf.py +1234 -0
  15. machinegnostics/magcal/gdf/base_qldf.py +1019 -0
  16. machinegnostics/magcal/gdf/cluster_analysis.py +456 -0
  17. machinegnostics/magcal/gdf/data_cluster.py +975 -0
  18. machinegnostics/magcal/gdf/data_intervals.py +853 -0
  19. machinegnostics/magcal/gdf/data_membership.py +536 -0
  20. machinegnostics/magcal/gdf/der_egdf.py +243 -0
  21. machinegnostics/magcal/gdf/distfunc_engine.py +841 -0
  22. machinegnostics/magcal/gdf/egdf.py +324 -0
  23. machinegnostics/magcal/gdf/eldf.py +297 -0
  24. machinegnostics/magcal/gdf/eldf_intv.py +609 -0
  25. machinegnostics/magcal/gdf/eldf_ma.py +627 -0
  26. machinegnostics/magcal/gdf/homogeneity.py +1218 -0
  27. machinegnostics/magcal/gdf/intv_engine.py +1523 -0
  28. machinegnostics/magcal/gdf/marginal_intv_analysis.py +558 -0
  29. machinegnostics/magcal/gdf/qgdf.py +289 -0
  30. machinegnostics/magcal/gdf/qldf.py +296 -0
  31. machinegnostics/magcal/gdf/scedasticity.py +197 -0
  32. machinegnostics/magcal/gdf/wedf.py +181 -0
  33. machinegnostics/magcal/gdf/z0_estimator.py +1047 -0
  34. machinegnostics/magcal/layer_base.py +42 -0
  35. machinegnostics/magcal/layer_history_base.py +74 -0
  36. machinegnostics/magcal/layer_io_process_base.py +238 -0
  37. machinegnostics/magcal/layer_param_base.py +448 -0
  38. machinegnostics/magcal/mg_weights.py +36 -0
  39. machinegnostics/magcal/sample_characteristics.py +532 -0
  40. machinegnostics/magcal/scale_optimization.py +185 -0
  41. machinegnostics/magcal/scale_param.py +313 -0
  42. machinegnostics/magcal/util/__init__.py +0 -0
  43. machinegnostics/magcal/util/dis_docstring.py +18 -0
  44. machinegnostics/magcal/util/logging.py +24 -0
  45. machinegnostics/magcal/util/min_max_float.py +34 -0
  46. machinegnostics/magnet/__init__.py +0 -0
  47. machinegnostics/metrics/__init__.py +28 -0
  48. machinegnostics/metrics/accu.py +61 -0
  49. machinegnostics/metrics/accuracy.py +67 -0
  50. machinegnostics/metrics/auto_correlation.py +183 -0
  51. machinegnostics/metrics/auto_covariance.py +204 -0
  52. machinegnostics/metrics/cls_report.py +130 -0
  53. machinegnostics/metrics/conf_matrix.py +93 -0
  54. machinegnostics/metrics/correlation.py +178 -0
  55. machinegnostics/metrics/cross_variance.py +167 -0
  56. machinegnostics/metrics/divi.py +82 -0
  57. machinegnostics/metrics/evalmet.py +109 -0
  58. machinegnostics/metrics/f1_score.py +128 -0
  59. machinegnostics/metrics/gmmfe.py +108 -0
  60. machinegnostics/metrics/hc.py +141 -0
  61. machinegnostics/metrics/mae.py +72 -0
  62. machinegnostics/metrics/mean.py +117 -0
  63. machinegnostics/metrics/median.py +122 -0
  64. machinegnostics/metrics/mg_r2.py +167 -0
  65. machinegnostics/metrics/mse.py +78 -0
  66. machinegnostics/metrics/precision.py +119 -0
  67. machinegnostics/metrics/r2.py +122 -0
  68. machinegnostics/metrics/recall.py +108 -0
  69. machinegnostics/metrics/rmse.py +77 -0
  70. machinegnostics/metrics/robr2.py +119 -0
  71. machinegnostics/metrics/std.py +144 -0
  72. machinegnostics/metrics/variance.py +101 -0
  73. machinegnostics/models/__init__.py +2 -0
  74. machinegnostics/models/classification/__init__.py +1 -0
  75. machinegnostics/models/classification/layer_history_log_reg.py +121 -0
  76. machinegnostics/models/classification/layer_io_process_log_reg.py +98 -0
  77. machinegnostics/models/classification/layer_mlflow_log_reg.py +107 -0
  78. machinegnostics/models/classification/layer_param_log_reg.py +275 -0
  79. machinegnostics/models/classification/mg_log_reg.py +273 -0
  80. machinegnostics/models/cross_validation.py +118 -0
  81. machinegnostics/models/data_split.py +106 -0
  82. machinegnostics/models/regression/__init__.py +2 -0
  83. machinegnostics/models/regression/layer_histroy_rob_reg.py +139 -0
  84. machinegnostics/models/regression/layer_io_process_rob_rig.py +88 -0
  85. machinegnostics/models/regression/layer_mlflow_rob_reg.py +134 -0
  86. machinegnostics/models/regression/layer_param_rob_reg.py +212 -0
  87. machinegnostics/models/regression/mg_lin_reg.py +253 -0
  88. machinegnostics/models/regression/mg_poly_reg.py +258 -0
  89. machinegnostics-0.0.1.dist-info/METADATA +246 -0
  90. machinegnostics-0.0.1.dist-info/RECORD +93 -0
  91. machinegnostics-0.0.1.dist-info/WHEEL +5 -0
  92. machinegnostics-0.0.1.dist-info/licenses/LICENSE +674 -0
  93. machinegnostics-0.0.1.dist-info/top_level.txt +2 -0
@@ -0,0 +1,381 @@
1
+ '''
2
+ ManGo - Machine Gnostics Library
3
+ Copyright (C) 2025 ManGo Team
4
+
5
+ Author: Nirmal Parmar
6
+ '''
7
+
8
+ import numpy as np
9
+
10
+ class DataConversion:
11
+ """
12
+ A class to convert data between different data domains.
13
+ converts data domains,
14
+ - from additive to multiplicative,
15
+ - from multiplicative to additive,
16
+ - from finite normalized multiplicative to infinite interval,
17
+ - from infinite interval to finite normalized multiplicative.
18
+
19
+ Methods
20
+ -------
21
+ add_to_mult(data)
22
+ Converts additive data to multiplicative domain.
23
+ mult_to_add(data)
24
+ Converts multiplicative data to additive domain.
25
+ convert_data(data, to_multiplicative=True)
26
+ Converts data between additive and multiplicative domains.
27
+ get_bounds(data)
28
+ Gets the lower and upper bounds of the data.
29
+
30
+ """
31
+
32
+ @staticmethod
33
+ def _convert_az(a, lb=None, ub=None):
34
+ """
35
+ Converts additive data into the finite normalized multiplicative form.
36
+
37
+ Parameters:
38
+ ----------
39
+ a : scalar or numpy.ndarray
40
+ Input additive data.
41
+ lb : float
42
+ Lower bound (must be a scalar).
43
+ ub : float
44
+ Upper bound (must be a scalar).
45
+
46
+ Returns:
47
+ -------
48
+ z : scalar or numpy.ndarray
49
+ Data converted into finite normalized multiplicative form,
50
+ same type as 'a'.
51
+
52
+ Raises:
53
+ ------
54
+ ValueError:
55
+ If lb or ub is not a scalar.
56
+ """
57
+ if lb is None:
58
+ lb = np.min(a)
59
+ if ub is None:
60
+ ub = np.max(a)
61
+
62
+ if not np.isscalar(lb) or not np.isscalar(ub):
63
+ raise ValueError("lb and ub must be scalars")
64
+ eps = 1e-6 # Small value to ensure strict inequality
65
+ # if lb >= ub:
66
+ # raise ZeroDivisionError("lb must be less than ub")
67
+
68
+ a = np.asarray(a)
69
+ z = np.exp((2 * a - ub - lb) / ((ub - lb) + eps))
70
+
71
+ if z.size == 1:
72
+ return z.item() # Return scalar if input was scalar
73
+ return z
74
+
75
+ @staticmethod
76
+ def _convert_za(z, lb=None, ub=None):
77
+ """
78
+ Converts multiplicative data into the finite normalized additive form.
79
+
80
+ Parameters:
81
+ ----------
82
+ z : scalar or numpy.ndarray
83
+ Input multiplicative data.
84
+ lb : float
85
+ Lower bound (must be a scalar).
86
+ ub : float
87
+ Upper bound (must be a scalar).
88
+
89
+ Returns:
90
+ -------
91
+ a : scalar or numpy.ndarray
92
+ Data converted into finite normalized additive form,
93
+ same type as 'z'.
94
+
95
+ Raises:
96
+ ------
97
+ ValueError:
98
+ If lb or ub is not a scalar.
99
+ """
100
+ if lb is None:
101
+ lb = np.min(z)
102
+ if ub is None:
103
+ ub = np.max(z)
104
+
105
+ if not np.isscalar(lb) or not np.isscalar(ub):
106
+ raise ValueError("lb and ub must be scalars")
107
+ eps = 1e-6 # Small value to ensure strict inequality
108
+ if lb >= ub:
109
+ ub = ub + 1e-12
110
+
111
+ z = np.asarray(z)
112
+ a = (np.log(np.abs(z) + eps) * (ub - lb) + lb + ub) / 2
113
+
114
+ if a.size == 1:
115
+ return a.item() # Return scalar if input was scalar
116
+ return a
117
+
118
+ @staticmethod
119
+ def _convert_mz(m, lb=None, ub=None):
120
+ """
121
+ Converts multiplicative data into the finite normalized multiplicative form.
122
+
123
+ Parameters:
124
+ ----------
125
+ m : scalar or numpy.ndarray
126
+ Input multiplicative data.
127
+ lb : float
128
+ Lower bound (must be a scalar).
129
+ ub : float
130
+ Upper bound (must be a scalar).
131
+
132
+ Returns:
133
+ -------
134
+ z : scalar or numpy.ndarray
135
+ Data converted into finite normalized multiplicative form,
136
+ same type as 'm'.
137
+
138
+ Raises:
139
+ ------
140
+ ValueError:
141
+ If lb or ub is not a scalar.
142
+ """
143
+ if lb is None:
144
+ lb = np.min(m)
145
+ if ub is None:
146
+ ub = np.max(m)
147
+
148
+ if not np.isscalar(lb) or not np.isscalar(ub):
149
+ raise ValueError("lb and ub must be scalars")
150
+
151
+ m = np.asarray(m)
152
+ a = np.log(m / lb) * (2.0 / np.log(ub / lb)) - 1
153
+ z = np.exp(a)
154
+
155
+ if z.size == 1:
156
+ return z.item() # Return scalar if input was scalar
157
+ return z
158
+
159
+ @staticmethod
160
+ def _convert_zm(z, lb=None, ub=None):
161
+ """
162
+ Converts normalized multiplicative data z back to the original multiplicative form.
163
+
164
+ Parameters
165
+ ----------
166
+ z : scalar or numpy.ndarray
167
+ Normalized multiplicative data.
168
+ lb : float
169
+ Lower bound (must be a scalar).
170
+ ub : float
171
+ Upper bound (must be a scalar).
172
+
173
+ Returns
174
+ -------
175
+ m : scalar or numpy.ndarray
176
+ Data converted back to multiplicative form, same type as 'z'.
177
+
178
+ Raises
179
+ ------
180
+ ValueError:
181
+ If lb or ub is not a scalar.
182
+ """
183
+ if lb is None:
184
+ lb = np.min(z)
185
+ if ub is None:
186
+ ub = np.max(z)
187
+
188
+ if not np.isscalar(lb) or not np.isscalar(ub):
189
+ raise ValueError("lb and ub must be scalars")
190
+ v = np.sqrt(ub / lb)
191
+ z = np.asarray(z)
192
+ m = lb * v * z ** np.log(v)
193
+ if m.size == 1:
194
+ return m.item() # Return scalar if input was scalar
195
+ return m
196
+
197
+ @staticmethod
198
+ def convert_data(data,to_multiplicative=True):
199
+ """
200
+ Converts data between additive and multiplicative forms.
201
+
202
+ Parameters:
203
+ ----------
204
+ data : scalar or numpy.ndarray
205
+ Input data to be converted.
206
+ lb : float
207
+ Lower bound (must be a scalar).
208
+ ub : float
209
+ Upper bound (must be a scalar).
210
+ to_multiplicative : bool
211
+ If True, convert from additive to multiplicative.
212
+ If False, convert from multiplicative to additive.
213
+
214
+ Returns:
215
+ -------
216
+ converted_data : scalar or numpy.ndarray
217
+ Converted data in the desired format.
218
+ """
219
+ # if data is not a numpy array, convert it
220
+ if not isinstance(data, np.ndarray):
221
+ data = np.array(data)
222
+ # Check if data is empty
223
+ if data.size == 0:
224
+ raise ValueError("Input data is empty")
225
+ # Check if data is 1D or 2D
226
+ if data.ndim > 2:
227
+ raise ValueError("Input data must be 1D or 2D")
228
+ # bounds
229
+ lb, ub = DataConversion.get_bounds(data)
230
+
231
+ if to_multiplicative:
232
+ return DataConversion._convert_az(data, lb, ub)
233
+ else:
234
+ return DataConversion._convert_za(data, lb, ub)
235
+
236
+ @staticmethod
237
+ def get_bounds(data):
238
+ """
239
+ Get the lower and upper bounds of the data.
240
+
241
+ Parameters:
242
+ ----------
243
+ data : scalar or numpy.ndarray
244
+ Input data to get bounds for.
245
+
246
+ Returns:
247
+ -------
248
+ lb : float
249
+ Lower bound.
250
+ ub : float
251
+ Upper bound.
252
+ """
253
+ data = np.asarray(data)
254
+ lb = np.min(data)
255
+ ub = np.max(data)
256
+ return lb, ub
257
+
258
+ @staticmethod
259
+ def _convert_fininf(z_fin, lb=None, ub=None):
260
+ """
261
+ Converts data from the finite normalized multiplicative form into the infinite interval.
262
+
263
+ Parameters:
264
+ ----------
265
+ z_fin : scalar or numpy.ndarray
266
+ Input data in finite normalized multiplicative form.
267
+ lb : float
268
+ Lower bound (must be a scalar).
269
+ ub : float
270
+ Upper bound (must be a scalar).
271
+
272
+ Returns:
273
+ -------
274
+ z_inf : scalar or numpy.ndarray
275
+ Converted data in infinite interval form, same type as z_fin.
276
+
277
+ Raises:
278
+ ------
279
+ ValueError:
280
+ If lb or ub is not a scalar.
281
+ """
282
+ if lb is None:
283
+ lb = np.min(z_fin)
284
+ if ub is None:
285
+ ub = np.max(z_fin)
286
+
287
+ if not np.isscalar(lb) or not np.isscalar(ub):
288
+ raise ValueError("lb and ub must be scalars")
289
+
290
+ # Adjust the logic to ensure the result is strictly less than ub
291
+ epsilon = 1e-6 # Small value to ensure strict inequality
292
+ z_inf = (z_fin -lb) / (1 - (z_fin / ub) + epsilon)
293
+ return z_inf
294
+
295
+ @staticmethod
296
+ def _convert_inffin(z_inf, lb=None, ub=None):
297
+ """
298
+ Converts data from the infinite interval into the finite normalized multiplicative form.
299
+
300
+ Parameters:
301
+ ----------
302
+ z_inf : scalar or numpy.ndarray
303
+ Input data in infinite interval form.
304
+ lb : float
305
+ Lower bound (must be a scalar).
306
+ ub : float
307
+ Upper bound (must be a scalar).
308
+
309
+ Returns:
310
+ -------
311
+ z_fin : scalar or numpy.ndarray
312
+ Data converted into finite normalized multiplicative form,
313
+ same type as z_inf.
314
+
315
+ Raises:
316
+ ------
317
+ ValueError:
318
+ If lb or ub is not a scalar.
319
+ """
320
+ if lb is None:
321
+ lb = np.min(z_inf)
322
+ if ub is None:
323
+ ub = np.max(z_inf)
324
+
325
+ if not np.isscalar(lb) or not np.isscalar(ub):
326
+ raise ValueError("lb and ub must be scalars")
327
+
328
+ z_inf = np.asarray(z_inf)
329
+ z_fin = (z_inf + lb) / (1 + z_inf / ub)
330
+
331
+ if z_fin.size == 1:
332
+ return z_fin.item() # Return scalar if input was scalar
333
+ return z_fin
334
+
335
+
336
+ @staticmethod
337
+ def get_zi_bounds(data_form, DL, DU)-> tuple:
338
+ """
339
+ Get the lower and upper bounds of the infinite domain data and perform data conversion.
340
+
341
+ Parameters:
342
+ ----------
343
+ data_form : str
344
+ Specifies the data form ('a' for additive, 'm' for multiplicative).
345
+ DLB : float
346
+ Lower bound of the data.
347
+ DUB : float
348
+ Upper bound of the data.
349
+ D : numpy.ndarray
350
+ Input data to be converted.
351
+ C : numpy.ndarray, optional
352
+ Censoring data (default is None).
353
+ B : numpy.ndarray, optional
354
+ Boundary censoring data (default is None).
355
+ ctype : int, optional
356
+ Censoring type (default is 0).
357
+
358
+ Returns:
359
+ -------
360
+ sample : dict
361
+ Contains converted data and bounds.
362
+ """
363
+
364
+ # Validate bounds
365
+ if not np.isscalar(DL) or not np.isscalar(DU):
366
+ raise ValueError("DL and DU must be scalars.")
367
+
368
+ if data_form == "a": # Additive form
369
+ LB = DL - (DU - DL) / 2
370
+ UB = DU + (DU - DL) / 2
371
+
372
+ elif data_form == "m": # Multiplicative form
373
+ LB = DL / np.sqrt(DU / DL)
374
+ UB = DU * np.sqrt(DU / DL)
375
+
376
+ else:
377
+ raise ValueError("Invalid data_form. Use 'a' for additive or 'm' for multiplicative.")
378
+
379
+ return LB, UB
380
+
381
+
@@ -0,0 +1,64 @@
1
+ '''
2
+ ManGo - Machine Gnostics Library
3
+ Copyright (C) 2025 ManGo Team
4
+
5
+ Author: Nirmal Parmar
6
+ '''
7
+
8
+ import numpy as np
9
+ from machinegnostics.magcal import DataConversion, GnosticsWeights
10
+
11
+ def __gcorrelation(data_1:np.ndarray, data_2:np.ndarray) -> float:
12
+ """
13
+ Calculate the Gnostic correlation between two data samples using robust irrelevance-based weighting.
14
+
15
+ This function implements the robust gnostic correlation as described in Kovanic & Humber (2015).
16
+ The method uses irrelevance functions to construct weights,
17
+ providing a robust alternative to classical Pearson correlation. It is less sensitive to outliers,
18
+ does not assume normality.
19
+
20
+
21
+ """
22
+ # if len(data_1) != len(data_2):
23
+ # raise ValueError("Input arrays must have the same length.")
24
+ # if len(data_1) == 0 or len(data_2) == 0:
25
+ # raise ValueError("Input arrays must not be empty.")
26
+ # if not isinstance(data_1, np.ndarray) or not isinstance(data_2, np.ndarray):
27
+ # raise ValueError("Input arrays must be numpy arrays.")
28
+
29
+ zx = data_1 / np.mean(data_1)
30
+ zy = data_2 / np.mean(data_2)
31
+
32
+ dc = DataConversion()
33
+ x_norm = dc._convert_az(zx)
34
+ y_norm = dc._convert_az(zy)
35
+
36
+ gwx = GnosticsWeights()
37
+ wx = gwx._get_gnostic_weights(x_norm)
38
+ gwy = GnosticsWeights()
39
+ wy = gwy._get_gnostic_weights(y_norm)
40
+
41
+ W = np.sqrt(wx * wy)
42
+
43
+ numerator = np.sum(x_norm * W * W * y_norm)
44
+ denominator = np.sqrt(np.sum(x_norm * W * W * x_norm) * np.sum(y_norm * W * W * y_norm))
45
+ if denominator == 0:
46
+ return 0.0
47
+ return numerator / denominator
48
+
49
+ # def gcorrelation(data_1: np.ndarray, data_2: np.ndarray) -> np.ndarray:
50
+ # if data_1.ndim == 1:
51
+ # data_1 = data_1[np.newaxis, :]
52
+ # if data_2.ndim == 1:
53
+ # data_2 = data_2[np.newaxis, :]
54
+ # if data_1.shape[1] != data_2.shape[1]:
55
+ # raise ValueError("Each row in data_1 and data_2 must have the same number of samples (columns).")
56
+
57
+ # n_x, n_samples = data_1.shape
58
+ # n_y = data_2.shape[0]
59
+ # corr_matrix = np.zeros((n_x, n_y))
60
+
61
+ # for i in range(n_x):
62
+ # for j in range(n_y):
63
+ # corr_matrix[i, j] = __gcorrelation(data_1[i], data_2[j])
64
+ # return corr_matrix
@@ -0,0 +1,2 @@
1
+ from machinegnostics.magcal.gdf.wedf import WEDF
2
+ from machinegnostics.magcal.gdf.egdf import EGDF
@@ -0,0 +1,39 @@
1
+ """
2
+ # Base class for distribution functions in Machine Gnostics
3
+ # This module defines the abstract base class for distribution functions used in the Machine Gnostics framework
4
+
5
+ Author: Nirmal Parmar
6
+ Machine Gnostics
7
+ """
8
+
9
+ from abc import ABC, abstractmethod
10
+
11
+ class BaseDistFunc(ABC):
12
+ """
13
+ Abstract base class for distribution functions.
14
+ """
15
+
16
+ @abstractmethod
17
+ def fit(self, data):
18
+ """
19
+ Fit MG distribution function to the data.
20
+
21
+ Parameters:
22
+ X (array-like): Input features.
23
+ y (array-like): Target values.
24
+ """
25
+ pass
26
+
27
+ @abstractmethod
28
+ def plot(self):
29
+ """
30
+ Plot the distribution function.
31
+ """
32
+ pass
33
+
34
+ # @abstractmethod
35
+ # def results(self):
36
+ # """
37
+ # Return the results of the fitted distribution function.
38
+ # """
39
+ # pass