mirror of
https://github.com/Doctorado-ML/bayesclass.git
synced 2025-08-17 16:45:54 +00:00
Refactor AODE
This commit is contained in:
@@ -382,7 +382,7 @@ class KDB(BayesBase):
|
|||||||
self.dag_ = dag
|
self.dag_ = dag
|
||||||
|
|
||||||
|
|
||||||
def build_spode(features, class_name):
|
def build_spodes(features, class_name):
|
||||||
"""Build SPODE estimators (Super Parent One Dependent Estimator)"""
|
"""Build SPODE estimators (Super Parent One Dependent Estimator)"""
|
||||||
class_edges = [(class_name, f) for f in features]
|
class_edges = [(class_name, f) for f in features]
|
||||||
for idx in range(len(features)):
|
for idx in range(len(features)):
|
||||||
@@ -394,15 +394,17 @@ def build_spode(features, class_name):
|
|||||||
yield model
|
yield model
|
||||||
|
|
||||||
|
|
||||||
class AODE(BayesBase, BaseEnsemble):
|
class AODE(ClassifierMixin, BaseEnsemble):
|
||||||
def __init__(self, show_progress=False, random_state=None):
|
def __init__(self, show_progress=False, random_state=None):
|
||||||
super().__init__(
|
self.base_model = BayesBase(
|
||||||
show_progress=show_progress, random_state=random_state
|
show_progress=show_progress, random_state=random_state
|
||||||
)
|
)
|
||||||
|
self.show_progress = show_progress
|
||||||
|
self.random_state = random_state
|
||||||
|
|
||||||
def _check_params(self, X, y, kwargs):
|
def _check_params(self, X, y, kwargs):
|
||||||
expected_args = ["class_name", "features", "state_names"]
|
expected_args = ["class_name", "features", "state_names"]
|
||||||
return self._check_params_fit(X, y, expected_args, kwargs)
|
return self.base_model._check_params_fit(X, y, expected_args, kwargs)
|
||||||
|
|
||||||
def nodes_edges(self):
|
def nodes_edges(self):
|
||||||
nodes = 0
|
nodes = 0
|
||||||
@@ -412,6 +414,30 @@ class AODE(BayesBase, BaseEnsemble):
|
|||||||
edges = sum([len(x.edges()) for x in self.models_])
|
edges = sum([len(x.edges()) for x in self.models_])
|
||||||
return nodes, edges
|
return nodes, edges
|
||||||
|
|
||||||
|
def version(self):
|
||||||
|
return self.base_model.version()
|
||||||
|
|
||||||
|
def fit(self, X, y, **kwargs):
|
||||||
|
X_, y_ = self._check_params(X, y, kwargs)
|
||||||
|
self.class_name_ = self.base_model.class_name_
|
||||||
|
self.feature_names_in_ = self.base_model.feature_names_in_
|
||||||
|
self.classes_ = self.base_model.classes_
|
||||||
|
self.n_features_in_ = self.base_model.n_features_in_
|
||||||
|
# Store the information needed to build the model
|
||||||
|
self.X_ = X_
|
||||||
|
self.y_ = y_
|
||||||
|
self.dataset_ = pd.DataFrame(
|
||||||
|
self.X_, columns=self.feature_names_in_, dtype=np.int32
|
||||||
|
)
|
||||||
|
self.dataset_[self.class_name_] = self.y_
|
||||||
|
# Train the model
|
||||||
|
self._train(kwargs)
|
||||||
|
self.fitted_ = True
|
||||||
|
# To keep compatiblity with the benchmark platform
|
||||||
|
self.nodes_leaves = self.nodes_edges
|
||||||
|
# Return the classifier
|
||||||
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def states_(self):
|
def states_(self):
|
||||||
if hasattr(self, "fitted_"):
|
if hasattr(self, "fitted_"):
|
||||||
@@ -424,13 +450,14 @@ class AODE(BayesBase, BaseEnsemble):
|
|||||||
) / len(self.models_)
|
) / len(self.models_)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def _build(self):
|
@property
|
||||||
self.dag_ = None
|
def depth_(self):
|
||||||
|
return self.states_
|
||||||
|
|
||||||
def _train(self, kwargs):
|
def _train(self, kwargs):
|
||||||
self.models_ = []
|
self.models_ = []
|
||||||
states = dict(state_names=kwargs.pop("state_names", []))
|
states = dict(state_names=kwargs.pop("state_names", []))
|
||||||
for model in build_spode(self.feature_names_in_, self.class_name_):
|
for model in build_spodes(self.feature_names_in_, self.class_name_):
|
||||||
model.fit(
|
model.fit(
|
||||||
self.dataset_,
|
self.dataset_,
|
||||||
estimator=BayesianEstimator,
|
estimator=BayesianEstimator,
|
||||||
@@ -442,8 +469,8 @@ class AODE(BayesBase, BaseEnsemble):
|
|||||||
def plot(self, title=""):
|
def plot(self, title=""):
|
||||||
warnings.simplefilter("ignore", UserWarning)
|
warnings.simplefilter("ignore", UserWarning)
|
||||||
for idx, model in enumerate(self.models_):
|
for idx, model in enumerate(self.models_):
|
||||||
self.model_ = model
|
self.base_model.model_ = model
|
||||||
super().plot(title=f"{idx} {title}")
|
self.base_model.plot(title=f"{idx} {title}")
|
||||||
|
|
||||||
def predict(self, X: np.ndarray) -> np.ndarray:
|
def predict(self, X: np.ndarray) -> np.ndarray:
|
||||||
check_is_fitted(self, ["X_", "y_", "fitted_"])
|
check_is_fitted(self, ["X_", "y_", "fitted_"])
|
||||||
@@ -481,7 +508,6 @@ class TANNew(TAN):
|
|||||||
return self.estimator.fit(X, y, **kwargs)
|
return self.estimator.fit(X, y, **kwargs)
|
||||||
|
|
||||||
def predict(self, X):
|
def predict(self, X):
|
||||||
self.plot()
|
|
||||||
return self.estimator.predict(X)
|
return self.estimator.predict(X)
|
||||||
|
|
||||||
|
|
||||||
@@ -510,13 +536,28 @@ class KDBNew(KDB):
|
|||||||
return self.estimator.predict(X)
|
return self.estimator.predict(X)
|
||||||
|
|
||||||
|
|
||||||
class AODENew(AODE):
|
class SpodeNew(BayesBase):
|
||||||
|
"""This class implements a classifier for the SPODE algorithm similar to TANNew and KDBNew"""
|
||||||
|
|
||||||
|
def __init__(self, random_state, show_progress, structure):
|
||||||
|
super().__init__(
|
||||||
|
random_state=random_state, show_progress=show_progress
|
||||||
|
)
|
||||||
|
self.structure = structure
|
||||||
|
|
||||||
|
|
||||||
|
class AODENew:
|
||||||
|
def __init__(self, show_progress=False, random_state=None):
|
||||||
|
self.show_progress = show_progress
|
||||||
|
self.random_state = random_state
|
||||||
|
|
||||||
def _train(self, kwargs):
|
def _train(self, kwargs):
|
||||||
self.estimators_ = []
|
self.estimators_ = []
|
||||||
states = dict(state_names=kwargs.pop("state_names", []))
|
states = dict(state_names=kwargs.pop("state_names", []))
|
||||||
kwargs["states"] = states
|
kwargs["states"] = states
|
||||||
for model in build_spode(self.feature_names_in_, self.class_name_):
|
for spode in build_spodes(self.feature_names_in_, self.class_name_):
|
||||||
estimator = Proposal(model)
|
model = SpodeNew(self.random_state, self.show_progress, spode)
|
||||||
|
estimator = Proposal(spode)
|
||||||
self.estimators_.append(estimator.fit(self.X_, self.y_, **kwargs))
|
self.estimators_.append(estimator.fit(self.X_, self.y_, **kwargs))
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@@ -551,7 +592,8 @@ class Proposal:
|
|||||||
|
|
||||||
def fit(self, X, y, **kwargs):
|
def fit(self, X, y, **kwargs):
|
||||||
# Check parameters
|
# Check parameters
|
||||||
super(self.class_type, self.estimator)._check_params(X, y, kwargs)
|
self.estimator._check_params(X, y, kwargs)
|
||||||
|
|
||||||
# Discretize train data
|
# Discretize train data
|
||||||
self.discretizer = FImdlp(
|
self.discretizer = FImdlp(
|
||||||
n_jobs=1,
|
n_jobs=1,
|
||||||
@@ -563,7 +605,6 @@ class Proposal:
|
|||||||
kwargs = self.update_kwargs(y, kwargs)
|
kwargs = self.update_kwargs(y, kwargs)
|
||||||
# Build the model
|
# Build the model
|
||||||
super(self.class_type, self.estimator).fit(self.Xd, y, **kwargs)
|
super(self.class_type, self.estimator).fit(self.Xd, y, **kwargs)
|
||||||
self.check_integrity("fit", self.Xd)
|
|
||||||
# Local discretization based on the model
|
# Local discretization based on the model
|
||||||
features = kwargs["features"]
|
features = kwargs["features"]
|
||||||
# assign indices to feature names
|
# assign indices to feature names
|
||||||
|
Reference in New Issue
Block a user