learningmachine 1.1.0__tar.gz → 2.0.1__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 (35) hide show
  1. learningmachine-2.0.1/LICENSE +32 -0
  2. {learningmachine-1.1.0 → learningmachine-2.0.1}/PKG-INFO +1 -1
  3. learningmachine-2.0.1/README.md +54 -0
  4. {learningmachine-1.1.0 → learningmachine-2.0.1}/learningmachine/base.py +75 -14
  5. learningmachine-2.0.1/learningmachine/classifier.py +140 -0
  6. learningmachine-2.0.1/learningmachine/regression.py +109 -0
  7. {learningmachine-1.1.0 → learningmachine-2.0.1}/learningmachine/utils.py +22 -1
  8. {learningmachine-1.1.0 → learningmachine-2.0.1}/learningmachine.egg-info/PKG-INFO +1 -1
  9. {learningmachine-1.1.0 → learningmachine-2.0.1}/learningmachine.egg-info/SOURCES.txt +1 -1
  10. learningmachine-2.0.1/setup.py +154 -0
  11. learningmachine-1.1.0/LICENSE +0 -32
  12. learningmachine-1.1.0/README.rst +0 -37
  13. learningmachine-1.1.0/learningmachine/classifier.py +0 -134
  14. learningmachine-1.1.0/learningmachine/regression.py +0 -92
  15. learningmachine-1.1.0/setup.py +0 -220
  16. {learningmachine-1.1.0 → learningmachine-2.0.1}/CONTRIBUTING.rst +0 -0
  17. {learningmachine-1.1.0 → learningmachine-2.0.1}/HISTORY.rst +0 -0
  18. {learningmachine-1.1.0 → learningmachine-2.0.1}/MANIFEST.in +0 -0
  19. {learningmachine-1.1.0 → learningmachine-2.0.1}/docs/Makefile +0 -0
  20. {learningmachine-1.1.0 → learningmachine-2.0.1}/docs/conf.py +0 -0
  21. {learningmachine-1.1.0 → learningmachine-2.0.1}/docs/contributing.rst +0 -0
  22. {learningmachine-1.1.0 → learningmachine-2.0.1}/docs/history.rst +0 -0
  23. {learningmachine-1.1.0 → learningmachine-2.0.1}/docs/index.rst +0 -0
  24. {learningmachine-1.1.0 → learningmachine-2.0.1}/docs/installation.rst +0 -0
  25. {learningmachine-1.1.0 → learningmachine-2.0.1}/docs/make.bat +0 -0
  26. {learningmachine-1.1.0 → learningmachine-2.0.1}/docs/readme.rst +0 -0
  27. {learningmachine-1.1.0 → learningmachine-2.0.1}/docs/usage.rst +0 -0
  28. {learningmachine-1.1.0 → learningmachine-2.0.1}/learningmachine/__init__.py +0 -0
  29. {learningmachine-1.1.0 → learningmachine-2.0.1}/learningmachine.egg-info/dependency_links.txt +0 -0
  30. {learningmachine-1.1.0 → learningmachine-2.0.1}/learningmachine.egg-info/not-zip-safe +0 -0
  31. {learningmachine-1.1.0 → learningmachine-2.0.1}/learningmachine.egg-info/requires.txt +0 -0
  32. {learningmachine-1.1.0 → learningmachine-2.0.1}/learningmachine.egg-info/top_level.txt +0 -0
  33. {learningmachine-1.1.0 → learningmachine-2.0.1}/setup.cfg +0 -0
  34. {learningmachine-1.1.0 → learningmachine-2.0.1}/tests/__init__.py +0 -0
  35. {learningmachine-1.1.0 → learningmachine-2.0.1}/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.0
3
+ Version: 2.0.1
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
@@ -88,22 +92,18 @@ class Base(BaseEstimator):
88
92
 
89
93
  try:
90
94
  base.library(StrVector(["learningmachine"]))
91
- except (
92
- NotImplementedError
93
- ) as e1: # can't load the package from the global environment
95
+ except: # can't load the package from the global environment
94
96
  try:
95
97
  base.library(
96
98
  StrVector(["learningmachine"]),
97
99
  lib_loc="learningmachine_r",
98
100
  )
99
- except NotImplementedError as e2: # well, we tried
101
+ except: # well, we tried
100
102
  try:
101
- r("try(library('learningmachine'), silence=FALSE)")
102
- except (
103
- NotImplementedError
104
- ) as e3: # well, we tried everything at this point
103
+ r("try(suppressWarnings(suppressMessages(library('learningmachine'))), silence=TRUE)")
104
+ except: # well, we tried everything at this point
105
105
  r(
106
- "try(library('learningmachine', lib.loc='learningmachine_r'), silence=FALSE)"
106
+ "try(suppressWarnings(suppressMessages(library('learningmachine', lib.loc='learningmachine_r'))), silence=TRUE)"
107
107
  )
108
108
 
109
109
  def score(self, X, y, scoring=None, **kwargs):
@@ -176,7 +176,7 @@ class Base(BaseEstimator):
176
176
  try:
177
177
  preds = preds.ravel().astype(int)
178
178
  return scoring_options[scoring](y, preds, **kwargs)
179
- except:
179
+ except TypeError:
180
180
  return scoring_options[scoring](y, preds, **kwargs)
181
181
 
182
182
  if self.type == "regression":
@@ -211,3 +211,64 @@ class Base(BaseEstimator):
211
211
  }
212
212
 
213
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,140 @@
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
+ 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)})")
57
+ except NotImplementedError:
58
+ self.obj = r(
59
+ 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)})"
60
+ )
61
+
62
+ # try:
63
+ # self.load_learningmachine()
64
+ # self.obj = r(
65
+ # 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)})"
66
+ # )
67
+ # except NotImplementedError as e:
68
+ # try:
69
+ # base.suppressWarnings(base.suppressMessages(r.library("learningmachine")))
70
+ # self.obj = r(
71
+ # 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)})"
72
+ # )
73
+ # except NotImplementedError as e:
74
+ # try:
75
+ # self.obj = r(
76
+ # f"""
77
+ # suppressWarnings(suppressMessages(library(learningmachine)));
78
+ # 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)})
79
+ # """
80
+ # )
81
+ # except NotImplementedError as e:
82
+ # print("R package can't be loaded: ", e)
83
+
84
+ def fit(self, X, y, **kwargs):
85
+ """
86
+ Fit the model according to the given training data.
87
+ """
88
+ params_dict = {}
89
+ for k, v in kwargs.items():
90
+ params_dict[k.replace('_', '.')] = v
91
+ self.obj["fit"](r.matrix(FloatVector(X.ravel()),
92
+ byrow=True,
93
+ ncol=X.shape[1],
94
+ nrow=X.shape[0]),
95
+ FactorVector(IntVector(y)),
96
+ **params_dict)
97
+ self.classes_ = np.unique(y) # /!\ do not remove
98
+ return self
99
+
100
+ def predict_proba(self, X):
101
+ """
102
+ Predict using the model.
103
+ """
104
+ if self.pi_method == "none":
105
+ res = self.obj["predict_proba"](
106
+ r.matrix(FloatVector(X.ravel()),
107
+ byrow=True,
108
+ ncol=X.shape[1],
109
+ nrow=X.shape[0])
110
+ )
111
+ return np.asarray(res)
112
+ return r_list_to_namedtuple(self.obj["predict_proba"](
113
+ r.matrix(FloatVector(X.ravel()),
114
+ byrow=True,
115
+ ncol=X.shape[1],
116
+ nrow=X.shape[0])
117
+ ))
118
+
119
+ def predict(self, X):
120
+ """
121
+ Predict using the model.
122
+ """
123
+ if self.pi_method == "none":
124
+ return (
125
+ np.asarray(
126
+ self.obj["predict"](
127
+ r.matrix(FloatVector(X.ravel()),
128
+ byrow=True,
129
+ ncol=X.shape[1],
130
+ nrow=X.shape[0])
131
+ )
132
+ ) - 1
133
+ )
134
+ return r_list_to_namedtuple(self.obj["predict"](
135
+ r.matrix(FloatVector(X.ravel()),
136
+ byrow=True,
137
+ ncol=X.shape[1],
138
+ nrow=X.shape[0])
139
+ ))
140
+
@@ -0,0 +1,109 @@
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
+ 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)})")
48
+ except NotImplementedError:
49
+ self.obj = r(
50
+ 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)})"
51
+ )
52
+
53
+ # try:
54
+ # self.load_learningmachine()
55
+ # self.obj = r(
56
+ # 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)})"
57
+ # )
58
+ # except NotImplementedError as e:
59
+ # try:
60
+ # base.suppressWarnings(base.suppressMessages(r.library("learningmachine")))
61
+ # self.obj = r(
62
+ # f"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)})"
63
+ # )
64
+ # except NotImplementedError as e:
65
+ # try:
66
+ # self.obj = r(
67
+ # f"""
68
+ # suppressWarnings(suppressMessages(library(learningmachine)));
69
+ # 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)})
70
+ # """
71
+ # )
72
+ # except NotImplementedError as e:
73
+ # print("R package can't be loaded: ", e)
74
+
75
+ def fit(self, X, y, **kwargs):
76
+ """
77
+ Fit the model according to the given training data.
78
+ """
79
+ params_dict = {}
80
+ for k, v in kwargs.items():
81
+ params_dict[k.replace('_', '.')] = v
82
+ self.obj["fit"](
83
+ r.matrix(FloatVector(X.ravel()),
84
+ byrow=True,
85
+ ncol=X.shape[1],
86
+ nrow=X.shape[0]),
87
+ FloatVector(y),
88
+ **params_dict
89
+ )
90
+ return self
91
+
92
+ def predict(self, X):
93
+ """
94
+ Predict using the model.
95
+ """
96
+ if self.pi_method == "none":
97
+ return(np.asarray(self.obj["predict"](
98
+ r.matrix(FloatVector(X.ravel()),
99
+ byrow=True,
100
+ ncol=X.shape[1],
101
+ nrow=X.shape[0])
102
+ )))
103
+ return r_list_to_namedtuple(self.obj["predict"](
104
+ r.matrix(FloatVector(X.ravel()),
105
+ byrow=True,
106
+ ncol=X.shape[1],
107
+ nrow=X.shape[0])
108
+ ))
109
+
@@ -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.0
3
+ Version: 2.0.1
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
@@ -0,0 +1,154 @@
1
+ import platform
2
+ import subprocess
3
+
4
+ def check_r_installed():
5
+ current_platform = platform.system()
6
+
7
+ if current_platform == "Windows":
8
+ # Check if R is installed on Windows by checking the registry
9
+ try:
10
+ subprocess.run(
11
+ ["reg", "query", "HKLM\\Software\\R-core\\R"], check=True
12
+ )
13
+ print("R is already installed on Windows.")
14
+ return True
15
+ except subprocess.CalledProcessError:
16
+ print("R is not installed on Windows.")
17
+ return False
18
+
19
+ elif current_platform == "Linux":
20
+ # Check if R is installed on Linux by checking if the 'R' executable is available
21
+ try:
22
+ subprocess.run(["which", "R"], check=True)
23
+ print("R is already installed on Linux.")
24
+ return True
25
+ except subprocess.CalledProcessError:
26
+ print("R is not installed on Linux.")
27
+ return False
28
+
29
+ elif current_platform == "Darwin": # macOS
30
+ # Check if R is installed on macOS by checking if the 'R' executable is available
31
+ try:
32
+ subprocess.run(["which", "R"], check=True)
33
+ print("R is already installed on macOS.")
34
+ return True
35
+ except subprocess.CalledProcessError:
36
+ print("R is not installed on macOS.")
37
+ return False
38
+
39
+ else:
40
+ print("Unsupported platform. Unable to check for R installation.")
41
+ return False
42
+
43
+ def install_r():
44
+
45
+ current_platform = platform.system()
46
+
47
+ if current_platform == "Windows":
48
+ # Install R on Windows using PowerShell
49
+ install_command = "Start-Process powershell -Verb subprocess.runAs -ArgumentList '-Command \"& {Invoke-WebRequest https://cran.r-project.org/bin/windows/base/R-4.1.2-win.exe -OutFile R.exe}; Start-Process R.exe -ArgumentList '/SILENT' -Wait}'"
50
+ subprocess.run(install_command, shell=True)
51
+
52
+ elif current_platform == "Linux":
53
+ # Install R on Linux using the appropriate package manager (e.g., apt-get)
54
+ install_command = (
55
+ "sudo apt update -qq && sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9"
56
+ + "&& sudo add-apt-repository 'deb https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/'"
57
+ + "&& sudo apt update"
58
+ + "&& sudo apt -y install r-base"
59
+ )
60
+ subprocess.run(install_command, shell=True)
61
+
62
+ elif current_platform == "Darwin": # macOS
63
+ # Install R on macOS using Homebrew
64
+ install_command = "brew install r"
65
+ subprocess.run(install_command, shell=True)
66
+
67
+ else:
68
+
69
+ print("Unsupported platform. Unable to install R.")
70
+
71
+ def install_packages():
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", "utils::install.packages('learningmachine', repos='https://techtonique.r-universe.dev', dependencies=TRUE)"])
76
+ subprocess.run(["Rscript", "-e", "remotes::install_github('Techtonique/learningmachine')"])
77
+ except:
78
+ try:
79
+ subprocess.run(["mkdir", "-p", "r-learningmachine"])
80
+ subprocess.run(["Rscript", "-e", "utils::install.packages('remotes', lib='r-learningmachine', dependencies=TRUE)"])
81
+ subprocess.run(["Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), lib='r-learningmachine', dependencies=TRUE)"])
82
+ #subprocess.run(["Rscript", "-e", "utils::install.packages('learningmachine', repos='https://techtonique.r-universe.dev', lib='r-learningmachine', dependencies=TRUE)"])
83
+ subprocess.run(["Rscript", "-e", "remotes::install_github('Techtonique/learningmachine', lib='r-learningmachine')"])
84
+ except:
85
+ try:
86
+ subprocess.run(["Rscript", "-e", "utils::install.packages('remotes', dependencies=TRUE)"])
87
+ subprocess.run(["Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), dependencies=TRUE)"])
88
+ #subprocess.run(["Rscript", "-e", "utils::install.packages('learningmachine', repos='https://techtonique.r-universe.dev', dependencies=TRUE)"])
89
+ subprocess.run(["Rscript", "-e", "remotes::install_github('Techtonique/learningmachine')"])
90
+ except:
91
+ try:
92
+ subprocess.run(["mkdir", "-p", "r-learningmachine"])
93
+ subprocess.run(["Rscript", "-e", "utils::install.packages('remotes', lib='r-learningmachine', dependencies=TRUE)"])
94
+ subprocess.run(["Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), lib='r-learningmachine', dependencies=TRUE)"])
95
+ #subprocess.run(["Rscript", "-e", "utils::install.packages('learningmachine', repos='https://techtonique.r-universe.dev', lib='r-learningmachine', dependencies=TRUE)"])
96
+ subprocess.run(["Rscript", "-e", "remotes::install_github('Techtonique/learningmachine', lib='r-learningmachine')"])
97
+ except:
98
+ try:
99
+ subprocess.run(["Rscript", "-e", "utils::install.packages('remotes', dependencies=TRUE)"])
100
+ subprocess.run(["Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), dependencies=TRUE)"])
101
+ subprocess.run(["Rscript", "-e", "remotes::install_github('Techtonique/learningmachine')"])
102
+ except:
103
+ subprocess.run(["mkdir", "-p", "r-learningmachine"])
104
+ subprocess.run(["Rscript", "-e", "utils::install.packages('remotes', lib='r-learningmachine', dependencies=TRUE)"])
105
+ subprocess.run(["Rscript", "-e", "utils::install.packages(c('R6', 'Rcpp', 'skimr'), lib='r-learningmachine', dependencies=TRUE)"])
106
+ subprocess.run(["Rscript", "-e", "remotes::install_github('Techtonique/learningmachine', lib='r-learningmachine')"])
107
+
108
+
109
+ # Check if R is installed; if not, install it
110
+ if not check_r_installed():
111
+ print("Installing R...")
112
+ install_r()
113
+ else:
114
+ print("No installation needed.")
115
+
116
+ install_packages()
117
+
118
+ subprocess.run(["pip", "install", "rpy2"])
119
+
120
+ from setuptools import setup, find_packages
121
+ from codecs import open
122
+ from os import path
123
+
124
+ # 4 - Package setup -----------------------------------------------
125
+
126
+ """The setup script."""
127
+
128
+ setup(
129
+ author="T. Moudiki",
130
+ author_email="thierry.moudiki@gmail.com",
131
+ python_requires=">=3.6",
132
+ classifiers=[
133
+ "Development Status :: 2 - Pre-Alpha",
134
+ "Intended Audience :: Developers",
135
+ "License :: OSI Approved :: BSD License",
136
+ "Natural Language :: English",
137
+ "Programming Language :: Python :: 3",
138
+ "Programming Language :: Python :: 3.6",
139
+ "Programming Language :: Python :: 3.7",
140
+ "Programming Language :: Python :: 3.8",
141
+ ],
142
+ description="Machine Learning with uncertainty quantification and interpretability",
143
+ install_requires=['numpy', 'pandas', 'rpy2>=3.4.5', 'scikit-learn', 'scipy'],
144
+ license="BSD Clause Clear license",
145
+ long_description="Machine Learning with uncertainty quantification and interpretability.",
146
+ include_package_data=True,
147
+ keywords="learningmachine",
148
+ name="learningmachine",
149
+ packages=find_packages(include=["learningmachine", "learningmachine.*"]),
150
+ test_suite="tests",
151
+ url="https://github.com/Techtonique/learningmachine_python",
152
+ version="2.0.1",
153
+ zip_safe=False,
154
+ )
@@ -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
- )
@@ -1,220 +0,0 @@
1
- #!/usr/bin/env python
2
-
3
- import platform
4
- import subprocess
5
- from os import path
6
- from setuptools import setup, find_packages
7
-
8
- # 0 - utility functions -----------------------------------------------
9
-
10
- def check_r_installed():
11
- current_platform = platform.system()
12
-
13
- if current_platform == "Windows":
14
- # Check if R is installed on Windows by checking the registry
15
- try:
16
- subprocess.run(
17
- ["reg", "query", "HKLM\\Software\\R-core\\R"], check=True
18
- )
19
- print("R is already installed on Windows.")
20
- return True
21
- except subprocess.CalledProcessError as e:
22
- install_r(prompt=True)
23
- return True
24
-
25
- elif current_platform in ("Darwin", "Linux"):
26
- # Check if R is installed on Linux by checking if the 'R' executable is available
27
-
28
- try:
29
- # Try to find the 'R' executable using 'which' (if available)
30
- subprocess.check_call(['which', 'R'])
31
- print(f"R is already installed on {current_platform}.")
32
- return True
33
- except subprocess.CalledProcessError:
34
- # 'which' might not be available, or R is not installed
35
- print('R may not be installed.')
36
- install_r(prompt=True)
37
- return True
38
-
39
- else:
40
-
41
- print("Unsupported platform (check manually: https://cloud.r-project.org/)")
42
- return False
43
-
44
- def install_r(prompt=False):
45
-
46
- current_platform = platform.system()
47
-
48
- if prompt == True:
49
- print("Installing R...")
50
- # choice = input("Would you like to install R? (yes/no): ").strip().lower()
51
- # if choice == 'yes':
52
- # print("Installing R...")
53
- # elif choice == 'no':
54
- # print("No problem. R will not be installed.")
55
- # return
56
- # else:
57
- # print("Invalid input. Please enter 'yes' or 'no'.")
58
- # return
59
-
60
- if current_platform == "Windows":
61
- # Install R on Windows using PowerShell
62
- install_command = "Start-Process powershell -Verb runAs -ArgumentList '-Command \"& {Invoke-WebRequest https://cran.r-project.org/bin/windows/base/R-4.1.2-win.exe -OutFile R.exe}; Start-Process R.exe -ArgumentList '/SILENT' -Wait}'"
63
- subprocess.run(install_command, shell=True)
64
-
65
- elif current_platform == "Linux":
66
- # Install R on Linux using the appropriate package manager (e.g., apt-get)
67
- install_command = (
68
- "sudo apt update -qq && sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9"
69
- + "&& sudo add-apt-repository 'deb https://cloud.r-project.org/bin/linux/ubuntu focal-cran40/'"
70
- + "&& sudo apt update"
71
- + "&& sudo apt install r-base"
72
- )
73
- try:
74
- subprocess.run(install_command, shell=True)
75
- except NotImplementedError as e:
76
- print("Error installing R on this Linux distribution. Please check manually: https://cloud.r-project.org/")
77
-
78
- elif current_platform == "Darwin": # macOS
79
- # Install R on macOS using Homebrew
80
- install_command = "brew install r"
81
- try:
82
- subprocess.run(install_command, shell=True)
83
- except NotImplementedError as e:
84
- print("Error installing R on macOS. Please check manually: https://cloud.r-project.org/")
85
-
86
- else:
87
- print("Unsupported platform. Unable to install R.")
88
-
89
- def load_learningmachine():
90
- # Install R packages
91
- commands1_lm = 'base::system.file(package = "learningmachine")' # check "learningmachine" is installed
92
- commands2_lm = 'base::system.file("learningmachine_r", package = "learningmachine")' # check "learningmachine" is installed locally
93
- exec_commands1_lm = subprocess.run(
94
- ["Rscript", "-e", commands1_lm], capture_output=True, text=True
95
- )
96
- exec_commands2_lm = subprocess.run(
97
- ["Rscript", "-e", commands2_lm], capture_output=True, text=True
98
- )
99
- if (
100
- len(exec_commands1_lm.stdout) == 7
101
- and len(exec_commands2_lm.stdout) == 7
102
- ): # kind of convoluted, but works
103
- print("Installing R packages along with 'learningmachine'...")
104
- commands1 = [
105
- 'try(utils::install.packages(c("R6", "Rcpp", "skimr"), repos="https://cloud.r-project.org", dependencies = TRUE), silent=TRUE)',
106
- 'try(utils::install.packages("learningmachine", repos="https://techtonique.r-universe.dev", dependencies = TRUE), silent=TRUE)',
107
- ]
108
- commands2 = [
109
- 'try(utils::install.packages(c("R6", "Rcpp", "skimr"), lib="./learningmachine_r", repos="https://cloud.r-project.org", dependencies = TRUE), silent=TRUE)',
110
- 'try(utils::install.packages("learningmachine", lib="./learningmachine_r", repos="https://techtonique.r-universe.dev", dependencies = TRUE), silent=TRUE)',
111
- ]
112
- commands3 = [
113
- 'try(utils::install.packages(c("R6", "Rcpp", "remotes", "skimr"), repos="https://cloud.r-project.org", dependencies = TRUE), silent=TRUE)',
114
- 'try(remotes::install_github("Techtonique/learningmachine"), silent=TRUE)',
115
- ]
116
- commands4 = [
117
- 'try(utils::install.packages(c("R6", "Rcpp", "remotes", "skimr"), lib="./learningmachine_r", repos="https://cloud.r-project.org", dependencies = TRUE), silent=TRUE)',
118
- 'try(remotes::install_github("Techtonique/learningmachine", lib="./learningmachine_r", dependencies = TRUE), silent=TRUE)',
119
- ]
120
-
121
- try:
122
- for cmd in commands3:
123
- try:
124
- subprocess.run(["Rscript", "-e", cmd])
125
- except:
126
- pass
127
- except NotImplementedError as e: # can't install packages globally
128
- try:
129
- subprocess.run(["mkdir", "learningmachine_r"])
130
- for cmd in commands4:
131
- try:
132
- subprocess.run(["Rscript", "-e", cmd])
133
- except:
134
- pass
135
- except NotImplementedError as e:
136
- try:
137
- for cmd in commands1:
138
- try:
139
- subprocess.run(["Rscript", "-e", cmd])
140
- except:
141
- pass
142
- except NotImplementedError as e:
143
- subprocess.run(["mkdir", "learningmachine_r"])
144
- for cmd in commands2:
145
- try:
146
- subprocess.run(["Rscript", "-e", cmd])
147
- except:
148
- pass
149
-
150
- # try:
151
- # base.library(StrVector(["learningmachine"]))
152
- # except (
153
- # NotImplementedError
154
- # ) as e1: # can't load the package from the global environment
155
- # try:
156
- # base.library(
157
- # StrVector(["learningmachine"]), lib_loc="learningmachine_r"
158
- # )
159
- # except NotImplementedError as e2: # well, we tried
160
- # try:
161
- # r("try(library('learningmachine'), silence=TRUE)")
162
- # except (
163
- # NotImplementedError
164
- # ) as e3: # well, we tried everything at this point
165
- # r(
166
- # "try(library('learningmachine', lib.loc='learningmachine_r'), silence=TRUE)"
167
- # )
168
-
169
- # 1 - import Python packages -----------------------------------------------
170
-
171
- subprocess.run(["pip", "install", "rpy2"])
172
- try:
173
- subprocess.run(["pip", "install", "setuptools"])
174
- except ModuleNotFoundError as e:
175
- print("Error installing setuptools. Please install setuptools manually.")
176
-
177
- from rpy2.robjects.packages import importr
178
- from rpy2.robjects.vectors import StrVector
179
- from rpy2.robjects import r
180
-
181
- base = importr("base")
182
-
183
- if not check_r_installed():
184
- install_r()
185
- else:
186
- print("R is already installed.")
187
-
188
- load_learningmachine()
189
-
190
- # 4 - Package setup -----------------------------------------------
191
-
192
- """The setup script."""
193
-
194
- setup(
195
- author="T. Moudiki",
196
- author_email="thierry.moudiki@gmail.com",
197
- python_requires=">=3.6",
198
- classifiers=[
199
- "Development Status :: 2 - Pre-Alpha",
200
- "Intended Audience :: Developers",
201
- "License :: OSI Approved :: BSD License",
202
- "Natural Language :: English",
203
- "Programming Language :: Python :: 3",
204
- "Programming Language :: Python :: 3.6",
205
- "Programming Language :: Python :: 3.7",
206
- "Programming Language :: Python :: 3.8",
207
- ],
208
- description="Machine Learning with uncertainty quantification and interpretability",
209
- install_requires=['numpy', 'pandas', 'rpy2>=3.4.5', 'scikit-learn', 'scipy'],
210
- license="BSD Clause Clear license",
211
- long_description="Machine Learning with uncertainty quantification and interpretability.",
212
- include_package_data=True,
213
- keywords="learningmachine",
214
- name="learningmachine",
215
- packages=find_packages(include=["learningmachine", "learningmachine.*"]),
216
- test_suite="tests",
217
- url="https://github.com/Techtonique/learningmachine_python",
218
- version="1.1.0",
219
- zip_safe=False,
220
- )