title: AttributeError: module "sklearn.utils" has no attribute "_joblib" when inheriting class `sklearn.ensemble.BaggingClassifier.`
body: <p>I need to extract the probabilities of each model trained in <code>sklearn.ensemble.BaggingClassifier</code>. The reason for doing this is to estimate uncertainty around XGBoostClassifier models.</p>
  
  <p>To do this, I create a extended class inheriting from <code>sklearn.ensemble.BaggingClassifier</code> and adding a new method allowing to obtain these probabilities. Please note that this problem is different from <a href="https://stackoverflow.com/questions/54965751/modulenotfounderror-no-module-named-sklearn-utils-joblib">ModuleNotFoundError: No module named &#39;sklearn.utils._joblib&#39;</a></p>
  
  <p>I show the piece of code that I have implemented so far, below:</p>
  
  <p>The necessary modules</p>
  
  <pre><code>from sklearn.ensemble import BaggingClassifier
  from sklearn.ensemble.base import _partition_estimators
  from sklearn.utils import check_array
  from sklearn.utils.validation import check_is_fitted
  import sklearn.utils as su
  </code></pre>
  
  <p>The child class inheriting from <code>BaggingClassifier</code></p>
  
  <pre><code>class EBaggingClassifier(BaggingClassifier):
      """
      Extends the class BaggingClassifier fromsklearn
  
      """
  
      def __init__(self,
                   base_estimator=None,
                   n_estimators=10,
                   max_samples=1.0,
                   max_features=1.0,
                   bootstrap=True,
                   bootstrap_features=False,
                   oob_score=False,
                   warm_start=False,
                   n_jobs=1,
                   random_state=None,
                   verbose=0):
  
          super().__init__(
                   base_estimator,
                   n_estimators,
                   max_samples,
                   max_features,
                   bootstrap,
                   bootstrap_features,
                   oob_score,
                   warm_start,
                   n_jobs,
                   random_state,
                   verbose)
  </code></pre>
  
  <p>The new method allowing to calculate the probability of each estimator is defined below.</p>
  
  <pre><code>    def predict_proball(self, X):
          """
          Computes the probability of each individual estimator
  
          Parameters
          ----------
          X : {array-like, sparse matrix} of shape = [n_samples, n_features]
              The training input samples. Sparse matrices are accepted only if
              they are supported by the base estimator.
  
          Returns
          -------
          p : array of shape = [n_samples, n_classes]
              The class probabilities of the input samples. The order of the
              classes corresponds to that in the attribute `classes_`.
          """
  
          check_is_fitted(self, "classes_")
          # Check data
          X = check_array(
              X, accept_sparse=['csr', 'csc'], dtype=None,
              force_all_finite=False
          )
  
          if self.n_features_ != X.shape[1]:
              raise ValueError("Number of features of the model must "
                               "match the input. Model n_features is {0} and "
                               "input n_features is {1}."
                               "".format(self.n_features_, X.shape[1]))
  
          # Parallel loop
          n_jobs, n_estimators, starts = _partition_estimators(self.n_estimators,
                                                               self.n_jobs)
  
          all_proba = su._joblib.Parallel(n_jobs=n_jobs, verbose=self.verbose,
                               **self._parallel_args())(
              su._joblib.delayed(BaggingClassifier._parallel_predict_proba)(
                  self.estimators_[starts[i]:starts[i + 1]],
                  self.estimators_features_[starts[i]:starts[i + 1]],
                  X,
                  self.n_classes_)
              for i in range(n_jobs))
  
          return all_proba
  </code></pre>
  
  <p>I instantiate this class using <code>XGBoostClassifier</code> as the base estimator:</p>
  
  <pre><code>base_estimator = XGBoostClassifier(**params)
  estimator = EBaggingClassifier(base_estimator=base_estimator, max_samples=0.8, n_estimators=10)
  </code></pre>
  
  <p>and then the <code>estimator</code> using <code>estimator.fit(X, y)</code>, where <code>X</code> and <code>y</code> are <code>pandas.DataFrame</code> objects. When I try to run <code>estimator.predict_proball(X)</code> I get</p>
  
  <pre><code>&gt;&gt;&gt; estimator.predict_proball(X)
  AttributeError: module 'sklearn.utils' has no attribute '_joblib'
  </code></pre>
  
  <p>Does someone know why this is happening? Looking at the <code>BaggingClassifier</code> <a href="https://github.com/scikit-learn/scikit-learn/blob/b7b4d3e2f/sklearn/ensemble/bagging.py#L652" rel="nofollow noreferrer">script</a> the function 'sklearn.utils._joblib' should be available.</p>
  
  <p>FYI:</p>
  
  <pre><code>&gt;&gt;&gt; sklearn.__version__
  '0.19.2'
  </code></pre>