diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5240bfd..b826eee 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
  combined feature_pipeline + estimator Pipeline
 - Can pass a feature pipeline to `Dataset.plot` methods, to apply preprocessing
 before visualization
+- New config implementation. If you need to reset the configuration, you should use `Model.config.reset_config()`
 
 # v0.10.3
 - Fixed typehints in Dataset
diff --git a/docs/config.inc.rst b/docs/config.inc.rst
index 9e74071..e17e735 100644
--- a/docs/config.inc.rst
+++ b/docs/config.inc.rst
@@ -4,56 +4,41 @@ Config
 ------
 All configuration options available
 
-:class: ml_tooling.config.DefaultConfig
+.. autoclass:: ml_tooling.config.DefaultConfig
 
 
     :attr:`VERBOSITY` = 0
         The level of verbosity from output
 
-
     :attr:`CLASSIFIER_METRIC` = 'accuracy'
-
-    Default metric for classifiers
+        Default metric for classifiers
 
     :attr:`REGRESSION_METRIC` = 'r2'
-
-    Default metric for regressions
+        Default metric for regressions
 
     :attr:`CROSS_VALIDATION` = 10
-
-    Default Number of cross validation folds to use
-
-    :attr:`STYLE_SHEET` = 'almbrand.mplstyle'
-
-    Default style sheet to use for plots
+        Default Number of cross validation folds to use
 
     :attr:`N_JOBS` = -1
-
-    Default number of cores to use when doing multiprocessing.
-    -1 means use all available
+        Default number of cores to use when doing multiprocessing.
+        -1 means use all available
 
     :attr:`RANDOM_STATE` = 42
-
-    Default random state seed for all functions involving randomness
+        Default random state seed for all functions involving randomness
 
     :attr:`RUN_DIR` = './runs'
+        Default folder to store run logging files
 
-    Default folder to store run logging files
-
-    :attr:`MODEL_DIR` = './models'
-
-    Default folder to store pickled models in
+    :attr:`ESTIMATOR_DIR` = './models'
+        Default folder to store pickled models in
 
     :attr:`LOG` = False
+        Toggles whether or not to log runs to a file. Set to True if you
+        want every run to be logged, else use the :meth:`~ml_tooling.baseclass.ModelData.log`
+        context manager
 
-    Toggles whether or not to log runs to a file. Set to True if you
-    want every run to be logged, else use the :meth:`~ml_tooling.baseclass.ModelData.log`
-    context manager
-
-    :attr:`SHUFFLE` = True
-
-    Default whether or not to shuffle data for test set
+    :attr:`TRAIN_TEST_SHUFFLE` = True
+        Default whether or not to shuffle data for test set
 
     :attr:`TEST_SIZE` = 0.25
-
-    Default percentage of data that will be part of the test set
+        Default percentage of data that will be part of the test set
diff --git a/src/ml_tooling/baseclass.py b/src/ml_tooling/baseclass.py
index 4071793..81f6257 100644
--- a/src/ml_tooling/baseclass.py
+++ b/src/ml_tooling/baseclass.py
@@ -1,16 +1,17 @@
 import datetime
 import pathlib
-import joblib
-import pandas as pd
 from contextlib import contextmanager
 from importlib.resources import path as import_path
 from typing import Tuple, Optional, Sequence, Union, List, Iterable, Any
+
+import joblib
+import pandas as pd
 from sklearn.base import is_classifier, is_regressor
 from sklearn.exceptions import NotFittedError
 from sklearn.model_selection import check_cv
 from sklearn.pipeline import Pipeline
 
-from ml_tooling.config import DefaultConfig, ConfigGetter
+from ml_tooling.config import config
 from ml_tooling.data.base_data import Dataset
 from ml_tooling.logging.logger import create_logger
 from ml_tooling.metrics.metric import Metrics
@@ -40,9 +41,6 @@ class Model:
     Wrapper class for Estimators
     """
 
-    _config = None
-    config = ConfigGetter()
-
     def __init__(self, estimator: Estimator, feature_pipeline: Pipeline = None):
         """
         Parameters
@@ -57,6 +55,7 @@ class Model:
         self._estimator: Estimator = _validate_estimator(estimator)
         self.feature_pipeline = feature_pipeline
         self.result: Optional[ResultType] = None
+        self.config = config
 
     @property
     def estimator(self):
@@ -437,7 +436,7 @@ class Model:
         if not data.has_validation_set:
             data.create_train_test(
                 stratify=self.is_classifier,
-                shuffle=self.config.SHUFFLE,
+                shuffle=self.config.TRAIN_TEST_SHUFFLE,
                 test_size=self.config.TEST_SIZE,
                 seed=self.config.RANDOM_STATE,
             )
@@ -665,15 +664,6 @@ class Model:
             estimator = joblib.load(path)
         return cls(estimator)
 
-    @classmethod
-    def reset_config(cls):
-        """
-        Reset configuration to default
-        """
-        cls._config = DefaultConfig()
-
-        return cls
-
     def __repr__(self):
         return f"<Model: {self.estimator_name}>"
 
diff --git a/src/ml_tooling/config.py b/src/ml_tooling/config.py
index 9910893..3559cdf 100644
--- a/src/ml_tooling/config.py
+++ b/src/ml_tooling/config.py
@@ -12,27 +12,43 @@ ESTIMATOR_DIR = CWD.joinpath("models")
 
 class DefaultConfig:
     """
-    Configuration for a given BaseClass. Configs propagate through each instance
+    Configuration for Models
     """
 
+    default_config = {
+        "VERBOSITY": 0,
+        "CLASSIFIER_METRIC": "accuracy",
+        "REGRESSION_METRIC": "r2",
+        "CROSS_VALIDATION": 10,
+        "N_JOBS": -1,
+        "RANDOM_STATE": 42,
+        "TRAIN_TEST_SHUFFLE": True,
+        "TEST_SIZE": 0.25,
+    }
+
     def __init__(self):
-        self.VERBOSITY = 0
-        self.CLASSIFIER_METRIC = "accuracy"
-        self.REGRESSION_METRIC = "r2"
-        self.CROSS_VALIDATION = 10
-        self.STYLE_SHEET = MPL_STYLESHEET
-        self.N_JOBS = -1
-        self.RANDOM_STATE = 42
+        self._set_config()
+        self.LOG = False
         self.RUN_DIR = RUN_DIR
         self.ESTIMATOR_DIR = ESTIMATOR_DIR
-        self.LOG = False
-        self.SHUFFLE = True
-        self.TEST_SIZE = 0.25
+
+    def _set_config(self):
+        self.VERBOSITY = self.default_config["VERBOSITY"]
+        self.CLASSIFIER_METRIC = self.default_config["CLASSIFIER_METRIC"]
+        self.REGRESSION_METRIC = self.default_config["REGRESSION_METRIC"]
+        self.CROSS_VALIDATION = self.default_config["CROSS_VALIDATION"]
+        self.N_JOBS = self.default_config["N_JOBS"]
+        self.RANDOM_STATE = self.default_config["RANDOM_STATE"]
+        self.TRAIN_TEST_SHUFFLE = self.default_config["TRAIN_TEST_SHUFFLE"]
+        self.TEST_SIZE = self.default_config["TEST_SIZE"]
 
     @property
     def default_storage(self):
         return FileStorage(self.ESTIMATOR_DIR)
 
+    def reset_config(self):
+        self._set_config()
+
     def __repr__(self):
         attrs = "\n".join(
             [
@@ -44,13 +60,4 @@ class DefaultConfig:
         return f"<Config: \n{attrs}\n>"
 
 
-class ConfigGetter:
-    """
-    Give each class that inherits from Model an individual config attribute
-    without relying on the user to overriding the config when they define their class.
-    """
-
-    def __get__(self, obj, cls):
-        if cls._config is None:
-            cls._config = DefaultConfig()
-        return cls._config
+config = DefaultConfig()
diff --git a/src/ml_tooling/plots/viz/baseviz.py b/src/ml_tooling/plots/viz/baseviz.py
index 6c774c7..befb228 100644
--- a/src/ml_tooling/plots/viz/baseviz.py
+++ b/src/ml_tooling/plots/viz/baseviz.py
@@ -11,6 +11,7 @@ from ml_tooling.plots import (
 )
 from ml_tooling.utils import _get_estimator_name
 from sklearn.base import is_classifier
+from ml_tooling.config import MPL_STYLESHEET, config
 
 
 class BaseVisualize:
@@ -18,10 +19,9 @@ class BaseVisualize:
     Base class for visualizers
     """
 
-    def __init__(self, estimator, data, config):
+    def __init__(self, estimator, data):
         self._estimator = estimator
         self._estimator_name = _get_estimator_name(estimator)
-        self._config = config
         self._data = data
 
     @property
@@ -39,9 +39,9 @@ class BaseVisualize:
         """
 
         return (
-            self._config.CLASSIFIER_METRIC
+            config.CLASSIFIER_METRIC
             if is_classifier(self._estimator)
-            else self._config.REGRESSION_METRIC
+            else config.REGRESSION_METRIC
         )
 
     def feature_importance(
@@ -52,7 +52,6 @@ class BaseVisualize:
         bottom_n: Union[int, float] = None,
         add_label: bool = True,
         n_jobs: int = None,
-        random_state: int = None,
         ax: Axes = None,
         **kwargs,
     ) -> Axes:
@@ -83,9 +82,6 @@ class BaseVisualize:
             Overwrites N_JOBS from settings. Useful if data is to big to fit
             in memory multiple times.
 
-        random_state: int
-            Random state to be used when permuting features,
-
         ax: Axes
             Draws graph on passed ax - otherwise creates new ax
 
@@ -97,11 +93,11 @@ class BaseVisualize:
             matplotlib.Axes
         """
 
-        n_jobs = self._config.N_JOBS if n_jobs is None else n_jobs
+        n_jobs = config.N_JOBS if n_jobs is None else n_jobs
         scoring = self.default_metric if scoring == "default" else scoring
         title = f"Feature Importances ({scoring.title()}) - {self._estimator_name}"
 
-        with plt.style.context(self._config.STYLE_SHEET):
+        with plt.style.context(MPL_STYLESHEET):
             return plot_feature_importance(
                 estimator=self._estimator,
                 x=self._data.x,
@@ -109,7 +105,7 @@ class BaseVisualize:
                 scoring=scoring,
                 n_repeats=n_repeats,
                 n_jobs=n_jobs,
-                random_state=random_state,
+                random_state=config.RANDOM_STATE,
                 ax=ax,
                 top_n=top_n,
                 bottom_n=bottom_n,
@@ -120,7 +116,7 @@ class BaseVisualize:
 
     def learning_curve(
         self,
-        cv: int = 5,
+        cv: int = None,
         scoring: str = "default",
         n_jobs: int = None,
         train_sizes: Sequence[float] = np.linspace(0.1, 1.0, 5),
@@ -157,9 +153,10 @@ class BaseVisualize:
         """
 
         title = f"Learning Curve - {self._estimator_name}"
-        n_jobs = self._config.N_JOBS if n_jobs is None else n_jobs
+        n_jobs = config.N_JOBS if n_jobs is None else n_jobs
+        cv = config.CROSS_VALIDATION if cv is None else cv
 
-        with plt.style.context(self._config.STYLE_SHEET):
+        with plt.style.context(MPL_STYLESHEET):
             ax = plot_learning_curve(
                 estimator=self._estimator,
                 x=self._data.train_x,
@@ -180,7 +177,7 @@ class BaseVisualize:
         param_name: str,
         param_range: Sequence,
         n_jobs: int = None,
-        cv: int = 5,
+        cv: int = None,
         scoring: str = "default",
         ax: Axes = None,
         **kwargs,
@@ -205,7 +202,8 @@ class BaseVisualize:
             Number of jobs to use in parallelizing the estimator fitting and scoring
 
         cv: int
-            Number of CV iterations to run. Uses a :class:`~sklearn.model_selection.StratifiedKFold`
+            Number of CV iterations to run. Defaults to value in `Model.config`.
+            Uses a :class:`~sklearn.model_selection.StratifiedKFold`
             if`estimator` is a classifier - otherwise a :class:`~sklearn.model_selection.KFold`
             is used.
 
@@ -224,10 +222,11 @@ class BaseVisualize:
         plt.Axes
 
         """
-        n_jobs = self._config.N_JOBS if n_jobs is None else n_jobs
+        n_jobs = config.N_JOBS if n_jobs is None else n_jobs
+        cv = config.CROSS_VALIDATION if cv is None else cv
         title = f"Validation Curve - {self._estimator_name}"
 
-        with plt.style.context(self._config.STYLE_SHEET):
+        with plt.style.context(MPL_STYLESHEET):
             ax = plot_validation_curve(
                 self._estimator,
                 x=self._data.train_x,
diff --git a/src/ml_tooling/plots/viz/classification_viz.py b/src/ml_tooling/plots/viz/classification_viz.py
index e189030..5094a9c 100644
--- a/src/ml_tooling/plots/viz/classification_viz.py
+++ b/src/ml_tooling/plots/viz/classification_viz.py
@@ -8,6 +8,7 @@ from ml_tooling.plots import (
 )
 from ml_tooling.utils import VizError, _classify
 from ml_tooling.plots.viz.baseviz import BaseVisualize
+from ml_tooling.config import MPL_STYLESHEET
 
 
 class ClassificationVisualize(BaseVisualize):
@@ -35,7 +36,7 @@ class ClassificationVisualize(BaseVisualize):
         matplotlib.Axes
         """
 
-        with plt.style.context(self._config.STYLE_SHEET):
+        with plt.style.context(MPL_STYLESHEET):
             title = f"Confusion Matrix - {self._estimator_name}"
             y_pred = _classify(self._data.test_x, self._estimator, threshold=threshold)
             return plot_confusion_matrix(
@@ -55,7 +56,7 @@ class ClassificationVisualize(BaseVisualize):
         if not hasattr(self._estimator, "predict_proba"):
             raise VizError("Model must provide a 'predict_proba' method")
 
-        with plt.style.context(self._config.STYLE_SHEET):
+        with plt.style.context(MPL_STYLESHEET):
             title = f"ROC AUC - {self._estimator_name}"
             y_proba = self._estimator.predict_proba(self._data.test_x)[:, 1]
             return plot_roc_auc(self._data.test_y, y_proba, title=title, **kwargs)
@@ -70,7 +71,7 @@ class ClassificationVisualize(BaseVisualize):
         -------
         matplotlib.Axes
         """
-        with plt.style.context(self._config.STYLE_SHEET):
+        with plt.style.context(MPL_STYLESHEET):
             title = f"Lift Curve - {self._estimator_name}"
             y_proba = self._estimator.predict_proba(self._data.test_x)[:, 1]
             return plot_lift_curve(self._data.test_y, y_proba, title=title, **kwargs)
@@ -95,7 +96,7 @@ class ClassificationVisualize(BaseVisualize):
         if not hasattr(self._estimator, "predict_proba"):
             raise VizError("Estimator must provide a 'predict_proba' method")
 
-        with plt.style.context(self._config.STYLE_SHEET):
+        with plt.style.context(MPL_STYLESHEET):
             title = f"Precision-Recall - {self._estimator_name}"
             y_proba = self._estimator.predict_proba(self._data.test_x)[:, 1]
             return plot_pr_curve(self._data.test_y, y_proba, title=title, **kwargs)
diff --git a/src/ml_tooling/plots/viz/regression_viz.py b/src/ml_tooling/plots/viz/regression_viz.py
index 1b50010..657b848 100644
--- a/src/ml_tooling/plots/viz/regression_viz.py
+++ b/src/ml_tooling/plots/viz/regression_viz.py
@@ -2,6 +2,7 @@ from matplotlib import pyplot as plt
 
 from ml_tooling.plots import plot_residuals, plot_prediction_error
 from ml_tooling.plots.viz.baseviz import BaseVisualize
+from ml_tooling.config import MPL_STYLESHEET
 
 
 class RegressionVisualize(BaseVisualize):
@@ -19,7 +20,7 @@ class RegressionVisualize(BaseVisualize):
         matplotlib.Axes
             Plot of the estimator's residuals
         """
-        with plt.style.context(self._config.STYLE_SHEET):
+        with plt.style.context(MPL_STYLESHEET):
             title = f"Residual Plot - {self._estimator_name}"
             y_pred = self._estimator.predict(self._data.test_x)
             return plot_residuals(self._data.test_y, y_pred, title, **kwargs)
@@ -35,7 +36,7 @@ class RegressionVisualize(BaseVisualize):
             Plot of the estimator's prediction error
         """
 
-        with plt.style.context(self._config.STYLE_SHEET):
+        with plt.style.context(MPL_STYLESHEET):
             title = f"Prediction Error - {self._estimator_name}"
             y_pred = self._estimator.predict(self._data.test_x)
             return plot_prediction_error(
diff --git a/src/ml_tooling/result/result.py b/src/ml_tooling/result/result.py
index 173a7d0..4e3c1cf 100644
--- a/src/ml_tooling/result/result.py
+++ b/src/ml_tooling/result/result.py
@@ -32,10 +32,8 @@ class Result:
     @property
     def plot(self):
         if self.model.is_classifier:
-            return ClassificationVisualize(
-                self.model.estimator, self.data, self.model.config
-            )
-        return RegressionVisualize(self.model.estimator, self.data, self.model.config)
+            return ClassificationVisualize(self.model.estimator, self.data)
+        return RegressionVisualize(self.model.estimator, self.data)
 
     @classmethod
     def from_model(
diff --git a/src/ml_tooling/storage/file.py b/src/ml_tooling/storage/file.py
index f799e4e..1bb9ef6 100644
--- a/src/ml_tooling/storage/file.py
+++ b/src/ml_tooling/storage/file.py
@@ -15,7 +15,7 @@ class FileStorage(Storage):
 
     def __init__(self, dir_path: Pathlike = None):
         self.dir_path = Path.cwd() if dir_path is None else Path(dir_path)
-        if not self.dir_path.is_dir():
+        if self.dir_path.is_file():
             raise MLToolingError(
                 f"dir_path is {self.dir_path} which is not a directory"
             )
diff --git a/src/ml_tooling/utils.py b/src/ml_tooling/utils.py
index d283f9d..659eff5 100644
--- a/src/ml_tooling/utils.py
+++ b/src/ml_tooling/utils.py
@@ -118,7 +118,7 @@ def _get_estimator_name(clf: Estimator) -> str:
     return class_name
 
 
-def listify(collection) -> list:
+def listify(collection: Any) -> List:
     """
     Takes a given collection and returns a list of the elements, handling strings correctly
 
@@ -140,7 +140,7 @@ def listify(collection) -> list:
     return collection
 
 
-def _validate_estimator(estimator: Estimator):
+def _validate_estimator(estimator: Estimator) -> Estimator:
     """
     Ensures that estimator is a valid estimator - either a :class:`~sklearn.base.BaseEstimator`
     or a :class:`~sklearn.pipeline.Pipeline` with a :class:`~sklearn.base.BaseEstimator`

ENH: Maybe we can remove ConfigGetter
Now that we don't need to subclass the model class ConfigGetter might be obsolete. We should check this.

diff --git a/tests/test_baseclass.py b/tests/test_baseclass.py
index 6d0fbce..c5363c8 100644
--- a/tests/test_baseclass.py
+++ b/tests/test_baseclass.py
@@ -75,7 +75,7 @@ class TestBaseClass:
         assert rf.config.CLASSIFIER_METRIC == "fowlkes_mallows_score"
         assert rf.config.REGRESSION_METRIC == "r2"
         assert rf.default_metric == "fowlkes_mallows_score"
-        rf.reset_config()
+        rf.config.reset_config()
 
     def test_default_metric_getter_works_as_expected_regressor(self):
         linreg = Model(LinearRegression())
@@ -86,7 +86,7 @@ class TestBaseClass:
         assert linreg.config.CLASSIFIER_METRIC == "accuracy"
         assert linreg.config.REGRESSION_METRIC == "neg_mean_squared_error"
         assert linreg.default_metric == "neg_mean_squared_error"
-        linreg.reset_config()
+        linreg.config.reset_config()
 
     def test_default_metric_works_as_expected_without_pipeline(self):
         rf = Model(RandomForestClassifier(n_estimators=10))
@@ -97,8 +97,8 @@ class TestBaseClass:
         linreg.config.REGRESSION_METRIC = "neg_mean_squared_error"
         assert "fowlkes_mallows_score" == rf.default_metric
         assert "neg_mean_squared_error" == linreg.default_metric
-        rf.reset_config()
-        linreg.reset_config()
+        rf.config.reset_config()
+        linreg.config.reset_config()
 
     def test_default_metric_works_as_expected_with_pipeline(
         self, pipeline_logistic: Pipeline, pipeline_linear: Pipeline
@@ -111,8 +111,8 @@ class TestBaseClass:
         linreg.config.REGRESSION_METRIC = "neg_mean_squared_error"
         assert "fowlkes_mallows_score" == logreg.default_metric
         assert "neg_mean_squared_error" == linreg.default_metric
-        logreg.reset_config()
-        linreg.reset_config()
+        logreg.config.reset_config()
+        linreg.config.reset_config()
 
     def test_regression_model_can_be_saved(
         self, classifier: Model, tmp_path: pathlib.Path, train_iris_dataset
@@ -475,7 +475,7 @@ class TestScoreEstimator:
         model = Model(LinearRegression())
         model.config.RANDOM_STATE = 1
         model.config.TEST_SIZE = 0.5
-        model.config.SHUFFLE = False
+        model.config.TRAIN_TEST_SHUFFLE = False
         data = boston_dataset()
         model.score_estimator(data)
 
@@ -486,7 +486,7 @@ class TestScoreEstimator:
         assert np.array_equal(data.test_y, test.test_y)
         pd.testing.assert_frame_equal(data.train_x, test.train_x)
         assert np.array_equal(data.train_y, test.train_y)
-        model.reset_config()
+        model.config.reset_config()
 
     def test_score_estimator_creates_train_test_data_with_changed_config_and_classification_data(
         self, iris_dataset
@@ -504,7 +504,7 @@ class TestScoreEstimator:
         assert np.array_equal(data.test_y, test.test_y)
         pd.testing.assert_frame_equal(data.train_x, test.train_x)
         assert np.array_equal(data.train_y, test.train_y)
-        model.reset_config()
+        model.config.reset_config()
 
     def test_can_score_estimator_with_specified_metric(self, train_iris_dataset):
         model = Model(LogisticRegression(solver="liblinear"))
diff --git a/tests/test_config.py b/tests/test_config.py
index 00a5b40..0b0ee48 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -1,53 +1,7 @@
-from ml_tooling import Model
 from ml_tooling.config import DefaultConfig
-from sklearn.linear_model import LinearRegression
 
 
 class TestConfig:
-    def test_config_is_set_globally(self, pipeline_dummy_classifier, pipeline_linear):
-        class TestModel(Model):
-            @classmethod
-            def setup_estimator(cls):
-                pass
-
-            def get_prediction_data(self, *args):
-                pass
-
-            def get_training_data(self):
-                pass
-
-        TestModel.reset_config()
-
-        assert TestModel.config.N_JOBS == -1
-
-        model = TestModel(pipeline_dummy_classifier)
-        assert model.config.N_JOBS == -1
-
-        TestModel.config.N_JOBS = 1
-        assert TestModel.config.N_JOBS == 1
-        assert model.config.N_JOBS == 1
-
-        new_model = TestModel(pipeline_dummy_classifier)
-        assert new_model.config.N_JOBS == 1
-
-    def test_can_change_config(self):
-        class SomeModel(Model):
-            @classmethod
-            def setup_estimator(cls):
-                pass
-
-            def get_training_data(self):
-                pass
-
-            def get_prediction_data(self, *args):
-                pass
-
-        SomeModel.reset_config()
-        test_model = SomeModel(LinearRegression())
-        assert 10 == test_model.config.CROSS_VALIDATION
-        test_model.config.CROSS_VALIDATION = 2
-        assert test_model.config.CROSS_VALIDATION == 2
-
     def test_config_repr_works(self):
         config = DefaultConfig()
         for key in [
@@ -55,7 +9,6 @@ class TestConfig:
             "CLASSIFIER_METRIC",
             "REGRESSION_METRIC",
             "CROSS_VALIDATION",
-            "STYLE_SHEET",
             "N_JOBS",
             "RANDOM_STATE",
         ]:
@@ -69,23 +22,7 @@ class TestConfig:
         assert log.config.CLASSIFIER_METRIC == "accuracy"
         log.config.CLASSIFIER_METRIC = "fowlkes_mallows_score"
         assert rf.config.CLASSIFIER_METRIC == "fowlkes_mallows_score"
-
-    def test_from_different_classes_do_not_share_config(
-        self, base, pipeline_logistic, pipeline_forest_classifier
-    ):
-        class NoModel(Model):
-            def get_prediction_data(self, idx):
-                pass
-
-            def get_training_data(self):
-                pass
-
-        log = base(pipeline_logistic)
-        rf = NoModel(pipeline_forest_classifier)
-        assert log.config.CLASSIFIER_METRIC == "accuracy"
-        log.config.CLASSIFIER_METRIC = "fowlkes_mallows_score"
-        assert rf.config.CLASSIFIER_METRIC == "accuracy"
-        assert log.config.CLASSIFIER_METRIC == "fowlkes_mallows_score"
+        log.config.reset_config()
 
     def test_config_default_storage_points_to_cwd(self, base, tmp_path):
         base.config.ESTIMATOR_DIR = tmp_path
diff --git a/tests/test_storage.py b/tests/test_storage.py
index e9c799e..f219e37 100644
--- a/tests/test_storage.py
+++ b/tests/test_storage.py
@@ -90,8 +90,10 @@ class TestFileStorage:
         assert estimators[-1] == paths[3]
 
     def test_raise_when_non_dir(self, classifier: Model, tmp_path: pathlib.Path):
+        path = tmp_path / "file.txt"
+        path.write_text("test")
         with pytest.raises(MLToolingError, match="which is not a directory"):
-            _ = FileStorage("/not/a/dir.file")
+            FileStorage(path)
 
     def test_cannot_instantiate_an_abstract_baseclass(self):
         with pytest.raises(TypeError):
diff --git a/tests/test_visualize.py b/tests/test_visualize.py
index ad90689..9c1bbfe 100644
--- a/tests/test_visualize.py
+++ b/tests/test_visualize.py
@@ -129,7 +129,7 @@ class TestFeatureImportancePlot:
         plt.close()
 
     def test_feature_importance_plots_have_correct_data(self, classifier: Model):
-        ax = classifier.result.plot.feature_importance(random_state=42)
+        ax = classifier.result.plot.feature_importance()
 
         expected = {"0.04", "0.06", "0.10", "-0.03"}
         assert {text.get_text() for text in ax.texts} == expected
@@ -161,7 +161,7 @@ class TestFeatureImportancePlot:
     def test_feature_importance_plots_have_correct_labels_when_top_n_is_set(
         self, classifier: Model
     ):
-        ax = classifier.result.plot.feature_importance(top_n=2, random_state=42)
+        ax = classifier.result.plot.feature_importance(top_n=2)
         assert 2 == len(ax.texts)
         assert {text.get_text() for text in ax.texts} == {"0.10", "0.06"}
 
@@ -179,7 +179,7 @@ class TestFeatureImportancePlot:
     def test_feature_importance_plots_have_correct_labels_when_top_n_is_percent(
         self, classifier: Model
     ):
-        ax = classifier.result.plot.feature_importance(top_n=0.2, random_state=42)
+        ax = classifier.result.plot.feature_importance(top_n=0.2)
         assert len(ax.texts) == 1
         assert {text.get_text() for text in ax.texts} == {"0.10"}
 
@@ -197,7 +197,7 @@ class TestFeatureImportancePlot:
     def test_feature_importance_plots_have_correct_labels_when_bottom_n_is_int(
         self, classifier: Model
     ):
-        ax = classifier.result.plot.feature_importance(bottom_n=2, random_state=42)
+        ax = classifier.result.plot.feature_importance(bottom_n=2)
         assert len(ax.texts) == 2
         assert {text.get_text() for text in ax.texts} == {"0.04", "-0.03"}
 
@@ -215,7 +215,7 @@ class TestFeatureImportancePlot:
     def test_feature_importance_plots_have_correct_labels_when_bottom_n_is_percent(
         self, classifier: Model
     ):
-        ax = classifier.result.plot.feature_importance(bottom_n=0.2, random_state=42)
+        ax = classifier.result.plot.feature_importance(bottom_n=0.2)
         assert len(ax.texts) == 1
         assert {text.get_text() for text in ax.texts} == {"-0.03"}
 
@@ -233,9 +233,7 @@ class TestFeatureImportancePlot:
     def test_feature_importance_plots_correct_if_top_n_is_int_and_bottom_n_is_int(
         self, classifier: Model
     ):
-        ax = classifier.result.plot.feature_importance(
-            top_n=1, bottom_n=1, random_state=42
-        )
+        ax = classifier.result.plot.feature_importance(top_n=1, bottom_n=1)
         assert len(ax.texts) == 2
         assert {text.get_text() for text in ax.texts} == {"0.10", "-0.03"}
         assert ax.get_ylabel() == "Feature Labels"
@@ -252,9 +250,7 @@ class TestFeatureImportancePlot:
     def test_feature_importance_plots_correct_when_top_n_is_int_and_bottom_n_is_percent(
         self, classifier: Model
     ):
-        ax = classifier.result.plot.feature_importance(
-            top_n=1, bottom_n=0.2, random_state=42
-        )
+        ax = classifier.result.plot.feature_importance(top_n=1, bottom_n=0.2)
         assert 2 == len(ax.texts)
         assert {text.get_text() for text in ax.texts} == {"0.10", "-0.03"}
         assert ax.get_ylabel() == "Feature Labels"
@@ -271,9 +267,7 @@ class TestFeatureImportancePlot:
     def test_feature_importance_plots_correct_when_top_n_is_percent_and_bottom_n_is_int(
         self, classifier: Model
     ):
-        ax = classifier.result.plot.feature_importance(
-            top_n=0.2, bottom_n=1, random_state=42
-        )
+        ax = classifier.result.plot.feature_importance(top_n=0.2, bottom_n=1)
         assert len(ax.texts) == 2
         assert {text.get_text() for text in ax.texts} == {"-0.03", "0.10"}
         assert ax.get_ylabel() == "Feature Labels"
@@ -340,9 +334,7 @@ class TestFeatureImportancePlot:
         plt.close()
 
     def test_can_use_different_scoring_metrics(self, classifier: Model):
-        ax = classifier.result.plot.feature_importance(
-            scoring="roc_auc", random_state=42
-        )
+        ax = classifier.result.plot.feature_importance(scoring="roc_auc")
         assert (
             ax.title.get_text() == "Feature Importances (Roc_Auc) - LogisticRegression"
         )
@@ -516,7 +508,7 @@ class TestLearningCurve:
         plt.close()
 
     def test_learning_curve_plots_have_correct_elements(self, classifier: Model):
-        test_ax = classifier.result.plot.learning_curve()
+        test_ax = classifier.result.plot.learning_curve(cv=5)
         assert test_ax.title.get_text() == "Learning Curve - LogisticRegression"
         assert test_ax.get_ylabel() == "Accuracy Score"
         assert test_ax.get_xlabel() == "Number of Examples Used"

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
3.7
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
attrs==19.3.0
Babel==2.14.0
cachetools==5.5.2
certifi @ file:///croot/certifi_1671487769961/work/certifi
cfgv==3.3.1
chardet==5.2.0
charset-normalizer==3.4.1
colorama==0.4.6
coverage==7.2.7
cycler==0.10.0
distlib==0.3.9
docutils==0.19
exceptiongroup==1.2.2
filelock==3.12.2
identify==2.5.24
idna==3.10
imagesize==1.4.1
importlib-metadata==6.7.0
iniconfig==2.0.0
Jinja2==3.1.6
joblib==0.16.0
kiwisolver==1.2.0
MarkupSafe==2.1.5
matplotlib==3.3.0
-e git+https://github.com/andersbogsnes/ml_tooling.git@b4e9ed520586ce65692da3ff8a3a84751aaf2915#egg=ml_tooling
nodeenv==1.9.1
numpy==1.19.0
packaging==24.0
pandas==1.0.5
Pillow==7.2.0
platformdirs==4.0.0
pluggy==1.2.0
pre-commit==2.21.0
Pygments==2.17.2
pyparsing==2.4.7
pyproject-api==1.5.3
pytest==7.4.4
pytest-cov==4.1.0
python-dateutil==2.8.1
pytz==2020.1
PyYAML==5.3.1
requests==2.31.0
scikit-learn==0.23.1
scipy==1.5.1
six==1.15.0
snowballstemmer==2.2.0
Sphinx==5.3.0
sphinx-rtd-theme==2.0.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
SQLAlchemy==1.3.18
threadpoolctl==2.1.0
tomli==2.0.1
tox==4.8.0
typing_extensions==4.7.1
urllib3==2.0.7
virtualenv==20.26.6
zipp==3.15.0

name: ml_tooling
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - attrs==19.3.0
      - babel==2.14.0
      - cachetools==5.5.2
      - cfgv==3.3.1
      - chardet==5.2.0
      - charset-normalizer==3.4.1
      - colorama==0.4.6
      - coverage==7.2.7
      - cycler==0.10.0
      - distlib==0.3.9
      - docutils==0.19
      - exceptiongroup==1.2.2
      - filelock==3.12.2
      - identify==2.5.24
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - jinja2==3.1.6
      - joblib==0.16.0
      - kiwisolver==1.2.0
      - markupsafe==2.1.5
      - matplotlib==3.3.0
      - nodeenv==1.9.1
      - numpy==1.19.0
      - packaging==24.0
      - pandas==1.0.5
      - pillow==7.2.0
      - platformdirs==4.0.0
      - pluggy==1.2.0
      - pre-commit==2.21.0
      - pygments==2.17.2
      - pyparsing==2.4.7
      - pyproject-api==1.5.3
      - pytest==7.4.4
      - pytest-cov==4.1.0
      - python-dateutil==2.8.1
      - pytz==2020.1
      - pyyaml==5.3.1
      - requests==2.31.0
      - scikit-learn==0.23.1
      - scipy==1.5.1
      - six==1.15.0
      - snowballstemmer==2.2.0
      - sphinx==5.3.0
      - sphinx-rtd-theme==2.0.0
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jquery==4.1
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - sqlalchemy==1.3.18
      - threadpoolctl==2.1.0
      - tomli==2.0.1
      - tox==4.8.0
      - typing-extensions==4.7.1
      - urllib3==2.0.7
      - virtualenv==20.26.6
      - zipp==3.15.0
prefix: /opt/conda/envs/ml_tooling

tests/test_baseclass.py::TestBaseClass::test_default_metric_getter_works_as_expected_classifier tests/test_baseclass.py::TestBaseClass::test_default_metric_getter_works_as_expected_regressor tests/test_baseclass.py::TestBaseClass::test_default_metric_works_as_expected_without_pipeline tests/test_baseclass.py::TestBaseClass::test_default_metric_works_as_expected_with_pipeline tests/test_baseclass.py::TestScoreEstimator::test_score_estimator_creates_train_test_data_with_changed_config tests/test_baseclass.py::TestScoreEstimator::test_score_estimator_creates_train_test_data_with_changed_config_and_classification_data tests/test_baseclass.py::TestScoreEstimator::test_can_score_estimator_with_default_metric tests/test_baseclass.py::TestModelSelection::test_model_selection_works_with_default_metric tests/test_baseclass.py::TestGridSearch::test_gridsearch_uses_default_metric tests/test_baseclass.py::TestRandomSearch::test_randomsearch_uses_default_metric tests/test_baseclass.py::TestRandomSearch::test_randomsearch_can_take_dist_objs tests/test_config.py::TestConfig::test_from_same_class_share_config tests/test_visualize.py::TestFeatureImportancePlot::test_feature_importance_plots_have_correct_data tests/test_visualize.py::TestFeatureImportancePlot::test_feature_importance_plots_have_no_labels_if_value_is_false tests/test_visualize.py::TestFeatureImportancePlot::test_feature_importance_plots_have_correct_labels_when_top_n_is_set tests/test_visualize.py::TestFeatureImportancePlot::test_feature_importance_plots_have_correct_labels_when_top_n_is_percent tests/test_visualize.py::TestFeatureImportancePlot::test_feature_importance_plots_have_correct_labels_when_bottom_n_is_int tests/test_visualize.py::TestFeatureImportancePlot::test_feature_importance_plots_have_correct_labels_when_bottom_n_is_percent tests/test_visualize.py::TestFeatureImportancePlot::test_feature_importance_plots_correct_if_top_n_is_int_and_bottom_n_is_int tests/test_visualize.py::TestFeatureImportancePlot::test_feature_importance_plots_correct_when_top_n_is_int_and_bottom_n_is_percent tests/test_visualize.py::TestFeatureImportancePlot::test_feature_importance_plots_correct_when_top_n_is_percent_and_bottom_n_is_int tests/test_visualize.py::TestFeatureImportancePlot::test_feature_importance_plots_correctly_in_pipeline
tests/test_baseclass.py::TestBaseClass::test_is_properties_works tests/test_baseclass.py::TestBaseClass::test_instantiate_model_with_non_estimator_pipeline_fails tests/test_baseclass.py::TestBaseClass::test_instantiate_model_with_feature_pipeline_sets_estimator_correctly tests/test_baseclass.py::TestBaseClass::test_instantiate_model_with_other_object_fails tests/test_baseclass.py::TestBaseClass::test_regression_model_can_be_saved tests/test_baseclass.py::TestBaseClass::test_regression_model_filename_is_generated_correctly tests/test_baseclass.py::TestBaseClass::test_save_model_saves_pipeline_correctly tests/test_baseclass.py::TestBaseClass::test_save_estimator_saves_logging_dir_correctly tests/test_baseclass.py::TestBaseClass::test_save_estimator_with_prod_flag_saves_correctly tests/test_baseclass.py::TestBaseClass::test_save_estimator_uses_default_storage_if_no_storage_is_passed tests/test_baseclass.py::TestBaseClass::test_can_load_production_estimator tests/test_baseclass.py::TestBaseClass::test_log_context_manager_works_as_expected tests/test_baseclass.py::TestBaseClass::test_log_context_manager_logs_when_scoring_model tests/test_baseclass.py::TestBaseClass::test_test_models_logs_when_given_dir tests/test_baseclass.py::TestBaseClass::test_dump_serializes_correctly_without_pipeline tests/test_baseclass.py::TestBaseClass::test_dump_serializes_correctly_with_pipeline tests/test_baseclass.py::TestBaseClass::test_to_dict_serializes_correctly_with_feature_union tests/test_baseclass.py::TestBaseClass::test_from_yaml_serializes_correctly_with_feature_union tests/test_baseclass.py::TestBaseClass::test_can_load_serialized_model_from_pipeline tests/test_baseclass.py::TestBaseClass::test_can_load_serialized_model_from_estimator tests/test_baseclass.py::TestTrainEstimator::test_train_model_sets_result_to_none tests/test_baseclass.py::TestTrainEstimator::test_train_model_followed_by_score_model_returns_correctly tests/test_baseclass.py::TestTrainEstimator::test_train_model_errors_correctly_when_not_scored tests/test_baseclass.py::TestTrainEstimator::test_can_score_estimator_with_no_y_value tests/test_baseclass.py::TestScoreEstimator::test_score_estimator_creates_train_test_data tests/test_baseclass.py::TestScoreEstimator::test_score_estimator_creates_train_test_data_classification tests/test_baseclass.py::TestScoreEstimator::test_can_score_estimator_with_specified_metric tests/test_baseclass.py::TestScoreEstimator::test_can_score_estimator_with_multiple_metrics tests/test_baseclass.py::TestModelSelection::test_model_selection_works_as_expected tests/test_baseclass.py::TestModelSelection::test_model_selection_works_with_multiple_metrics tests/test_baseclass.py::TestModelSelection::test_model_selection_with_nonstandard_metric_works_as_expected tests/test_baseclass.py::TestModelSelection::test_model_selection_with_pipeline_works_as_expected tests/test_baseclass.py::TestModelSelection::test_model_selection_refits_final_model tests/test_baseclass.py::TestGridSearch::test_gridsearch_model_returns_as_expected tests/test_baseclass.py::TestGridSearch::test_gridsearch_model_does_not_fail_when_run_twice tests/test_baseclass.py::TestGridSearch::test_prepare_gridsearch_estimators_has_different_parameters tests/test_baseclass.py::TestGridSearch::test_prepare_gridsearch_estimators_in_pipeline_has_different_parameters tests/test_baseclass.py::TestGridSearch::test_gridsearch_can_take_multiple_metrics tests/test_baseclass.py::TestGridSearch::test_gridsearch_can_log_with_context_manager tests/test_baseclass.py::TestRandomSearch::test_randomsearch_model_returns_as_expected tests/test_baseclass.py::TestRandomSearch::test_randomsearch_model_does_not_fail_when_run_twice tests/test_baseclass.py::TestRandomSearch::test_prepare_randomsearch_estimators_has_different_parameters tests/test_baseclass.py::TestRandomSearch::test_prepare_randomsearch_estimators_in_pipeline_has_different_parameters tests/test_baseclass.py::TestRandomSearch::test_randomsearch_can_take_multiple_metrics tests/test_baseclass.py::TestRandomSearch::test_randomsearch_can_log_with_context_manager tests/test_baseclass.py::TestMakePrediction::test_make_prediction_errors_when_model_is_not_fitted tests/test_baseclass.py::TestMakePrediction::test_make_prediction_with_regression_sqldataset_works_as_expected tests/test_baseclass.py::TestMakePrediction::test_make_prediction_with_classification_sqldataset_works_as_expected tests/test_baseclass.py::TestMakePrediction::test_make_prediction_errors_if_asked_for_proba_without_predict_proba_method tests/test_baseclass.py::TestMakePrediction::test_make_prediction_returns_prediction_if_proba_is_false[False-0] tests/test_baseclass.py::TestMakePrediction::test_make_prediction_returns_prediction_if_proba_is_false[True-5] tests/test_baseclass.py::TestMakePrediction::test_make_prediction_returns_proba_if_proba_is_true[False-0] tests/test_baseclass.py::TestMakePrediction::test_make_prediction_returns_proba_if_proba_is_true[True-5] tests/test_baseclass.py::TestMakePrediction::test_make_prediction_returns_prediction_if_threshold_is_specified[False-0] tests/test_baseclass.py::TestMakePrediction::test_make_prediction_returns_prediction_if_threshold_is_specified[True-5] tests/test_baseclass.py::TestMakePrediction::test_make_prediction_uses_cache_if_set tests/test_config.py::TestConfig::test_config_repr_works tests/test_config.py::TestConfig::test_config_default_storage_points_to_cwd tests/test_storage.py::TestFileStorage::test_can_save_file tests/test_storage.py::TestFileStorage::test_can_save_with_model tests/test_storage.py::TestFileStorage::test_can_load_file tests/test_storage.py::TestFileStorage::test_can_load_file_by_filename tests/test_storage.py::TestFileStorage::test_can_load_with_model tests/test_storage.py::TestFileStorage::test_can_list_estimators tests/test_storage.py::TestFileStorage::test_can_get_list_of_paths_and_load_from_output tests/test_storage.py::TestFileStorage::test_raise_when_non_dir tests/test_storage.py::TestFileStorage::test_cannot_instantiate_an_abstract_baseclass tests/test_storage.py::TestFileStorage::test_store_prod_flag_overrules_init_ tests/test_visualize.py::TestVisualize::test_result_regression_gets_correct_visualizers tests/test_visualize.py::TestVisualize::test_result_classification_gets_correct_visualizers tests/test_visualize.py::TestVisualize::test_regression_visualize_has_all_plots[residuals] tests/test_visualize.py::TestVisualize::test_regression_visualize_has_all_plots[prediction_error] tests/test_visualize.py::TestVisualize::test_regression_visualize_has_all_plots[feature_importance] tests/test_visualize.py::TestVisualize::test_regression_visualize_has_all_plots[learning_curve] tests/test_visualize.py::TestVisualize::test_classifier_visualize_has_all_plots[confusion_matrix] tests/test_visualize.py::TestVisualize::test_classifier_visualize_has_all_plots[roc_curve] tests/test_visualize.py::TestVisualize::test_classifier_visualize_has_all_plots[lift_curve] tests/test_visualize.py::TestVisualize::test_classifier_visualize_has_all_plots[feature_importance] tests/test_visualize.py::TestVisualize::test_classifier_visualize_has_all_plots[pr_curve] tests/test_visualize.py::TestVisualize::test_classifier_visualize_has_all_plots[learning_curve] tests/test_visualize.py::TestConfusionMatrixPlot::test_confusion_matrix_plots_can_be_given_an_ax tests/test_visualize.py::TestConfusionMatrixPlot::test_confusion_matrix_plots_have_correct_data tests/test_visualize.py::TestConfusionMatrixPlot::test_confusion_matrix_plots_have_correct_data_with_threshold tests/test_visualize.py::TestConfusionMatrixPlot::test_confusion_matrix_plots_have_correct_data_when_not_normalized tests/test_visualize.py::TestConfusionMatrixPlot::test_confusion_matrix_has_custom_labels tests/test_visualize.py::TestFeatureImportancePlot::test_feature_importance_plots_can_be_given_an_ax tests/test_visualize.py::TestFeatureImportancePlot::test_feature_importance_doesnt_error_in_on_large_datasets tests/test_visualize.py::TestFeatureImportancePlot::test_can_use_different_scoring_metrics tests/test_visualize.py::TestFeatureImportancePlot::test_can_use_feature_importance_with_regressor tests/test_visualize.py::TestFeatureImportancePlot::test_plot_feature_importance_with_default_metrics tests/test_visualize.py::TestLiftCurvePlot::test_lift_curve_plots_can_be_given_an_ax tests/test_visualize.py::TestLiftCurvePlot::test_lift_curve_have_correct_data tests/test_visualize.py::TestLiftCurvePlot::test_lift_chart_fails_correctly_with_2d_proba tests/test_visualize.py::TestPredictionErrorPlot::test_prediction_error_plots_can_be_given_an_ax tests/test_visualize.py::TestPredictionErrorPlot::test_prediction_error_plots_have_correct_data tests/test_visualize.py::TestResidualPlot::test_residuals_plots_can_be_given_an_ax tests/test_visualize.py::TestResidualPlot::test_residual_plots_have_correct_data tests/test_visualize.py::TestRocCurve::test_roc_curve_plots_can_be_given_an_ax tests/test_visualize.py::TestRocCurve::test_roc_curve_have_correct_data tests/test_visualize.py::TestRocCurve::test_roc_curve_fails_correctly_without_predict_proba tests/test_visualize.py::TestPRCurve::test_prediction_error_plots_can_be_given_an_ax tests/test_visualize.py::TestPRCurve::test_pr_curve_have_correct_data tests/test_visualize.py::TestPRCurve::test_pr_curve_fails_correctly_without_predict_proba tests/test_visualize.py::TestPRCurve::test_pr_curve_can_use_ax tests/test_visualize.py::TestLearningCurve::test_learning_curve_plots_can_be_given_an_ax tests/test_visualize.py::TestLearningCurve::test_learning_curve_plots_have_correct_elements tests/test_visualize.py::TestLearningCurve::test_learning_curve_can_use_different_scoring_parameters tests/test_visualize.py::TestValidationCurve::test_validation_curve_plots_can_be_given_an_ax tests/test_visualize.py::TestValidationCurve::test_validation_curve_plot_has_correct_attributes tests/test_visualize.py::TestValidationCurve::test_validation_curve_plot_can_multiprocess tests/test_visualize.py::TestValidationCurve::test_validation_curve_can_plot_other_metrics tests/test_visualize.py::TestTargetCorrelation::test_target_correlation_can_pass_pipeline tests/test_visualize.py::TestTargetCorrelation::test_target_correlation_uses_pipeline_when_passed tests/test_visualize.py::TestTargetCorrelation::test_target_correlation_works_as_expected tests/test_visualize.py::TestTargetCorrelation::test_target_correlation_works_with_different_methods tests/test_visualize.py::TestTargetCorrelation::test_target_correlation_works_with_top_n tests/test_visualize.py::TestTargetCorrelation::test_target_correlation_works_with_bottom_n tests/test_visualize.py::TestTargetCorrelation::test_target_correlation_works_with_bottom_n_and_top_n tests/test_visualize.py::TestTargetCorrelation::test_target_correlation_plots_can_be_given_an_ax tests/test_visualize.py::TestMissingDataViz::test_missing_data_can_pass_pipeline tests/test_visualize.py::TestMissingDataViz::test_target_correlation_uses_pipeline_when_passed tests/test_visualize.py::TestMissingDataViz::test_missing_data_text_labels_are_correct tests/test_visualize.py::TestMissingDataViz::test_ylabel_is_correct tests/test_visualize.py::TestMissingDataViz::test_xlabel_is_correct tests/test_visualize.py::TestMissingDataViz::test_xticklabels_are_correct tests/test_visualize.py::TestMissingDataViz::test_missing_data_plots_can_be_given_an_ax tests/test_visualize.py::TestMissingDataViz::test_can_call_missing_data_with_no_missing_values
src/ml_tooling/plots/viz/baseviz.py src/ml_tooling/plots/viz/classification_viz.py docs/config.inc.rst CHANGELOG.md src/ml_tooling/storage/file.py src/ml_tooling/plots/viz/regression_viz.py src/ml_tooling/result/result.py src/ml_tooling/utils.py src/ml_tooling/baseclass.py src/ml_tooling/config.py
src/ml_tooling/plots/viz/baseviz.py src/ml_tooling/plots/viz/classification_viz.py docs/config.inc.rst CHANGELOG.md src/ml_tooling/storage/file.py src/ml_tooling/plots/viz/regression_viz.py src/ml_tooling/result/result.py src/ml_tooling/utils.py src/ml_tooling/baseclass.py src/ml_tooling/config.py