'Compute decision function of ``X`` for each boosting iteration.
This method allows monitoring (i.e. determine error on testing set)
after each boosting iteration.
Parameters
X : {array-like, sparse matrix} of shape = [n_samples, n_features]
The training input samples. Sparse matrix can be CSC, CSR, COO,
DOK, or LIL. DOK and LIL are converted to CSR.
Returns
score : generator of array, shape = [n_samples, k]
The decision function of the input samples. The order of
outputs is the same of that of the `classes_` attribute.
Binary classification is a special cases with ``k == 1``,
otherwise ``k==n_classes``. For binary classification,
values closer to -1 or 1 mean more like the first or second
class in ``classes_``, respectively.'

def staged_decision_function(self, X):

    check_is_fitted(self, 'n_classes_')
    X = self._validate_X_predict(X)
    n_classes = self.n_classes_
    classes = self.classes_[:, np.newaxis]
    pred = None
    norm = 0.0
    for (weight, estimator) in zip(self.estimator_weights_, self.estimators_):
        norm += weight
        if (self.algorithm == 'SAMME.R'):
            current_pred = _samme_proba(estimator, n_classes, X)
        else:
            current_pred = estimator.predict(X)
            current_pred = ((current_pred == classes).T * weight)
        if (pred is None):
            pred = current_pred
        else:
            pred += current_pred
        if (n_classes == 2):
            tmp_pred = np.copy(pred)
            tmp_pred[:, 0] *= (-1)
            (yield (tmp_pred / norm).sum(axis=1))
        else:
            (yield (pred / norm))
