learningmachine 1.1.2__tar.gz → 2.1.0__tar.gz

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 (34) hide show
  1. learningmachine-2.1.0/LICENSE +32 -0
  2. {learningmachine-1.1.2 → learningmachine-2.1.0}/PKG-INFO +1 -1
  3. learningmachine-2.1.0/README.md +54 -0
  4. {learningmachine-1.1.2 → learningmachine-2.1.0}/learningmachine/base.py +72 -7
  5. learningmachine-2.1.0/learningmachine/classifier.py +132 -0
  6. learningmachine-2.1.0/learningmachine/regression.py +100 -0
  7. {learningmachine-1.1.2 → learningmachine-2.1.0}/learningmachine/utils.py +22 -1
  8. {learningmachine-1.1.2 → learningmachine-2.1.0}/learningmachine.egg-info/PKG-INFO +1 -1
  9. {learningmachine-1.1.2 → learningmachine-2.1.0}/learningmachine.egg-info/SOURCES.txt +1 -1
  10. {learningmachine-1.1.2 → learningmachine-2.1.0}/setup.py +57 -22
  11. learningmachine-1.1.2/LICENSE +0 -32
  12. learningmachine-1.1.2/README.rst +0 -37
  13. learningmachine-1.1.2/learningmachine/classifier.py +0 -134
  14. learningmachine-1.1.2/learningmachine/regression.py +0 -92
  15. {learningmachine-1.1.2 → learningmachine-2.1.0}/CONTRIBUTING.rst +0 -0
  16. {learningmachine-1.1.2 → learningmachine-2.1.0}/HISTORY.rst +0 -0
  17. {learningmachine-1.1.2 → learningmachine-2.1.0}/MANIFEST.in +0 -0
  18. {learningmachine-1.1.2 → learningmachine-2.1.0}/docs/Makefile +0 -0
  19. {learningmachine-1.1.2 → learningmachine-2.1.0}/docs/conf.py +0 -0
  20. {learningmachine-1.1.2 → learningmachine-2.1.0}/docs/contributing.rst +0 -0
  21. {learningmachine-1.1.2 → learningmachine-2.1.0}/docs/history.rst +0 -0
  22. {learningmachine-1.1.2 → learningmachine-2.1.0}/docs/index.rst +0 -0
  23. {learningmachine-1.1.2 → learningmachine-2.1.0}/docs/installation.rst +0 -0
  24. {learningmachine-1.1.2 → learningmachine-2.1.0}/docs/make.bat +0 -0
  25. {learningmachine-1.1.2 → learningmachine-2.1.0}/docs/readme.rst +0 -0
  26. {learningmachine-1.1.2 → learningmachine-2.1.0}/docs/usage.rst +0 -0
  27. {learningmachine-1.1.2 → learningmachine-2.1.0}/learningmachine/__init__.py +0 -0
  28. {learningmachine-1.1.2 → learningmachine-2.1.0}/learningmachine.egg-info/dependency_links.txt +0 -0
  29. {learningmachine-1.1.2 → learningmachine-2.1.0}/learningmachine.egg-info/not-zip-safe +0 -0
  30. {learningmachine-1.1.2 → learningmachine-2.1.0}/learningmachine.egg-info/requires.txt +0 -0
  31. {learningmachine-1.1.2 → learningmachine-2.1.0}/learningmachine.egg-info/top_level.txt +0 -0
  32. {learningmachine-1.1.2 → learningmachine-2.1.0}/setup.cfg +0 -0
  33. {learningmachine-1.1.2 → learningmachine-2.1.0}/tests/__init__.py +0 -0
  34. {learningmachine-1.1.2 → learningmachine-2.1.0}/tests/test_learningmachine.py +0 -0
@@ -0,0 +1,32 @@
1
+ The Clear BSD License
2
+
3
+ Copyright (c) [2023-2024] [T. Moudiki]
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted (subject to the limitations in the disclaimer
8
+ below) provided that the following conditions are met:
9
+
10
+ * Redistributions of source code must retain the above copyright notice,
11
+ this list of conditions and the following disclaimer.
12
+
13
+ * Redistributions in binary form must reproduce the above copyright
14
+ notice, this list of conditions and the following disclaimer in the
15
+ documentation and/or other materials provided with the distribution.
16
+
17
+ * Neither the name of the copyright holder nor the names of its
18
+ contributors may be used to endorse or promote products derived from this
19
+ software without specific prior written permission.
20
+
21
+ NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
22
+ THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23
+ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
26
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
30
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ POSSIBILITY OF SUCH DAMAGE.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: learningmachine
3
- Version: 1.1.2
3
+ Version: 2.1.0
4
4
  Summary: Machine Learning with uncertainty quantification and interpretability
5
5
  Home-page: https://github.com/Techtonique/learningmachine_python
6
6
  Author: T. Moudiki
@@ -0,0 +1,54 @@
1
+ # learningmachine
2
+
3
+ ![PyPI](https://img.shields.io/pypi/v/learningmachine) [![PyPI - License](https://img.shields.io/pypi/l/learningmachine)](https://github.com/thierrymoudiki/learningmachine/blob/master/LICENSE) [![Downloads](https://pepy.tech/badge/learningmachine)](https://pepy.tech/project/learningmachine)
4
+
5
+
6
+ Machine Learning with uncertainty quantification and interpretability.
7
+
8
+ ## Install
9
+
10
+ If R packages are not installed automatically when running `pip`, [install it manually](https://cloud.r-project.org/).
11
+
12
+ **Development version**
13
+
14
+ ```bash
15
+ !pip install git+https://github.com/Techtonique/learningmachine_python.git --verbose
16
+ ```
17
+
18
+ **Stable version**
19
+
20
+ ```bash
21
+ !pip install learningmachine --verbose
22
+ ```
23
+
24
+ ## Example
25
+
26
+ See also:
27
+ - [this notebook](https://colab.research.google.com/github/Techtonique/learningmachine_python/blob/main/learningmachine/demo/thierrymoudiki_20240401_calib.ipynb)
28
+ - [this notebook](https://colab.research.google.com/github/Techtonique/learningmachine_python/blob/main/learningmachine/demo/thierrymoudiki_20240508_calib.ipynb)
29
+
30
+ ```python
31
+ import learningmachine as lm
32
+
33
+ from sklearn.datasets import load_diabetes
34
+ from sklearn.model_selection import train_test_split
35
+ from time import time
36
+ from sklearn.metrics import mean_squared_error
37
+
38
+ # Regression (linear)
39
+ fit_obj = lm.BaseRegressor()
40
+ diabetes = load_diabetes()
41
+ X = diabetes.data[:150]
42
+ y = diabetes.target[:150]
43
+
44
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
45
+ random_state=1213)
46
+
47
+ start = time()
48
+ fit_obj.fit(X_train, y_train)
49
+ print("Elapsed time: ", time() - start)
50
+
51
+ ## Compute RMSE
52
+ rms1 = sqrt(mean_squared_error(y_test, fit_obj.predict(X_test), squared=False))
53
+ print(rms1)
54
+ ```
@@ -2,9 +2,16 @@ import sklearn.metrics as skm
2
2
  import subprocess
3
3
  from functools import lru_cache
4
4
  from sklearn.base import BaseEstimator
5
- from rpy2.robjects.vectors import StrVector
5
+ from rpy2.robjects.vectors import (
6
+ StrVector,
7
+ FloatMatrix,
8
+ FloatVector,
9
+ IntVector,
10
+ FactorVector,
11
+ )
6
12
  from rpy2.robjects.packages import importr
7
13
  from rpy2.robjects import r
14
+ from rpy2.robjects import NULL as rNULL
8
15
 
9
16
  base = importr("base")
10
17
  stats = importr("stats")
@@ -23,7 +30,6 @@ class Base(BaseEstimator):
23
30
  method="ranger",
24
31
  pi_method="kdesplitconformal",
25
32
  level=95,
26
- type_prediction_set="score",
27
33
  B=100,
28
34
  nb_hidden = 0,
29
35
  nodes_sim = "sobol",
@@ -40,7 +46,6 @@ class Base(BaseEstimator):
40
46
  self.method = method
41
47
  self.pi_method = pi_method
42
48
  self.level = level
43
- self.type_prediction_set = type_prediction_set
44
49
  self.B = B
45
50
  self.nb_hidden = nb_hidden
46
51
  assert nodes_sim in ("sobol", "halton", "unif"), \
@@ -54,7 +59,6 @@ class Base(BaseEstimator):
54
59
  self.seed = seed
55
60
  self.obj = None
56
61
 
57
- @lru_cache
58
62
  def load_learningmachine(self):
59
63
  # Install R packages
60
64
  commands1_lm = 'base::system.file(package = "learningmachine")' # check "learningmachine" is installed
@@ -96,10 +100,10 @@ class Base(BaseEstimator):
96
100
  )
97
101
  except: # well, we tried
98
102
  try:
99
- r("try(library('learningmachine'), silence=TRUE)")
103
+ r("try(suppressWarnings(suppressMessages(library('learningmachine'))), silence=TRUE)")
100
104
  except: # well, we tried everything at this point
101
105
  r(
102
- "try(library('learningmachine', lib.loc='learningmachine_r'), silence=TRUE)"
106
+ "try(suppressWarnings(suppressMessages(library('learningmachine', lib.loc='learningmachine_r'))), silence=TRUE)"
103
107
  )
104
108
 
105
109
  def score(self, X, y, scoring=None, **kwargs):
@@ -172,7 +176,7 @@ class Base(BaseEstimator):
172
176
  try:
173
177
  preds = preds.ravel().astype(int)
174
178
  return scoring_options[scoring](y, preds, **kwargs)
175
- except:
179
+ except TypeError:
176
180
  return scoring_options[scoring](y, preds, **kwargs)
177
181
 
178
182
  if self.type == "regression":
@@ -207,3 +211,64 @@ class Base(BaseEstimator):
207
211
  }
208
212
 
209
213
  return scoring_options[scoring](y, preds, **kwargs)
214
+
215
+ def summary(self, X, y,
216
+ class_index = None,
217
+ level = 95,
218
+ show_progress = True,
219
+ cl = None):
220
+
221
+ if cl is None:
222
+
223
+ if self.type == "classification":
224
+
225
+ assert class_index is not None, "class_index must be provided for classification models"
226
+
227
+ self.obj["summary"](X = r.matrix(FloatVector(X.ravel()),
228
+ byrow=True,
229
+ ncol=X.shape[1],
230
+ nrow=X.shape[0]),
231
+ y = FactorVector(IntVector(y)),
232
+ class_index = class_index + 1,
233
+ level = level,
234
+ show_progress = show_progress
235
+ )
236
+
237
+ else: # regression
238
+
239
+ self.obj["summary"](X = r.matrix(FloatVector(X.ravel()),
240
+ byrow=True,
241
+ ncol=X.shape[1],
242
+ nrow=X.shape[0]),
243
+ y = FloatVector(y),
244
+ level = level,
245
+ show_progress = show_progress
246
+ )
247
+ else: # cl is not None, parallel computing
248
+
249
+ if self.type == "classification":
250
+
251
+ assert class_index is not None, "class_index must be provided for classification models"
252
+
253
+ self.obj["summary"](X = r.matrix(FloatVector(X.ravel()),
254
+ byrow=True,
255
+ ncol=X.shape[1],
256
+ nrow=X.shape[0]),
257
+ y = FactorVector(IntVector(y)),
258
+ level = level,
259
+ show_progress = show_progress,
260
+ class_index = class_index + 1,
261
+ cl = cl
262
+ )
263
+
264
+ else: # regression
265
+
266
+ self.obj["summary"](X = r.matrix(FloatVector(X.ravel()),
267
+ byrow=True,
268
+ ncol=X.shape[1],
269
+ nrow=X.shape[0]),
270
+ y = FloatVector(y),
271
+ level = level,
272
+ show_progress = show_progress,
273
+ cl = cl
274
+ )
@@ -0,0 +1,132 @@
1
+ import numpy as np
2
+ import sklearn.metrics as skm
3
+ from rpy2.robjects import r
4
+ from rpy2.robjects.packages import importr
5
+ from rpy2.robjects.vectors import (
6
+ FloatVector,
7
+ IntVector,
8
+ FactorVector,
9
+ ListVector
10
+ )
11
+ from sklearn.base import ClassifierMixin
12
+ from .base import Base
13
+ from .utils import format_value, r_list_to_namedtuple
14
+
15
+ base = importr("base")
16
+ stats = importr("stats")
17
+ utils = importr("utils")
18
+
19
+
20
+ class Classifier(Base, ClassifierMixin):
21
+ """
22
+ Classifier.
23
+ """
24
+
25
+ def __init__(
26
+ self,
27
+ method="ranger",
28
+ pi_method="none",
29
+ level=95,
30
+ type_prediction_set="score",
31
+ B=100,
32
+ nb_hidden = 0,
33
+ nodes_sim = "sobol",
34
+ activ = "relu",
35
+ seed=123,
36
+ ):
37
+ """
38
+ Initialize the model.
39
+ """
40
+ super().__init__(
41
+ name = "Classifier",
42
+ type = "classification",
43
+ method=method,
44
+ pi_method=pi_method,
45
+ level=level,
46
+ B=B,
47
+ nb_hidden=nb_hidden,
48
+ nodes_sim=nodes_sim,
49
+ activ=activ,
50
+ seed=seed,
51
+ )
52
+
53
+ self.type_prediction_set=type_prediction_set
54
+
55
+ try:
56
+ r_obj_command = (
57
+ 'suppressWarnings(suppressMessages(library(learningmachine))); '
58
+ 'Classifier$new(method = ' + str(format_value(self.method)) + ', '
59
+ 'pi_method = ' + str(format_value(self.pi_method)) + ', '
60
+ 'level = ' + str(format_value(self.level)) + ', '
61
+ 'type_prediction_set = ' + str(format_value(self.type_prediction_set)) + ', '
62
+ 'B = ' + str(format_value(self.B)) + ', '
63
+ 'nb_hidden = ' + str(format_value(self.nb_hidden)) + ', '
64
+ 'nodes_sim = ' + str(format_value(self.nodes_sim)) + ', '
65
+ 'activ = ' + str(format_value(self.activ)) + ', '
66
+ 'seed = ' + str(format_value(self.seed)) + ')')
67
+ self.obj = r(r_obj_command)
68
+ except Exception:
69
+ try:
70
+ self.obj = r(f"suppressWarnings(suppressMessages(library(learningmachine))); Classifier$new(method = {format_value(self.method)}, pi_method = {format_value(self.pi_method)}, level = {format_value(self.level)}, type_prediction_set = {format_value(self.type_prediction_set)}, B = {format_value(self.B)}, nb_hidden = {format_value(self.nb_hidden)}, nodes_sim = {format_value(self.nodes_sim)}, activ = {format_value(self.activ)}, seed = {format_value(self.seed)})")
71
+ except Exception:
72
+ self.obj = r(
73
+ f"learningmachine::Classifier$new(method = {format_value(self.method)}, pi_method = {format_value(self.pi_method)}, level = {format_value(self.level)}, type_prediction_set = {format_value(self.type_prediction_set)}, B = {format_value(self.B)}, nb_hidden = {format_value(self.nb_hidden)}, nodes_sim = {format_value(self.nodes_sim)}, activ = {format_value(self.activ)}, seed = {format_value(self.seed)})"
74
+ )
75
+
76
+ def fit(self, X, y, **kwargs):
77
+ """
78
+ Fit the model according to the given training data.
79
+ """
80
+ params_dict = {}
81
+ for k, v in kwargs.items():
82
+ params_dict[k.replace('_', '.')] = v
83
+ self.obj["fit"](r.matrix(FloatVector(X.ravel()),
84
+ byrow=True,
85
+ ncol=X.shape[1],
86
+ nrow=X.shape[0]),
87
+ FactorVector(IntVector(y)),
88
+ **params_dict)
89
+ self.classes_ = np.unique(y) # /!\ do not remove
90
+ return self
91
+
92
+ def predict_proba(self, X):
93
+ """
94
+ Predict using the model.
95
+ """
96
+ if self.pi_method == "none":
97
+ res = self.obj["predict_proba"](
98
+ r.matrix(FloatVector(X.ravel()),
99
+ byrow=True,
100
+ ncol=X.shape[1],
101
+ nrow=X.shape[0])
102
+ )
103
+ return np.asarray(res)
104
+ return r_list_to_namedtuple(self.obj["predict_proba"](
105
+ r.matrix(FloatVector(X.ravel()),
106
+ byrow=True,
107
+ ncol=X.shape[1],
108
+ nrow=X.shape[0])
109
+ ))
110
+
111
+ def predict(self, X):
112
+ """
113
+ Predict using the model.
114
+ """
115
+ if self.pi_method == "none":
116
+ return (
117
+ np.asarray(
118
+ self.obj["predict"](
119
+ r.matrix(FloatVector(X.ravel()),
120
+ byrow=True,
121
+ ncol=X.shape[1],
122
+ nrow=X.shape[0])
123
+ )
124
+ ) - 1
125
+ )
126
+ return r_list_to_namedtuple(self.obj["predict"](
127
+ r.matrix(FloatVector(X.ravel()),
128
+ byrow=True,
129
+ ncol=X.shape[1],
130
+ nrow=X.shape[0])
131
+ ))
132
+
@@ -0,0 +1,100 @@
1
+ import numpy as np
2
+ from rpy2.robjects import r
3
+ from rpy2.robjects.packages import importr
4
+ from rpy2.robjects.vectors import FloatVector, ListVector
5
+ from sklearn.base import RegressorMixin
6
+ from .base import Base
7
+ from .utils import format_value, r_list_to_namedtuple
8
+
9
+ base = importr("base")
10
+ stats = importr("stats")
11
+ utils = importr("utils")
12
+
13
+
14
+ class Regressor(Base, RegressorMixin):
15
+ """
16
+ Regressor.
17
+ """
18
+
19
+ def __init__(
20
+ self,
21
+ method="ranger",
22
+ pi_method="none",
23
+ level=95,
24
+ B=100,
25
+ nb_hidden = 0,
26
+ nodes_sim = "sobol",
27
+ activ = "relu",
28
+ seed=123,
29
+ ):
30
+ """
31
+ Initialize the model.
32
+ """
33
+ super().__init__(
34
+ name = "Regressor",
35
+ type = "regression",
36
+ method=method,
37
+ pi_method=pi_method,
38
+ level=level,
39
+ B=B,
40
+ nb_hidden=nb_hidden,
41
+ nodes_sim=nodes_sim,
42
+ activ=activ,
43
+ seed=seed,
44
+ )
45
+
46
+ try:
47
+ r_obj_command = (
48
+ 'suppressWarnings(suppressMessages(library(learningmachine))); '
49
+ 'Regressor$new(method = ' + str(format_value(self.method)) + ', '
50
+ 'pi_method = ' + str(format_value(self.pi_method)) + ', '
51
+ 'level = ' + str(format_value(self.level)) + ', '
52
+ 'B = ' + str(format_value(self.B)) + ', '
53
+ 'nb_hidden = ' + str(format_value(self.nb_hidden)) + ', '
54
+ 'nodes_sim = ' + str(format_value(self.nodes_sim)) + ', '
55
+ 'activ = ' + str(format_value(self.activ)) + ', '
56
+ 'seed = ' + str(format_value(self.seed)) + ')')
57
+ self.obj = r(r_obj_command)
58
+ except Exception:
59
+ try:
60
+ self.obj = r(f"suppressWarnings(suppressMessages(library(learningmachine))); Regressor$new(method = {format_value(self.method)}, pi_method = {format_value(self.pi_method)}, level = {format_value(self.level)}, B = {format_value(self.B)}, nb_hidden = {format_value(self.nb_hidden)}, nodes_sim = {format_value(self.nodes_sim)}, activ = {format_value(self.activ)}, seed = {format_value(self.seed)})")
61
+ except Exception:
62
+ self.obj = r(
63
+ f"learningmachine::Regressor$new(method = {format_value(self.method)}, pi_method = {format_value(self.pi_method)}, level = {format_value(self.level)}, B = {format_value(self.B)}, nb_hidden = {format_value(self.nb_hidden)}, nodes_sim = {format_value(self.nodes_sim)}, activ = {format_value(self.activ)}, seed = {format_value(self.seed)})"
64
+ )
65
+
66
+ def fit(self, X, y, **kwargs):
67
+ """
68
+ Fit the model according to the given training data.
69
+ """
70
+ params_dict = {}
71
+ for k, v in kwargs.items():
72
+ params_dict[k.replace('_', '.')] = v
73
+ self.obj["fit"](
74
+ r.matrix(FloatVector(X.ravel()),
75
+ byrow=True,
76
+ ncol=X.shape[1],
77
+ nrow=X.shape[0]),
78
+ FloatVector(y),
79
+ **params_dict
80
+ )
81
+ return self
82
+
83
+ def predict(self, X):
84
+ """
85
+ Predict using the model.
86
+ """
87
+ if self.pi_method == "none":
88
+ return(np.asarray(self.obj["predict"](
89
+ r.matrix(FloatVector(X.ravel()),
90
+ byrow=True,
91
+ ncol=X.shape[1],
92
+ nrow=X.shape[0])
93
+ )))
94
+ return r_list_to_namedtuple(self.obj["predict"](
95
+ r.matrix(FloatVector(X.ravel()),
96
+ byrow=True,
97
+ ncol=X.shape[1],
98
+ nrow=X.shape[0])
99
+ ))
100
+
@@ -1,5 +1,8 @@
1
+ import numpy as np
1
2
  import subprocess
2
3
  from rpy2.robjects import r
4
+ from rpy2.robjects import NULL as rNULL
5
+ from collections import namedtuple
3
6
 
4
7
 
5
8
  def check_pkg_installed():
@@ -71,4 +74,22 @@ def format_value(value):
71
74
  if isinstance(value, bool):
72
75
  return f"{str(value).upper()}"
73
76
  if isinstance(value, int) or isinstance(value, float):
74
- return f"{value}"
77
+ return f"{value}"
78
+
79
+ # R list to namedtuple
80
+ def r_list_to_namedtuple(r_list):
81
+ # Extract the names from the R list
82
+ if r_list.names is rNULL:
83
+ ##names = [f'obs{i+1}' for i in range(len(r_list))]
84
+ # Define a namedtuple type based on the names in the R list
85
+ ##DescribeResult = namedtuple('DescribeResult', names)
86
+ # Extract elements from the R list and create a namedtuple
87
+ ##elements = {name: r_list.rx2(i+1) for i, name in enumerate(names)}
88
+ ##return DescribeResult(**elements)
89
+ return tuple([[int(r_list.rx2(i+1)[j]) for j in range(len(r_list.rx2(i+1)))] for i in range(len(r_list))])
90
+ names = r_list.names
91
+ # Define a namedtuple type based on the names in the R list
92
+ DescribeResult = namedtuple('DescribeResult', names)
93
+ # Extract elements from the R list and create a namedtuple
94
+ elements = {name: np.asarray(r_list.rx2(name)) for name in names}
95
+ return DescribeResult(**elements)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: learningmachine
3
- Version: 1.1.2
3
+ Version: 2.1.0
4
4
  Summary: Machine Learning with uncertainty quantification and interpretability
5
5
  Home-page: https://github.com/Techtonique/learningmachine_python
6
6
  Author: T. Moudiki
@@ -2,7 +2,7 @@ CONTRIBUTING.rst
2
2
  HISTORY.rst
3
3
  LICENSE
4
4
  MANIFEST.in
5
- README.rst
5
+ README.md
6
6
  setup.cfg
7
7
  setup.py
8
8
  docs/Makefile
@@ -69,34 +69,69 @@ def install_r():
69
69
  print("Unsupported platform. Unable to install R.")
70
70
 
71
71
  def install_packages():
72
- try:
73
- subprocess.run(["sudo", "Rscript", "-e", "utils::install.packages(devtools, dependencies=TRUE)"])
74
- subprocess.run(["sudo", "Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), dependencies=TRUE)"])
75
- subprocess.run(["sudo", "Rscript", "-e", "utils::install.packages('learningmachine', repos='https://techtonique.r-universe.dev', dependencies=TRUE)"])
76
- except:
77
- try:
72
+ try:
73
+ subprocess.run(["Rscript", "-e", "utils::install.packages('remotes', dependencies=TRUE)"])
74
+ subprocess.run(["Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), dependencies=TRUE)"])
75
+ subprocess.run(["Rscript", "-e", "remotes::install_github('Techtonique/learningmachine')"])
76
+ except subprocess.CalledProcessError as e:
77
+ print(f"Error occurred: {e}")
78
+ print(f"Return code: {e.returncode}")
79
+ print(f"Output: {e.output}")
80
+ print(f"Stderr: {e.stderr}")
81
+ try:
78
82
  subprocess.run(["mkdir", "-p", "r-learningmachine"])
79
- subprocess.run(["sudo", "Rscript", "-e", "utils::install.packages(devtools, lib='r-learningmachine', dependencies=TRUE)"])
80
- subprocess.run(["sudo", "Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), lib='r-learningmachine', dependencies=TRUE)"])
81
- subprocess.run(["sudo", "Rscript", "-e", "utils::install.packages('learningmachine', repos='https://techtonique.r-universe.dev', lib='r-learningmachine', dependencies=TRUE)"])
82
- except:
83
+ subprocess.run(["Rscript", "-e", "utils::install.packages('remotes', lib='r-learningmachine', dependencies=TRUE)"])
84
+ subprocess.run(["Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), lib='r-learningmachine', dependencies=TRUE)"])
85
+ subprocess.run(["Rscript", "-e", "remotes::install_github('Techtonique/learningmachine', lib='r-learningmachine')"])
86
+ except subprocess.CalledProcessError as e:
87
+ print(f"Error occurred: {e}")
88
+ print(f"Return code: {e.returncode}")
89
+ print(f"Output: {e.output}")
90
+ print(f"Stderr: {e.stderr}")
83
91
  try:
84
- subprocess.run(["sudo", "Rscript", "-e", "utils::install.packages(devtools, dependencies=TRUE)"])
85
- subprocess.run(["sudo", "Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), dependencies=TRUE)"])
86
- subprocess.run(["sudo", "Rscript", "-e", "devtools::install_github('Techtonique/learningmachine')"])
87
- except:
88
- subprocess.run(["mkdir", "-p", "r-learningmachine"])
89
- subprocess.run(["sudo", "Rscript", "-e", "utils::install.packages(devtools, lib='r-learningmachine', dependencies=TRUE)"])
90
- subprocess.run(["sudo", "Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), lib='r-learningmachine', dependencies=TRUE)"])
91
- subprocess.run(["sudo", "Rscript", "-e", "devtools::install_github('Techtonique/learningmachine', lib='r-learningmachine')"])
92
+ subprocess.run(["Rscript", "-e", "utils::install.packages('remotes', dependencies=TRUE)"])
93
+ subprocess.run(["Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), dependencies=TRUE)"])
94
+ subprocess.run(["Rscript", "-e", "remotes::install_github('Techtonique/learningmachine')"])
95
+ except subprocess.CalledProcessError as e:
96
+ print(f"Error occurred: {e}")
97
+ print(f"Return code: {e.returncode}")
98
+ print(f"Output: {e.output}")
99
+ print(f"Stderr: {e.stderr}")
100
+ try:
101
+ subprocess.run(["mkdir", "-p", "r-learningmachine"])
102
+ subprocess.run(["Rscript", "-e", "utils::install.packages('remotes', lib='r-learningmachine', dependencies=TRUE)"])
103
+ subprocess.run(["Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), lib='r-learningmachine', dependencies=TRUE)"])
104
+ subprocess.run(["Rscript", "-e", "remotes::install_github('Techtonique/learningmachine', lib='r-learningmachine')"])
105
+ except subprocess.CalledProcessError as e:
106
+ print(f"Error occurred: {e}")
107
+ print(f"Return code: {e.returncode}")
108
+ print(f"Output: {e.output}")
109
+ print(f"Stderr: {e.stderr}")
110
+ try:
111
+ subprocess.run(["Rscript", "-e", "utils::install.packages('remotes', dependencies=TRUE)"])
112
+ subprocess.run(["Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), dependencies=TRUE)"])
113
+ subprocess.run(["Rscript", "-e", "remotes::install_github('Techtonique/learningmachine')"])
114
+ except subprocess.CalledProcessError as e:
115
+ print(f"Error occurred: {e}")
116
+ print(f"Return code: {e.returncode}")
117
+ print(f"Output: {e.output}")
118
+ print(f"Stderr: {e.stderr}")
119
+ subprocess.run(["mkdir", "-p", "r-learningmachine"])
120
+ subprocess.run(["Rscript", "-e", "utils::install.packages('remotes', lib='r-learningmachine', dependencies=TRUE)"])
121
+ subprocess.run(["Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), lib='r-learningmachine', dependencies=TRUE)"])
122
+ subprocess.run(["Rscript", "-e", "remotes::install_github('Techtonique/learningmachine', lib='r-learningmachine')"])
92
123
 
93
124
 
94
125
  # Check if R is installed; if not, install it
95
126
  if not check_r_installed():
96
- print("Installing R...")
97
- install_r()
127
+ install_r_prompt = int(input("Try installing R? 1-yes, 2-no"))
128
+ if install_r_prompt == 1:
129
+ print("Installing R...")
130
+ install_r()
131
+ else:
132
+ raise ValueError('Try installing R manually first.')
98
133
  else:
99
- print("No installation needed.")
134
+ print("No R installation needed.")
100
135
 
101
136
  install_packages()
102
137
 
@@ -134,6 +169,6 @@ setup(
134
169
  packages=find_packages(include=["learningmachine", "learningmachine.*"]),
135
170
  test_suite="tests",
136
171
  url="https://github.com/Techtonique/learningmachine_python",
137
- version="1.1.2",
172
+ version="2.1.0",
138
173
  zip_safe=False,
139
174
  )
@@ -1,32 +0,0 @@
1
-
2
-
3
- BSD License
4
-
5
- Copyright (c) 2024, T. Moudiki
6
- All rights reserved.
7
-
8
- Redistribution and use in source and binary forms, with or without modification,
9
- are permitted provided that the following conditions are met:
10
-
11
- * Redistributions of source code must retain the above copyright notice, this
12
- list of conditions and the following disclaimer.
13
-
14
- * Redistributions in binary form must reproduce the above copyright notice, this
15
- list of conditions and the following disclaimer in the documentation and/or
16
- other materials provided with the distribution.
17
-
18
- * Neither the name of the copyright holder nor the names of its
19
- contributors may be used to endorse or promote products derived from this
20
- software without specific prior written permission.
21
-
22
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
- IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
26
- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
29
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30
- OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31
- OF THE POSSIBILITY OF SUCH DAMAGE.
32
-
@@ -1,37 +0,0 @@
1
- ===============
2
- learningmachine
3
- ===============
4
-
5
-
6
- .. image:: https://img.shields.io/pypi/v/learningmachine.svg
7
- :target: https://pypi.python.org/pypi/learningmachine
8
-
9
- .. image:: https://img.shields.io/travis/Techtonique/learningmachine.svg
10
- :target: https://travis-ci.com/Techtonique/learningmachine
11
-
12
- .. image:: https://readthedocs.org/projects/learningmachine/badge/?version=latest
13
- :target: https://learningmachine.readthedocs.io/en/latest/?version=latest
14
- :alt: Documentation Status
15
-
16
-
17
-
18
-
19
- Machine Learning with uncertainty quantification and interpretability
20
-
21
-
22
- * Free software: BSD license
23
- * Documentation: https://learningmachine.readthedocs.io.
24
-
25
-
26
- Features
27
- --------
28
-
29
- * TODO
30
-
31
- Credits
32
- -------
33
-
34
- This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.
35
-
36
- .. _Cookiecutter: https://github.com/audreyr/cookiecutter
37
- .. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage
@@ -1,134 +0,0 @@
1
- import numpy as np
2
- import sklearn.metrics as skm
3
- from rpy2.robjects import r
4
- from rpy2.robjects.packages import importr
5
- from rpy2.robjects.vectors import (
6
- FloatMatrix,
7
- FloatVector,
8
- IntVector,
9
- FactorVector,
10
- )
11
- from sklearn.base import ClassifierMixin
12
- from .base import Base
13
- from .utils import format_value
14
-
15
- base = importr("base")
16
- stats = importr("stats")
17
- utils = importr("utils")
18
-
19
-
20
- class Classifier(Base, ClassifierMixin):
21
- """
22
- Classifier.
23
- """
24
-
25
- def __init__(
26
- self,
27
- method="ranger",
28
- pi_method="kdesplitconformal",
29
- level=95,
30
- type_prediction_set="score",
31
- B=100,
32
- nb_hidden = 0,
33
- nodes_sim = "sobol",
34
- activ = "relu",
35
- seed=123,
36
- ):
37
- """
38
- Initialize the model.
39
- """
40
- super().__init__(
41
- name = "Classifier",
42
- type = "classification",
43
- method=method,
44
- pi_method=pi_method,
45
- level=level,
46
- type_prediction_set=type_prediction_set,
47
- B=B,
48
- nb_hidden=nb_hidden,
49
- nodes_sim=nodes_sim,
50
- activ=activ,
51
- seed=seed,
52
- )
53
-
54
- try:
55
- self.load_learningmachine()
56
- self.obj = r(
57
- f"learningmachine::Classifier$new(method = {format_value(self.method)}, pi_method = {format_value(self.pi_method)}, level = {format_value(self.level)}, type_prediction_set = {format_value(self.type_prediction_set)}, B = {format_value(self.B)}, nb_hidden = {format_value(self.nb_hidden)}, nodes_sim = {format_value(self.nodes_sim)}, activ = {format_value(self.activ)}, seed = {format_value(self.seed)})"
58
- )
59
- except NotImplementedError as e:
60
- try:
61
- r.library("learningmachine")
62
- self.obj = r(
63
- f"Classifier$new(method = {format_value(self.method)}, pi_method = {format_value(self.pi_method)}, level = {format_value(self.level)}, type_prediction_set = {format_value(self.type_prediction_set)}, B = {format_value(self.B)}, nb_hidden = {format_value(self.nb_hidden)}, nodes_sim = {format_value(self.nodes_sim)}, activ = {format_value(self.activ)}, seed = {format_value(self.seed)})"
64
- )
65
- except NotImplementedError as e:
66
- try:
67
- self.obj = r(
68
- f"""
69
- library(learningmachine);
70
- Classifier$new(method = {format_value(self.method)}, pi_method = {format_value(self.pi_method)}, level = {format_value(self.level)}, type_prediction_set = {format_value(self.type_prediction_set)}, B = {format_value(self.B)}, nb_hidden = {format_value(self.nb_hidden)}, nodes_sim = {format_value(self.nodes_sim)}, activ = {format_value(self.activ)}, seed = {format_value(self.seed)})
71
- """
72
- )
73
- except NotImplementedError as e:
74
- print("R package can't be loaded: ", e)
75
-
76
- def fit(self, X, y):
77
- """
78
- Fit the model according to the given training data.
79
- """
80
- self.obj["fit"](
81
- r.matrix(FloatVector(X.ravel()),
82
- byrow=True,
83
- ncol=X.shape[1],
84
- nrow=X.shape[0]),
85
- FactorVector(IntVector(y)),
86
- )
87
- self.classes_ = np.unique(y) # /!\ do not remove
88
- return self
89
-
90
- def predict_proba(self, X):
91
- """
92
- Predict using the model.
93
- """
94
- if self.level is None:
95
- res = self.obj["predict_proba"](
96
- r.matrix(FloatVector(X.ravel()),
97
- byrow=True,
98
- ncol=X.shape[1],
99
- nrow=X.shape[0])
100
- )
101
- return np.asarray(res)
102
- res = self.obj["predict_proba"](
103
- r.matrix(FloatVector(X.ravel()),
104
- byrow=True,
105
- ncol=X.shape[1],
106
- nrow=X.shape[0])
107
- )
108
- return np.asarray(res[0])
109
-
110
- def predict(self, X):
111
- """
112
- Predict using the model.
113
- """
114
- if self.level is None:
115
- return (
116
- np.asarray(
117
- self.obj["predict"](
118
- r.matrix(FloatVector(X.ravel()),
119
- byrow=True,
120
- ncol=X.shape[1],
121
- nrow=X.shape[0])
122
- )
123
- ) - 1
124
- )
125
- return (
126
- np.asarray(
127
- self.obj["predict"](
128
- r.matrix(FloatVector(X.ravel()),
129
- byrow=True,
130
- ncol=X.shape[1],
131
- nrow=X.shape[0])
132
- )
133
- )
134
- )
@@ -1,92 +0,0 @@
1
- import numpy as np
2
- from rpy2.robjects import r
3
- from rpy2.robjects.packages import importr
4
- from rpy2.robjects.vectors import FloatMatrix, FloatVector
5
- from sklearn.base import RegressorMixin
6
- from .base import Base
7
- from .utils import format_value
8
-
9
- base = importr("base")
10
- stats = importr("stats")
11
- utils = importr("utils")
12
-
13
-
14
- class Regressor(Base, RegressorMixin):
15
- """
16
- Regressor.
17
- """
18
-
19
- def __init__(
20
- self,
21
- method="ranger",
22
- pi_method="kdesplitconformal",
23
- level=95,
24
- B=100,
25
- nb_hidden = 0,
26
- nodes_sim = "sobol",
27
- activ = "relu",
28
- seed=123,
29
- ):
30
- """
31
- Initialize the model.
32
- """
33
- super().__init__(
34
- name = "Regressor",
35
- type = "regression",
36
- method=method,
37
- pi_method=pi_method,
38
- level=level,
39
- B=B,
40
- nb_hidden=nb_hidden,
41
- nodes_sim=nodes_sim,
42
- activ=activ,
43
- seed=seed,
44
- )
45
-
46
- try:
47
- self.load_learningmachine()
48
- self.obj = r(
49
- f"learningmachine::Regressor$new(method = {format_value(self.method)}, pi_method = {format_value(self.pi_method)}, level = {format_value(self.level)}, type_prediction_set = {format_value(self.type_prediction_set)}, B = {format_value(self.B)}, nb_hidden = {format_value(self.nb_hidden)}, nodes_sim = {format_value(self.nodes_sim)}, activ = {format_value(self.activ)}, seed = {format_value(self.seed)})"
50
- )
51
- except NotImplementedError as e:
52
- try:
53
- r.library("learningmachine")
54
- self.obj = r(
55
- f"Regressor$new(method = {format_value(self.method)}, pi_method = {format_value(self.pi_method)}, level = {format_value(self.level)}, type_prediction_set = {format_value(self.type_prediction_set)}, B = {format_value(self.B)}, nb_hidden = {format_value(self.nb_hidden)}, nodes_sim = {format_value(self.nodes_sim)}, activ = {format_value(self.activ)}, seed = {format_value(self.seed)})"
56
- )
57
- except NotImplementedError as e:
58
- try:
59
- self.obj = r(
60
- f"""
61
- library(learningmachine);
62
- Regressor$new(method = {format_value(self.method)}, pi_method = {format_value(self.pi_method)}, level = {format_value(self.level)}, type_prediction_set = {format_value(self.type_prediction_set)}, B = {format_value(self.B)}, nb_hidden = {format_value(self.nb_hidden)}, nodes_sim = {format_value(self.nodes_sim)}, activ = {format_value(self.activ)}, seed = {format_value(self.seed)})
63
- """
64
- )
65
- except NotImplementedError as e:
66
- print("R package can't be loaded: ", e)
67
-
68
- def fit(self, X, y):
69
- """
70
- Fit the model according to the given training data.
71
- """
72
- self.obj["fit"](
73
- r.matrix(FloatVector(X.ravel()),
74
- byrow=True,
75
- ncol=X.shape[1],
76
- nrow=X.shape[0]),
77
- FloatVector(y),
78
- )
79
- return self
80
-
81
- def predict(self, X):
82
- """
83
- Predict using the model.
84
- """
85
- return np.asarray(
86
- self.obj["predict"](
87
- r.matrix(FloatVector(X.ravel()),
88
- byrow=True,
89
- ncol=X.shape[1],
90
- nrow=X.shape[0])
91
- )
92
- )