<commit_before>"""Forest of trees-based ensemble methods

Those methods include random forests and extremely randomized trees.

The module structure is the following:

- The ``Forest`` base class implements a common ``fit`` method for all
  the estimators in the module. The ``fit`` method of the base ``Forest``
  class calls the ``fit`` method of each sub-estimator on random samples
  (with replacement, a.k.a. bootstrap) of the training set.

  The init of the sub-estimator is further delegated to the
  ``BaseEnsemble`` constructor.

- The ``ForestClassifier`` and ``ForestRegressor`` base classes further
  implement the prediction logic by computing an average of the predicted
  outcomes of the sub-estimators.

- The ``RandomForestClassifier`` and ``RandomForestRegressor`` derived
  classes provide the user with concrete implementations of
  the forest ensemble method using classical, deterministic
  ``DecisionTreeClassifier`` and ``DecisionTreeRegressor`` as
  sub-estimator implementations.

- The ``ExtraTreesClassifier`` and ``ExtraTreesRegressor`` derived
  classes provide the user with concrete implementations of the
  forest ensemble method using the extremly randomized trees
  ``ExtraTreeClassifier`` and ``ExtraTreeRegressor`` as
  sub-estimator implementations.

"""

# Authors: <NAME>, <NAME>
# License: BSD 3

import numpy as np

from ..base import ClassifierMixin, RegressorMixin
from ..externals.joblib import Parallel, delayed
from ..tree import DecisionTreeClassifier, DecisionTreeRegressor, \
                   ExtraTreeClassifier, ExtraTreeRegressor
from ..utils import check_random_state

from .base import BaseEnsemble

__all__ = ["RandomForestClassifier",
           "RandomForestRegressor",
           "ExtraTreesClassifier",
           "ExtraTreesRegressor"]


def _parallel_build_tree(forest, X, y, sample_mask, X_argsorted):
    tree = forest._make_estimator(append=False)

    if forest.bootstrap:
        n_samples = X.shape[0]
        indices = forest.random_state.randint(0, n_samples, n_samples)
        tree.fit(X[indices], y[indices],
                 sample_mask=sample_mask, X_argsorted=X_argsorted)

    else:
        tree.fit(X, y,
                 sample_mask=sample_mask, X_argsorted=X_argsorted)

    return tree

def _parallel_predict_proba(tree, X, n_classes):
    p = np.zeros((X.shape[0], n_classes))

    if n_classes == tree.n_classes_:
        p += tree.predict_proba(X)

    else:
        proba = tree.predict_proba(X)

        for j, c in enumerate(tree.classes_):
            p[:, c] += proba[:, j]

    return p

def _parallel_predict_regr(tree, X):
    return tree.predict(X)

def _parallel_compute_importances(tree):
    return tree.feature_importances()


class Forest(BaseEnsemble):
    """Base class for forests of trees.

    Warning: This class should not be used directly. Use derived classes
    instead.
    """
    def __init__(self, base_estimator,
                       n_estimators=10,
                       estimator_params=[],
                       bootstrap=False,
                       n_jobs=1,
                       random_state=None):
        super(Forest, self).__init__(
            base_estimator=base_estimator,
            n_estimators=n_estimators,
            estimator_params=estimator_params)

        self.bootstrap = bootstrap
        self.n_jobs = n_jobs
        self.random_state = check_random_state(random_state)

    def fit(self, X, y):
        """Build a forest of trees from the training set (X, y).

        Parameters
        ----------
        X : array-like of shape = [n_samples, n_features]
            The training input samples.

        y : array-like, shape = [n_samples]
            The target values (integers that correspond to classes in
            classification, real numbers in regression).

        Returns
        -------
        self : object
            Returns self.
        """
        # Build the forest
        X = np.atleast_2d(X)
        y = np.atleast_1d(y)

        if self.bootstrap:
            sample_mask = None
            X_argsorted = None

        else:
            sample_mask = np.ones((X.shape[0],), dtype=np.bool)
            X_argsorted = np.asfortranarray(
                np.argsort(X.T, axis=1).astype(np.int32).T)

        if isinstance(self.base_estimator, ClassifierMixin):
            self.classes_ = np.unique(y)
            self.n_classes_ = len(self.classes_)
            y = np.searchsorted(self.classes_, y)

        self.estimators_ = Parallel(n_jobs=self.n_jobs)(
            delayed(_parallel_build_tree)(self, X, y, sample_mask, X_argsorted)
                for i in xrange(self.n_estimators))

        return self

    def feature_importances(self):
        """Compute the mean feature importances over the trees in the forest.

        Returns
        -------
        importances : array of shape = [n_features]
            The feature importances.<commit_msg>FIX: Ensure random random_states<commit_after>"""Forest of trees-based ensemble methods

Those methods include random forests and extremely randomized trees.

The module structure is the following:

- The ``Forest`` base class implements a common ``fit`` method for all
  the estimators in the module. The ``fit`` method of the base ``Forest``
  class calls the ``fit`` method of each sub-estimator on random samples
  (with replacement, a.k.a. bootstrap) of the training set.

  The init of the sub-estimator is further delegated to the
  ``BaseEnsemble`` constructor.

- The ``ForestClassifier`` and ``ForestRegressor`` base classes further
  implement the prediction logic by computing an average of the predicted
  outcomes of the sub-estimators.

- The ``RandomForestClassifier`` and ``RandomForestRegressor`` derived
  classes provide the user with concrete implementations of
  the forest ensemble method using classical, deterministic
  ``DecisionTreeClassifier`` and ``DecisionTreeRegressor`` as
  sub-estimator implementations.

- The ``ExtraTreesClassifier`` and ``ExtraTreesRegressor`` derived
  classes provide the user with concrete implementations of the
  forest ensemble method using the extremly randomized trees
  ``ExtraTreeClassifier`` and ``ExtraTreeRegressor`` as
  sub-estimator implementations.

"""

# Authors: <NAME>, <NAME>
# License: BSD 3

import numpy as np

from ..base import ClassifierMixin, RegressorMixin
from ..externals.joblib import Parallel, delayed
from ..tree import DecisionTreeClassifier, DecisionTreeRegressor, \
                   ExtraTreeClassifier, ExtraTreeRegressor
from ..utils import check_random_state

from .base import BaseEnsemble

__all__ = ["RandomForestClassifier",
           "RandomForestRegressor",
           "ExtraTreesClassifier",
           "ExtraTreesRegressor"]


def _parallel_build_tree(forest, X, y, sample_mask, X_argsorted, seed):
    random_state = check_random_state(seed)

    tree = forest._make_estimator(append=False)
    tree.random_state = check_random_state(seed + 1)

    if forest.bootstrap:
        n_samples = X.shape[0]
        indices = random_state.randint(0, n_samples, n_samples)
        tree.fit(X[indices], y[indices],
                 sample_mask=sample_mask, X_argsorted=X_argsorted)

    else:
        tree.fit(X, y,
                 sample_mask=sample_mask, X_argsorted=X_argsorted)

    return tree

def _parallel_predict_proba(tree, X, n_classes):
    p = np.zeros((X.shape[0], n_classes))

    if n_classes == tree.n_classes_:
        p += tree.predict_proba(X)

    else:
        proba = tree.predict_proba(X)

        for j, c in enumerate(tree.classes_):
            p[:, c] += proba[:, j]

    return p

def _parallel_predict_regr(tree, X):
    return tree.predict(X)

def _parallel_compute_importances(tree):
    return tree.feature_importances()


class Forest(BaseEnsemble):
    """Base class for forests of trees.

    Warning: This class should not be used directly. Use derived classes
    instead.
    """
    def __init__(self, base_estimator,
                       n_estimators=10,
                       estimator_params=[],
                       bootstrap=False,
                       n_jobs=1,
                       random_state=None):
        super(Forest, self).__init__(
            base_estimator=base_estimator,
            n_estimators=n_estimators,
            estimator_params=estimator_params)

        self.bootstrap = bootstrap
        self.n_jobs = n_jobs
        self.random_state = check_random_state(random_state)

    def fit(self, X, y):
        """Build a forest of trees from the training set (X, y).

        Parameters
        ----------
        X : array-like of shape = [n_samples, n_features]
            The training input samples.

        y : array-like, shape = [n_samples]
            The target values (integers that correspond to classes in
            classification, real numbers in regression).

        Returns
        -------
        self : object
            Returns self.
        """
        # Build the forest
        X = np.atleast_2d(X)
        y = np.atleast_1d(y)

        if self.bootstrap:
            sample_mask = None
            X_argsorted = None

        else:
            sample_mask = np.ones((X.shape[0],), dtype=np.bool)
            X_argsorted = np.asfortranarray(
                np.argsort(X.T, axis=1).astype(np.int32).T)

        if isinstance(self.base_estimator, ClassifierMixin):
            self.classes_ = np.unique(y)
            self.n_classes_ = len(self.classes_)
            y = np.searchsorted(self.classes_, y)

        self.estimators_ = Parallel(n_jobs=self.n_jobs)(
            delayed(_parallel_build_tree)(
                    self, X, y, sample_mask, X_argsorted,
                    self.random_state.randint(np.iinfo(np.int32).max))
                for i in xrange(self.n_estimators))

        return self

    def feature_importances(self):
        """Compute the mean feature importances over the trees in the forest.

        Returns
        -------
        importances : array of shape = [n_features]
            The feature importances.
{'fraction_non_alphanumeric': 0.08922191345772132, 'fraction_numerical': 0.0028781262405716554, 'mean_word_length': 2.5469904963041183, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6582348', 'n_tokens_mistral': 2964, 'n_tokens_neox': 2833, 'n_words': 822}