Skip to content

Commit 86949f3

Browse files
bump v0.4.0
1 parent 8d08d3e commit 86949f3

File tree

7 files changed

+141
-16
lines changed

7 files changed

+141
-16
lines changed

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ tisthemachinelearner
33

44
<hr>
55

6-
Lightweight interface to scikit-learn with 2 classes, Classifier and Regressor.
6+
Lightweight interface to scikit-learn with 2 classes, `Classifier` and `Regressor.
77

8-
![PyPI](https://img.shields.io/pypi/v/tisthemachinelearner) [![PyPI - License](https://img.shields.io/pypi/l/tisthemachinelearner)](./LICENSE) [![Downloads](https://pepy.tech/badge/tisthemachinelearner)](https://pepy.tech/project/tisthemachinelearner)
9-
[![HitCount](https://hits.dwyl.com/Techtonique/tisthemachinelearner.svg?style=flat-square)](http://hits.dwyl.com/Techtonique/tisthemachinelearner)
8+
![PyPI](https://img.shields.io/pypi/v/tisthemachinelearner) [![PyPI - License](https://img.shields.io/pypi/l/tisthemachinelearner)](LICENSE) [![Downloads](https://pepy.tech/badge/tisthemachinelearner)](https://pepy.tech/project/tisthemachinelearner)
109
[![Documentation](https://img.shields.io/badge/documentation-is_here-green)](https://techtonique.github.io/tisthemachinelearner/)
1110

1211

examples/example.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,37 @@
2929
print(reg.predict(X_test))
3030
print(np.sqrt(np.mean((reg.predict(X_test) - y_test) ** 2)))
3131

32+
# custom
33+
34+
X, y = load_breast_cancer(return_X_y=True)
35+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
36+
37+
38+
clf = Classifier("LogisticRegression", custom=False, calibrate=False)
39+
clf.fit(X_train, y_train)
40+
print(clf.predict(X_test))
41+
print(clf.score(X_test, y_test))
42+
43+
clf = Classifier("LogisticRegression", custom=True, calibrate=False)
44+
clf.fit(X_train, y_train)
45+
print(clf.predict(X_test))
46+
print(clf.score(X_test, y_test))
47+
48+
clf = Classifier("LogisticRegression", custom=True, n_hidden_features=3, random_state=42, calibrate=False)
49+
clf.fit(X_train, y_train)
50+
print(clf.predict(X_test))
51+
print(clf.score(X_test, y_test))
52+
53+
X, y = load_diabetes(return_X_y=True)
54+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
55+
56+
reg = Regressor("RidgeCV", alphas=[0.01, 0.1, 1, 10], custom=True, n_hidden_features=3)
57+
reg.fit(X_train, y_train)
58+
print(reg.predict(X_test))
59+
print(np.sqrt(np.mean((reg.predict(X_test) - y_test) ** 2)))
60+
61+
reg = Regressor("RidgeCV", alphas=[0.01, 0.1, 1, 10], custom=True, n_hidden_features=10)
62+
reg.fit(X_train, y_train)
63+
print(reg.predict(X_test))
64+
print(np.sqrt(np.mean((reg.predict(X_test) - y_test) ** 2)))
65+

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
[project]
22
name = "tisthemachinelearner"
3-
version = "0.3.3"
4-
description = "git"
3+
version = "0.4.0"
4+
description = "Lightweight interface to scikit-learn, with 2 classes"
55
readme = "README.md"
66
requires-python = ">=3.8"
7-
dependencies = ["scikit-learn"]
7+
dependencies = ["scikit-learn", "nnetsauce"]
88

99
[build-system]
1010
requires = ["hatchling"]

src/tisthemachinelearner/base.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
1-
from sklearn.base import BaseEstimator, ClassifierMixin, RegressorMixin
21
import importlib
2+
import nnetsauce as ns
3+
from sklearn.base import BaseEstimator
34

45

56
class BaseModel(BaseEstimator):
67
"""
78
Base class for dynamically loading and wrapping scikit-learn models.
89
"""
9-
def __init__(self, base_model, **kwargs):
10+
# Custom parameters that should only be passed to nnetsauce models
11+
CUSTOM_PARAMS = [
12+
'n_hidden_features',
13+
'activation_name',
14+
'bias',
15+
'dropout',
16+
'direct_link',
17+
'n_clusters',
18+
'cluster_encode',
19+
'type_clust'
20+
]
21+
22+
def __init__(self, base_model, custom=False, **kwargs):
1023
"""
1124
Initialize a scikit-learn model dynamically.
1225
1326
Parameters:
1427
- base_model (str): The class name of the scikit-learn model (e.g., 'LogisticRegression').
15-
- **kwargs: Additional parameters to pass to the scikit-learn model constructor.
28+
- custom (bool): Whether the model is a custom nnetsauce model.
29+
- **kwargs: Additional parameters to pass to the model constructor.
1630
"""
1731
sklearn_modules = [
1832
"linear_model",
@@ -27,8 +41,16 @@ def __init__(self, base_model, **kwargs):
2741
"kernel_ridge",
2842
]
2943
self.base_model = base_model
30-
self.model_params = kwargs
31-
self.model = self._load_model(base_model, sklearn_modules)(**kwargs)
44+
self.custom = custom
45+
46+
# Split kwargs into base and custom parameters
47+
self.base_kwargs = {k: v for k, v in kwargs.items() if k not in self.CUSTOM_PARAMS}
48+
self.custom_kwargs = {k: v for k, v in kwargs.items() if k in self.CUSTOM_PARAMS}
49+
50+
# Initialize only the base model here
51+
self.model = self._load_model(base_model, sklearn_modules)(**self.base_kwargs)
52+
53+
# Custom model wrapping is handled in derived classes
3254

3355
def _load_model(self, base_model, modules):
3456
"""
@@ -57,7 +79,7 @@ def fit(self, X, y, **kwargs):
5779
Parameters:
5880
- X (array-like): Training data features.
5981
- y (array-like): Target values.
60-
- **kwargs: Additional parameters to pass to the scikit-learn model fit method.
82+
- **kwargs: Additional parameters to pass to the model fit method.
6183
"""
6284
self.model.fit(X, y, **kwargs)
6385
return self
@@ -68,7 +90,7 @@ def predict(self, X, **kwargs):
6890
6991
Parameters:
7092
- X (array-like): Input data.
71-
- **kwargs: Additional parameters to pass to the scikit-learn model predict method.
93+
- **kwargs: Additional parameters to pass to the model predict method.
7294
Returns:
7395
- array-like: Predictions.
7496
"""
@@ -81,7 +103,7 @@ def score(self, X, y, **kwargs):
81103
Parameters:
82104
- X (array-like): Test data features.
83105
- y (array-like): True labels.
84-
- **kwargs: Additional parameters to pass to the scikit-learn model score method.
106+
- **kwargs: Additional parameters to pass to the model score method.
85107
86108
Returns:
87109
- float: The score.

src/tisthemachinelearner/classifier.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import nnetsauce as ns
12
from .base import BaseModel
23
from sklearn.base import ClassifierMixin
4+
from .wrappedcalibratedclassifier import WrappedCalibratedClassifier
35

46
class Classifier(BaseModel, ClassifierMixin):
57
"""
@@ -29,4 +31,30 @@ class Classifier(BaseModel, ClassifierMixin):
2931
print(clf.score(X_test, y_test))
3032
```
3133
"""
32-
pass
34+
def __init__(self, base_model, custom=False, calibrate=False, **kwargs):
35+
super().__init__(base_model, custom, **kwargs)
36+
if self.custom:
37+
self.model = ns.CustomClassifier(self.model, **self.custom_kwargs)
38+
self.calibrate = calibrate
39+
if self.calibrate:
40+
raise NotImplementedError
41+
42+
def fit(self, X, y, **kwargs):
43+
"""Fit the model."""
44+
super().fit(X, y, **kwargs)
45+
if self.calibrate:
46+
self.model = WrappedCalibratedClassifier(self.model, method='sigmoid', cv='prefit')
47+
self.model.fit(X, y)
48+
return self
49+
50+
def predict_proba(self, X):
51+
"""
52+
Predict class probabilities for the input data.
53+
54+
Parameters:
55+
- X (array-like): Input data features.
56+
57+
Returns:
58+
- array-like: Predicted class probabilities.
59+
"""
60+
return self.model.predict_proba(X)

src/tisthemachinelearner/regressor.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import nnetsauce as ns
12
from .base import BaseModel
23
from sklearn.base import RegressorMixin
34

@@ -29,4 +30,14 @@ class Regressor(BaseModel, RegressorMixin):
2930
print(np.sqrt(np.mean((reg.predict(X_test) - y_test) ** 2)))
3031
```
3132
"""
32-
pass
33+
def __init__(self, base_model, custom=False, **kwargs):
34+
super().__init__(base_model, custom, **kwargs)
35+
if self.custom:
36+
self.model = ns.CustomRegressor(self.model, **self.custom_kwargs)
37+
38+
def fit(self, X, y, **kwargs):
39+
"""Fit the model."""
40+
super().fit(X, y, **kwargs)
41+
if self.custom:
42+
self.model.fit(X, y)
43+
return self
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from sklearn.base import BaseEstimator, ClassifierMixin
2+
from sklearn.calibration import CalibratedClassifierCV
3+
4+
class WrappedCalibratedClassifier(BaseEstimator, ClassifierMixin):
5+
def __init__(self, base_estimator, method='sigmoid', cv=5):
6+
self.base_estimator = base_estimator
7+
self.method = method
8+
self.cv = cv
9+
10+
def fit(self, X, y):
11+
self.calibrated_clf_ = CalibratedClassifierCV(
12+
estimator=self.base_estimator,
13+
method=self.method,
14+
cv=self.cv
15+
)
16+
self.calibrated_clf_.fit(X, y)
17+
return self
18+
19+
def predict(self, X):
20+
return self.calibrated_clf_.predict(X)
21+
22+
def predict_proba(self, X):
23+
return self.calibrated_clf_.predict_proba(X)
24+
25+
@property
26+
def classes_(self):
27+
return self.calibrated_clf_.classes_
28+
29+
@property
30+
def _estimator_type(self):
31+
return "classifier"

0 commit comments

Comments
 (0)