Expand source code
from copy import deepcopy
from typing import List
import numpy as np
from sklearn import datasets
from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.model_selection import cross_val_score, train_test_split
from sklearn.tree import DecisionTreeClassifier
from imodels.tree.hierarchical_shrinkage import HSTreeRegressor, HSTreeClassifier
from imodels.util.tree import compute_tree_complexity
class DecisionTreeCCPClassifier(ClassifierMixin, BaseEstimator):
def __init__(self, estimator_: BaseEstimator, desired_complexity: int = 1, complexity_measure='max_rules', *args,
**kwargs):
self.desired_complexity = desired_complexity
self.estimator_ = estimator_
self.complexity_measure = complexity_measure
def get_params(self, deep=True):
# defined explicitly because __init__ takes *args/**kwargs, which sklearn's
# automatic parameter introspection rejects
return {
"estimator_": self.estimator_,
"desired_complexity": self.desired_complexity,
"complexity_measure": self.complexity_measure,
}
def set_params(self, **params):
for key, value in params.items():
setattr(self, key, value)
return self
def _copy_fitted_attributes(self):
"""Mirror the wrapped estimator's fitted sklearn attributes onto self."""
for attr in ("classes_", "n_features_in_", "feature_names_in_"):
if hasattr(self.estimator_, attr):
setattr(self, attr, getattr(self.estimator_, attr))
def _get_alpha(self, X, y, sample_weight=None, *args, **kwargs):
path = self.estimator_.cost_complexity_pruning_path(
X, y, sample_weight=sample_weight)
ccp_alphas, impurities = path.ccp_alphas, path.impurities
complexities = {}
low = 0
high = len(ccp_alphas) - 1
cur = 0
while low <= high:
cur = (high + low) // 2
est_params = self.estimator_.get_params()
est_params['ccp_alpha'] = ccp_alphas[cur]
copied_estimator = deepcopy(self.estimator_).set_params(**est_params)
copied_estimator.fit(X, y, sample_weight=sample_weight)
if self._get_complexity(copied_estimator, self.complexity_measure) < self.desired_complexity:
high = cur - 1
elif self._get_complexity(copied_estimator, self.complexity_measure) > self.desired_complexity:
low = cur + 1
else:
break
self.alpha = ccp_alphas[cur]
# for alpha in ccp_alphas:
# est_params = self.estimator_.get_params()
# est_params['ccp_alpha'] = alpha
# copied_estimator = deepcopy(self.estimator_).set_params(**est_params)
# copied_estimator.fit(X, y)
# complexities[alpha] = self._get_complexity(copied_estimator,self.complexity_measure)
# closest_alpha, closest_leaves = min(complexities.items(), key=lambda x: abs(self.desired_complexity - x[1]))
# self.alpha = closest_alpha
def fit(self, X, y, sample_weight=None, *args, **kwargs):
params_for_fitting = self.estimator_.get_params()
self._get_alpha(X, y, sample_weight, *args, **kwargs)
params_for_fitting['ccp_alpha'] = self.alpha
self.estimator_.set_params(**params_for_fitting)
self.estimator_.fit(X, y, *args, sample_weight=sample_weight, **kwargs)
self._copy_fitted_attributes()
return self
def get_rules(self, feature_names=None):
"""Return this model's rules as a DataFrame (see imodels.get_rules)."""
from imodels.util.get_rules import get_rules
return get_rules(self, feature_names=feature_names)
def _get_complexity(self, BaseEstimator, complexity_measure):
return compute_tree_complexity(BaseEstimator.tree_, complexity_measure)
def predict_proba(self, X, *args, **kwargs):
if hasattr(self.estimator_, 'predict_proba'):
return self.estimator_.predict_proba(X, *args, **kwargs)
else:
return NotImplemented
def predict(self, X, *args, **kwargs):
return self.estimator_.predict(X, *args, **kwargs)
def score(self, X, y, *args, **kwargs):
if hasattr(self.estimator_, 'score'):
return self.estimator_.score(X, y, *args, **kwargs)
else:
return NotImplemented
class DecisionTreeCCPRegressor(BaseEstimator):
def __init__(self, estimator_: BaseEstimator, desired_complexity: int = 1, complexity_measure='max_rules', *args,
**kwargs):
self.desired_complexity = desired_complexity
self.estimator_ = estimator_
self.alpha = 0.0
self.complexity_measure = complexity_measure
def get_params(self, deep=True):
# defined explicitly because __init__ takes *args/**kwargs, which sklearn's
# automatic parameter introspection rejects
return {
"estimator_": self.estimator_,
"desired_complexity": self.desired_complexity,
"complexity_measure": self.complexity_measure,
}
def set_params(self, **params):
for key, value in params.items():
setattr(self, key, value)
return self
def _copy_fitted_attributes(self):
"""Mirror the wrapped estimator's fitted sklearn attributes onto self."""
for attr in ("n_features_in_", "feature_names_in_"):
if hasattr(self.estimator_, attr):
setattr(self, attr, getattr(self.estimator_, attr))
def _get_alpha(self, X, y, sample_weight=None):
path = self.estimator_.cost_complexity_pruning_path(
X, y, sample_weight=sample_weight)
ccp_alphas, impurities = path.ccp_alphas, path.impurities
complexities = {}
low = 0
high = len(ccp_alphas) - 1
cur = 0
while low <= high:
cur = (high + low) // 2
est_params = self.estimator_.get_params()
est_params['ccp_alpha'] = ccp_alphas[cur]
copied_estimator = deepcopy(self.estimator_).set_params(**est_params)
copied_estimator.fit(X, y, sample_weight=sample_weight)
if self._get_complexity(copied_estimator, self.complexity_measure) < self.desired_complexity:
high = cur - 1
elif self._get_complexity(copied_estimator, self.complexity_measure) > self.desired_complexity:
low = cur + 1
else:
break
self.alpha = ccp_alphas[cur]
# path = self.estimator_.cost_complexity_pruning_path(X,y)
# ccp_alphas, impurities = path.ccp_alphas, path.impurities
# complexities = {}
# for alpha in ccp_alphas:
# est_params = self.estimator_.get_params()
# est_params['ccp_alpha'] = alpha
# copied_estimator = deepcopy(self.estimator_).set_params(**est_params)
# copied_estimator.fit(X, y)
# complexities[alpha] = self._get_complexity(copied_estimator,self.complexity_measure)
# closest_alpha, closest_leaves = min(complexities.items(), key=lambda x: abs(self.desired_complexity - x[1]))
# self.alpha = closest_alpha
def fit(self, X, y, sample_weight=None):
params_for_fitting = self.estimator_.get_params()
self._get_alpha(X, y, sample_weight)
params_for_fitting['ccp_alpha'] = self.alpha
self.estimator_.set_params(**params_for_fitting)
self.estimator_.fit(X, y, sample_weight=sample_weight)
self._copy_fitted_attributes()
return self
def _get_complexity(self, BaseEstimator, complexity_measure):
return compute_tree_complexity(BaseEstimator.tree_, self.complexity_measure)
def predict(self, X, *args, **kwargs):
return self.estimator_.predict(X, *args, **kwargs)
def score(self, X, y, *args, **kwargs):
if hasattr(self.estimator_, 'score'):
return self.estimator_.score(X, y, *args, **kwargs)
else:
return NotImplemented
class HSDecisionTreeCCPRegressorCV(HSTreeRegressor):
def __init__(self, estimator_: BaseEstimator, reg_param_list: List[float] = [0.1, 1, 10, 50, 100, 500],
desired_complexity: int = 1, cv: int = 3, scoring=None, *args, **kwargs):
super().__init__(estimator_=estimator_, reg_param=None)
self.reg_param_list = np.array(reg_param_list)
self.cv = cv
self.scoring = scoring
self.desired_complexity = desired_complexity
def fit(self, X, y, sample_weight=None, *args, **kwargs):
m = DecisionTreeCCPRegressor(self.estimator_, desired_complexity=self.desired_complexity)
m.fit(X, y, sample_weight, *args, **kwargs)
self.scores_ = []
for reg_param in self.reg_param_list:
est = HSTreeRegressor(deepcopy(m.estimator_), reg_param)
cv_scores = cross_val_score(est, X, y, cv=self.cv, scoring=self.scoring)
self.scores_.append(np.mean(cv_scores))
self.reg_param = self.reg_param_list[np.argmax(self.scores_)]
return super().fit(X=X, y=y)
class HSDecisionTreeCCPClassifierCV(HSTreeClassifier):
def __init__(self, estimator_: BaseEstimator, reg_param_list: List[float] = [0.1, 1, 10, 50, 100, 500],
desired_complexity: int = 1, cv: int = 3, scoring=None, *args, **kwargs):
super().__init__(estimator_=estimator_, reg_param=None)
self.reg_param_list = np.array(reg_param_list)
self.cv = cv
self.scoring = scoring
self.desired_complexity = desired_complexity
def fit(self, X, y, sample_weight=None, *args, **kwargs):
m = DecisionTreeCCPClassifier(self.estimator_, desired_complexity=self.desired_complexity)
m.fit(X, y, sample_weight, *args, **kwargs)
self.scores_ = []
for reg_param in self.reg_param_list:
est = HSTreeClassifier(deepcopy(m.estimator_), reg_param)
cv_scores = cross_val_score(est, X, y, cv=self.cv, scoring=self.scoring)
self.scores_.append(np.mean(cv_scores))
self.reg_param = self.reg_param_list[np.argmax(self.scores_)]
return super().fit(X=X, y=y)
if __name__ == '__main__':
m = DecisionTreeCCPClassifier(estimator_=DecisionTreeClassifier(random_state=1), desired_complexity=10,
complexity_measure='max_leaf_nodes')
# X,y = make_friedman1() #For regression
X, y = datasets.load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.33, random_state=42)
m.fit(X_train, y_train)
m.predict(X_test)
print(m.score(X_test, y_test))
m = HSDecisionTreeCCPClassifierCV(estimator_=DecisionTreeClassifier(random_state=1), desired_complexity=10,
reg_param_list=[0.0, 0.1, 1.0, 5.0, 10.0, 25.0, 50.0, 100.0])
m.fit(X_train, y_train)
print(m.score(X_test, y_test))
Classes
class DecisionTreeCCPClassifier (estimator_: sklearn.base.BaseEstimator, desired_complexity: int = 1, complexity_measure='max_rules', *args, **kwargs)-
Mixin class for all classifiers in scikit-learn.
This mixin defines the following functionality:
- set estimator type to
"classifier"through theestimator_typetag; scoremethod that default to :func:~sklearn.metrics.accuracy_score.- enforce that
fitrequiresyto be passed through therequires_ytag, which is done by setting the classifier type tag.
Read more in the :ref:
User Guide <rolling_your_own_estimator>.Examples
>>> import numpy as np >>> from sklearn.base import BaseEstimator, ClassifierMixin >>> # Mixin classes should always be on the left-hand side for a correct MRO >>> class MyEstimator(ClassifierMixin, BaseEstimator): ... def __init__(self, *, param=1): ... self.param = param ... def fit(self, X, y=None): ... self.is_fitted_ = True ... return self ... def predict(self, X): ... return np.full(shape=X.shape[0], fill_value=self.param) >>> estimator = MyEstimator(param=1) >>> X = np.array([[1, 2], [2, 3], [3, 4]]) >>> y = np.array([1, 0, 1]) >>> estimator.fit(X, y).predict(X) array([1, 1, 1]) >>> estimator.score(X, y) 0.66...Expand source code
class DecisionTreeCCPClassifier(ClassifierMixin, BaseEstimator): def __init__(self, estimator_: BaseEstimator, desired_complexity: int = 1, complexity_measure='max_rules', *args, **kwargs): self.desired_complexity = desired_complexity self.estimator_ = estimator_ self.complexity_measure = complexity_measure def get_params(self, deep=True): # defined explicitly because __init__ takes *args/**kwargs, which sklearn's # automatic parameter introspection rejects return { "estimator_": self.estimator_, "desired_complexity": self.desired_complexity, "complexity_measure": self.complexity_measure, } def set_params(self, **params): for key, value in params.items(): setattr(self, key, value) return self def _copy_fitted_attributes(self): """Mirror the wrapped estimator's fitted sklearn attributes onto self.""" for attr in ("classes_", "n_features_in_", "feature_names_in_"): if hasattr(self.estimator_, attr): setattr(self, attr, getattr(self.estimator_, attr)) def _get_alpha(self, X, y, sample_weight=None, *args, **kwargs): path = self.estimator_.cost_complexity_pruning_path( X, y, sample_weight=sample_weight) ccp_alphas, impurities = path.ccp_alphas, path.impurities complexities = {} low = 0 high = len(ccp_alphas) - 1 cur = 0 while low <= high: cur = (high + low) // 2 est_params = self.estimator_.get_params() est_params['ccp_alpha'] = ccp_alphas[cur] copied_estimator = deepcopy(self.estimator_).set_params(**est_params) copied_estimator.fit(X, y, sample_weight=sample_weight) if self._get_complexity(copied_estimator, self.complexity_measure) < self.desired_complexity: high = cur - 1 elif self._get_complexity(copied_estimator, self.complexity_measure) > self.desired_complexity: low = cur + 1 else: break self.alpha = ccp_alphas[cur] # for alpha in ccp_alphas: # est_params = self.estimator_.get_params() # est_params['ccp_alpha'] = alpha # copied_estimator = deepcopy(self.estimator_).set_params(**est_params) # copied_estimator.fit(X, y) # complexities[alpha] = self._get_complexity(copied_estimator,self.complexity_measure) # closest_alpha, closest_leaves = min(complexities.items(), key=lambda x: abs(self.desired_complexity - x[1])) # self.alpha = closest_alpha def fit(self, X, y, sample_weight=None, *args, **kwargs): params_for_fitting = self.estimator_.get_params() self._get_alpha(X, y, sample_weight, *args, **kwargs) params_for_fitting['ccp_alpha'] = self.alpha self.estimator_.set_params(**params_for_fitting) self.estimator_.fit(X, y, *args, sample_weight=sample_weight, **kwargs) self._copy_fitted_attributes() return self def get_rules(self, feature_names=None): """Return this model's rules as a DataFrame (see imodels.get_rules).""" from imodels.util.get_rules import get_rules return get_rules(self, feature_names=feature_names) def _get_complexity(self, BaseEstimator, complexity_measure): return compute_tree_complexity(BaseEstimator.tree_, complexity_measure) def predict_proba(self, X, *args, **kwargs): if hasattr(self.estimator_, 'predict_proba'): return self.estimator_.predict_proba(X, *args, **kwargs) else: return NotImplemented def predict(self, X, *args, **kwargs): return self.estimator_.predict(X, *args, **kwargs) def score(self, X, y, *args, **kwargs): if hasattr(self.estimator_, 'score'): return self.estimator_.score(X, y, *args, **kwargs) else: return NotImplementedAncestors
- sklearn.base.ClassifierMixin
- sklearn.base.BaseEstimator
- sklearn.utils._repr_html.base.ReprHTMLMixin
- sklearn.utils._repr_html.base._HTMLDocumentationLinkMixin
- sklearn.utils._metadata_requests._MetadataRequester
Methods
def fit(self, X, y, sample_weight=None, *args, **kwargs)-
Expand source code
def fit(self, X, y, sample_weight=None, *args, **kwargs): params_for_fitting = self.estimator_.get_params() self._get_alpha(X, y, sample_weight, *args, **kwargs) params_for_fitting['ccp_alpha'] = self.alpha self.estimator_.set_params(**params_for_fitting) self.estimator_.fit(X, y, *args, sample_weight=sample_weight, **kwargs) self._copy_fitted_attributes() return self def get_params(self, deep=True)-
Get parameters for this estimator.
Parameters
deep:bool, default=True- If True, will return the parameters for this estimator and contained subobjects that are estimators.
Returns
params:dict- Parameter names mapped to their values.
Expand source code
def get_params(self, deep=True): # defined explicitly because __init__ takes *args/**kwargs, which sklearn's # automatic parameter introspection rejects return { "estimator_": self.estimator_, "desired_complexity": self.desired_complexity, "complexity_measure": self.complexity_measure, } def get_rules(self, feature_names=None)-
Return this model's rules as a DataFrame (see imodels.get_rules).
Expand source code
def get_rules(self, feature_names=None): """Return this model's rules as a DataFrame (see imodels.get_rules).""" from imodels.util.get_rules import get_rules return get_rules(self, feature_names=feature_names) def predict(self, X, *args, **kwargs)-
Expand source code
def predict(self, X, *args, **kwargs): return self.estimator_.predict(X, *args, **kwargs) def predict_proba(self, X, *args, **kwargs)-
Expand source code
def predict_proba(self, X, *args, **kwargs): if hasattr(self.estimator_, 'predict_proba'): return self.estimator_.predict_proba(X, *args, **kwargs) else: return NotImplemented def score(self, X, y, *args, **kwargs)-
Return :ref:
accuracy <accuracy_score>on provided data and labels.In multi-label classification, this is the subset accuracy which is a harsh metric since you require for each sample that each label set be correctly predicted.
Parameters
X:array-likeofshape (n_samples, n_features)- Test samples.
y:array-likeofshape (n_samples,)or(n_samples, n_outputs)- True labels for
X. sample_weight:array-likeofshape (n_samples,), default=None- Sample weights.
Returns
score:float- Mean accuracy of
self.predict(X)w.r.t.y.
Expand source code
def score(self, X, y, *args, **kwargs): if hasattr(self.estimator_, 'score'): return self.estimator_.score(X, y, *args, **kwargs) else: return NotImplemented def set_fit_request(self: DecisionTreeCCPClassifier, *, sample_weight: bool | str | None = '$UNCHANGED$') ‑> DecisionTreeCCPClassifier-
Configure whether metadata should be requested to be passed to the
fitmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a :term:
meta-estimatorand metadata routing is enabled withenable_metadata_routing=True(see :func:sklearn.set_config). Please check the :ref:User Guide <metadata_routing>on how the routing mechanism works.The options for each parameter are:
-
True: metadata is requested, and passed tofitif provided. The request is ignored if metadata is not provided. -
False: metadata is not requested and the meta-estimator will not pass it tofit. -
None: metadata is not requested, and the meta-estimator will raise an error if the user provides it. -
str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version: 1.3
Parameters
sample_weight:str, True, False,orNone, default=sklearn.utils.metadata_routing.UNCHANGED- Metadata routing for
sample_weightparameter infit.
Returns
self:object- The updated object.
Expand source code
def func(*args, **kw): """Updates the `_metadata_request` attribute of the consumer (`instance`) for the parameters provided as `**kw`. This docstring is overwritten below. See REQUESTER_DOC for expected functionality. """ if not _routing_enabled(): raise RuntimeError( "This method is only available when metadata routing is enabled." " You can enable it using" " sklearn.set_config(enable_metadata_routing=True)." ) if self.validate_keys and (set(kw) - set(self.keys)): raise TypeError( f"Unexpected args: {set(kw) - set(self.keys)} in {self.name}. " f"Accepted arguments are: {set(self.keys)}" ) # This makes it possible to use the decorated method as an unbound method, # for instance when monkeypatching. # https://github.com/scikit-learn/scikit-learn/issues/28632 if instance is None: _instance = args[0] args = args[1:] else: _instance = instance # Replicating python's behavior when positional args are given other than # `self`, and `self` is only allowed if this method is unbound. if args: raise TypeError( f"set_{self.name}_request() takes 0 positional argument but" f" {len(args)} were given" ) requests = _instance._get_metadata_request() method_metadata_request = getattr(requests, self.name) for prop, alias in kw.items(): if alias is not UNCHANGED: method_metadata_request.add_request(param=prop, alias=alias) _instance._metadata_request = requests return _instance -
def set_params(self, **params)-
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects (such as :class:
~sklearn.pipeline.Pipeline). The latter have parameters of the form<component>__<parameter>so that it's possible to update each component of a nested object.Parameters
**params:dict- Estimator parameters.
Returns
self:estimator instance- Estimator instance.
Expand source code
def set_params(self, **params): for key, value in params.items(): setattr(self, key, value) return self
- set estimator type to
class DecisionTreeCCPRegressor (estimator_: sklearn.base.BaseEstimator, desired_complexity: int = 1, complexity_measure='max_rules', *args, **kwargs)-
Base class for all estimators in scikit-learn.
Inheriting from this class provides default implementations of:
- setting and getting parameters used by
GridSearchCVand friends; - textual and HTML representation displayed in terminals and IDEs;
- estimator serialization;
- parameters validation;
- data validation;
- feature names validation.
Read more in the :ref:
User Guide <rolling_your_own_estimator>.Notes
All estimators should specify all the parameters that can be set at the class level in their
__init__as explicit keyword arguments (no*argsor**kwargs).Examples
>>> import numpy as np >>> from sklearn.base import BaseEstimator >>> class MyEstimator(BaseEstimator): ... def __init__(self, *, param=1): ... self.param = param ... def fit(self, X, y=None): ... self.is_fitted_ = True ... return self ... def predict(self, X): ... return np.full(shape=X.shape[0], fill_value=self.param) >>> estimator = MyEstimator(param=2) >>> estimator.get_params() {'param': 2} >>> X = np.array([[1, 2], [2, 3], [3, 4]]) >>> y = np.array([1, 0, 1]) >>> estimator.fit(X, y).predict(X) array([2, 2, 2]) >>> estimator.set_params(param=3).fit(X, y).predict(X) array([3, 3, 3])Expand source code
class DecisionTreeCCPRegressor(BaseEstimator): def __init__(self, estimator_: BaseEstimator, desired_complexity: int = 1, complexity_measure='max_rules', *args, **kwargs): self.desired_complexity = desired_complexity self.estimator_ = estimator_ self.alpha = 0.0 self.complexity_measure = complexity_measure def get_params(self, deep=True): # defined explicitly because __init__ takes *args/**kwargs, which sklearn's # automatic parameter introspection rejects return { "estimator_": self.estimator_, "desired_complexity": self.desired_complexity, "complexity_measure": self.complexity_measure, } def set_params(self, **params): for key, value in params.items(): setattr(self, key, value) return self def _copy_fitted_attributes(self): """Mirror the wrapped estimator's fitted sklearn attributes onto self.""" for attr in ("n_features_in_", "feature_names_in_"): if hasattr(self.estimator_, attr): setattr(self, attr, getattr(self.estimator_, attr)) def _get_alpha(self, X, y, sample_weight=None): path = self.estimator_.cost_complexity_pruning_path( X, y, sample_weight=sample_weight) ccp_alphas, impurities = path.ccp_alphas, path.impurities complexities = {} low = 0 high = len(ccp_alphas) - 1 cur = 0 while low <= high: cur = (high + low) // 2 est_params = self.estimator_.get_params() est_params['ccp_alpha'] = ccp_alphas[cur] copied_estimator = deepcopy(self.estimator_).set_params(**est_params) copied_estimator.fit(X, y, sample_weight=sample_weight) if self._get_complexity(copied_estimator, self.complexity_measure) < self.desired_complexity: high = cur - 1 elif self._get_complexity(copied_estimator, self.complexity_measure) > self.desired_complexity: low = cur + 1 else: break self.alpha = ccp_alphas[cur] # path = self.estimator_.cost_complexity_pruning_path(X,y) # ccp_alphas, impurities = path.ccp_alphas, path.impurities # complexities = {} # for alpha in ccp_alphas: # est_params = self.estimator_.get_params() # est_params['ccp_alpha'] = alpha # copied_estimator = deepcopy(self.estimator_).set_params(**est_params) # copied_estimator.fit(X, y) # complexities[alpha] = self._get_complexity(copied_estimator,self.complexity_measure) # closest_alpha, closest_leaves = min(complexities.items(), key=lambda x: abs(self.desired_complexity - x[1])) # self.alpha = closest_alpha def fit(self, X, y, sample_weight=None): params_for_fitting = self.estimator_.get_params() self._get_alpha(X, y, sample_weight) params_for_fitting['ccp_alpha'] = self.alpha self.estimator_.set_params(**params_for_fitting) self.estimator_.fit(X, y, sample_weight=sample_weight) self._copy_fitted_attributes() return self def _get_complexity(self, BaseEstimator, complexity_measure): return compute_tree_complexity(BaseEstimator.tree_, self.complexity_measure) def predict(self, X, *args, **kwargs): return self.estimator_.predict(X, *args, **kwargs) def score(self, X, y, *args, **kwargs): if hasattr(self.estimator_, 'score'): return self.estimator_.score(X, y, *args, **kwargs) else: return NotImplementedAncestors
- sklearn.base.BaseEstimator
- sklearn.utils._repr_html.base.ReprHTMLMixin
- sklearn.utils._repr_html.base._HTMLDocumentationLinkMixin
- sklearn.utils._metadata_requests._MetadataRequester
Methods
def fit(self, X, y, sample_weight=None)-
Expand source code
def fit(self, X, y, sample_weight=None): params_for_fitting = self.estimator_.get_params() self._get_alpha(X, y, sample_weight) params_for_fitting['ccp_alpha'] = self.alpha self.estimator_.set_params(**params_for_fitting) self.estimator_.fit(X, y, sample_weight=sample_weight) self._copy_fitted_attributes() return self def get_params(self, deep=True)-
Get parameters for this estimator.
Parameters
deep:bool, default=True- If True, will return the parameters for this estimator and contained subobjects that are estimators.
Returns
params:dict- Parameter names mapped to their values.
Expand source code
def get_params(self, deep=True): # defined explicitly because __init__ takes *args/**kwargs, which sklearn's # automatic parameter introspection rejects return { "estimator_": self.estimator_, "desired_complexity": self.desired_complexity, "complexity_measure": self.complexity_measure, } def predict(self, X, *args, **kwargs)-
Expand source code
def predict(self, X, *args, **kwargs): return self.estimator_.predict(X, *args, **kwargs) def score(self, X, y, *args, **kwargs)-
Expand source code
def score(self, X, y, *args, **kwargs): if hasattr(self.estimator_, 'score'): return self.estimator_.score(X, y, *args, **kwargs) else: return NotImplemented def set_fit_request(self: DecisionTreeCCPRegressor, *, sample_weight: bool | str | None = '$UNCHANGED$') ‑> DecisionTreeCCPRegressor-
Configure whether metadata should be requested to be passed to the
fitmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a :term:
meta-estimatorand metadata routing is enabled withenable_metadata_routing=True(see :func:sklearn.set_config). Please check the :ref:User Guide <metadata_routing>on how the routing mechanism works.The options for each parameter are:
-
True: metadata is requested, and passed tofitif provided. The request is ignored if metadata is not provided. -
False: metadata is not requested and the meta-estimator will not pass it tofit. -
None: metadata is not requested, and the meta-estimator will raise an error if the user provides it. -
str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version: 1.3
Parameters
sample_weight:str, True, False,orNone, default=sklearn.utils.metadata_routing.UNCHANGED- Metadata routing for
sample_weightparameter infit.
Returns
self:object- The updated object.
Expand source code
def func(*args, **kw): """Updates the `_metadata_request` attribute of the consumer (`instance`) for the parameters provided as `**kw`. This docstring is overwritten below. See REQUESTER_DOC for expected functionality. """ if not _routing_enabled(): raise RuntimeError( "This method is only available when metadata routing is enabled." " You can enable it using" " sklearn.set_config(enable_metadata_routing=True)." ) if self.validate_keys and (set(kw) - set(self.keys)): raise TypeError( f"Unexpected args: {set(kw) - set(self.keys)} in {self.name}. " f"Accepted arguments are: {set(self.keys)}" ) # This makes it possible to use the decorated method as an unbound method, # for instance when monkeypatching. # https://github.com/scikit-learn/scikit-learn/issues/28632 if instance is None: _instance = args[0] args = args[1:] else: _instance = instance # Replicating python's behavior when positional args are given other than # `self`, and `self` is only allowed if this method is unbound. if args: raise TypeError( f"set_{self.name}_request() takes 0 positional argument but" f" {len(args)} were given" ) requests = _instance._get_metadata_request() method_metadata_request = getattr(requests, self.name) for prop, alias in kw.items(): if alias is not UNCHANGED: method_metadata_request.add_request(param=prop, alias=alias) _instance._metadata_request = requests return _instance -
def set_params(self, **params)-
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects (such as :class:
~sklearn.pipeline.Pipeline). The latter have parameters of the form<component>__<parameter>so that it's possible to update each component of a nested object.Parameters
**params:dict- Estimator parameters.
Returns
self:estimator instance- Estimator instance.
Expand source code
def set_params(self, **params): for key, value in params.items(): setattr(self, key, value) return self
- setting and getting parameters used by
class HSDecisionTreeCCPClassifierCV (estimator_: sklearn.base.BaseEstimator, reg_param_list: List[float] = [0.1, 1, 10, 50, 100, 500], desired_complexity: int = 1, cv: int = 3, scoring=None, *args, **kwargs)-
Mixin class for all classifiers in scikit-learn.
This mixin defines the following functionality:
- set estimator type to
"classifier"through theestimator_typetag; scoremethod that default to :func:~sklearn.metrics.accuracy_score.- enforce that
fitrequiresyto be passed through therequires_ytag, which is done by setting the classifier type tag.
Read more in the :ref:
User Guide <rolling_your_own_estimator>.Examples
>>> import numpy as np >>> from sklearn.base import BaseEstimator, ClassifierMixin >>> # Mixin classes should always be on the left-hand side for a correct MRO >>> class MyEstimator(ClassifierMixin, BaseEstimator): ... def __init__(self, *, param=1): ... self.param = param ... def fit(self, X, y=None): ... self.is_fitted_ = True ... return self ... def predict(self, X): ... return np.full(shape=X.shape[0], fill_value=self.param) >>> estimator = MyEstimator(param=1) >>> X = np.array([[1, 2], [2, 3], [3, 4]]) >>> y = np.array([1, 0, 1]) >>> estimator.fit(X, y).predict(X) array([1, 1, 1]) >>> estimator.score(X, y) 0.66...Expand source code
class HSDecisionTreeCCPClassifierCV(HSTreeClassifier): def __init__(self, estimator_: BaseEstimator, reg_param_list: List[float] = [0.1, 1, 10, 50, 100, 500], desired_complexity: int = 1, cv: int = 3, scoring=None, *args, **kwargs): super().__init__(estimator_=estimator_, reg_param=None) self.reg_param_list = np.array(reg_param_list) self.cv = cv self.scoring = scoring self.desired_complexity = desired_complexity def fit(self, X, y, sample_weight=None, *args, **kwargs): m = DecisionTreeCCPClassifier(self.estimator_, desired_complexity=self.desired_complexity) m.fit(X, y, sample_weight, *args, **kwargs) self.scores_ = [] for reg_param in self.reg_param_list: est = HSTreeClassifier(deepcopy(m.estimator_), reg_param) cv_scores = cross_val_score(est, X, y, cv=self.cv, scoring=self.scoring) self.scores_.append(np.mean(cv_scores)) self.reg_param = self.reg_param_list[np.argmax(self.scores_)] return super().fit(X=X, y=y)Ancestors
- HSTreeClassifier
- sklearn.base.ClassifierMixin
- HSTree
- sklearn.base.BaseEstimator
- sklearn.utils._repr_html.base.ReprHTMLMixin
- sklearn.utils._repr_html.base._HTMLDocumentationLinkMixin
- sklearn.utils._metadata_requests._MetadataRequester
Methods
def fit(self, X, y, sample_weight=None, *args, **kwargs)-
Expand source code
def fit(self, X, y, sample_weight=None, *args, **kwargs): m = DecisionTreeCCPClassifier(self.estimator_, desired_complexity=self.desired_complexity) m.fit(X, y, sample_weight, *args, **kwargs) self.scores_ = [] for reg_param in self.reg_param_list: est = HSTreeClassifier(deepcopy(m.estimator_), reg_param) cv_scores = cross_val_score(est, X, y, cv=self.cv, scoring=self.scoring) self.scores_.append(np.mean(cv_scores)) self.reg_param = self.reg_param_list[np.argmax(self.scores_)] return super().fit(X=X, y=y)
Inherited members
- set estimator type to
class HSDecisionTreeCCPRegressorCV (estimator_: sklearn.base.BaseEstimator, reg_param_list: List[float] = [0.1, 1, 10, 50, 100, 500], desired_complexity: int = 1, cv: int = 3, scoring=None, *args, **kwargs)-
Mixin class for all regression estimators in scikit-learn.
This mixin defines the following functionality:
- set estimator type to
"regressor"through theestimator_typetag; scoremethod that default to :func:~sklearn.metrics.r2_score.- enforce that
fitrequiresyto be passed through therequires_ytag, which is done by setting the regressor type tag.
Read more in the :ref:
User Guide <rolling_your_own_estimator>.Examples
>>> import numpy as np >>> from sklearn.base import BaseEstimator, RegressorMixin >>> # Mixin classes should always be on the left-hand side for a correct MRO >>> class MyEstimator(RegressorMixin, BaseEstimator): ... def __init__(self, *, param=1): ... self.param = param ... def fit(self, X, y=None): ... self.is_fitted_ = True ... return self ... def predict(self, X): ... return np.full(shape=X.shape[0], fill_value=self.param) >>> estimator = MyEstimator(param=0) >>> X = np.array([[1, 2], [2, 3], [3, 4]]) >>> y = np.array([-1, 0, 1]) >>> estimator.fit(X, y).predict(X) array([0, 0, 0]) >>> estimator.score(X, y) 0.0Expand source code
class HSDecisionTreeCCPRegressorCV(HSTreeRegressor): def __init__(self, estimator_: BaseEstimator, reg_param_list: List[float] = [0.1, 1, 10, 50, 100, 500], desired_complexity: int = 1, cv: int = 3, scoring=None, *args, **kwargs): super().__init__(estimator_=estimator_, reg_param=None) self.reg_param_list = np.array(reg_param_list) self.cv = cv self.scoring = scoring self.desired_complexity = desired_complexity def fit(self, X, y, sample_weight=None, *args, **kwargs): m = DecisionTreeCCPRegressor(self.estimator_, desired_complexity=self.desired_complexity) m.fit(X, y, sample_weight, *args, **kwargs) self.scores_ = [] for reg_param in self.reg_param_list: est = HSTreeRegressor(deepcopy(m.estimator_), reg_param) cv_scores = cross_val_score(est, X, y, cv=self.cv, scoring=self.scoring) self.scores_.append(np.mean(cv_scores)) self.reg_param = self.reg_param_list[np.argmax(self.scores_)] return super().fit(X=X, y=y)Ancestors
- HSTreeRegressor
- sklearn.base.RegressorMixin
- HSTree
- sklearn.base.BaseEstimator
- sklearn.utils._repr_html.base.ReprHTMLMixin
- sklearn.utils._repr_html.base._HTMLDocumentationLinkMixin
- sklearn.utils._metadata_requests._MetadataRequester
Methods
def fit(self, X, y, sample_weight=None, *args, **kwargs)-
Expand source code
def fit(self, X, y, sample_weight=None, *args, **kwargs): m = DecisionTreeCCPRegressor(self.estimator_, desired_complexity=self.desired_complexity) m.fit(X, y, sample_weight, *args, **kwargs) self.scores_ = [] for reg_param in self.reg_param_list: est = HSTreeRegressor(deepcopy(m.estimator_), reg_param) cv_scores = cross_val_score(est, X, y, cv=self.cv, scoring=self.scoring) self.scores_.append(np.mean(cv_scores)) self.reg_param = self.reg_param_list[np.argmax(self.scores_)] return super().fit(X=X, y=y)
Inherited members
- set estimator type to