# Path: hep_ml/losses.py
# def compute_positions(y_pred, sample_weight):
#     def fit(self, X, y, sample_weight):
#     def negative_gradient(self, y_pred):
#     def __call__(self, y_pred):
#     def update_tree(self, tree, X, y, y_pred, sample_weight, update_mask, residual):
#     def update_fast_tree(self, fast_tree, X, y, y_pred, sample_weight, update_mask, residual):
#     def update_tree_leaf(self, leaf, indices_in_leaf,
#                          X, y, y_pred, sample_weight, update_mask, residual):
#     def __init__(self, regularization=1e-2):
#     def fit(self, X, y, sample_weight):
#     def __call__(self, y_pred):
#     def negative_gradient(self, y_pred):
#     def hessian(self, y_pred):
#     def update_tree_leaf(self, leaf, indices_in_leaf, X, y, y_pred, sample_weight, update_mask, residual):
#     def __init__(self, regularization=1.):
#     def fit(self, X, y, sample_weight):
#     def __call__(self, y_pred):
#     def negative_gradient(self, y_pred):
#     def hessian(self, y_pred):
#     def update_tree_leaf(self, leaf, indices_in_leaf, X, y, y_pred, sample_weight, update_mask, residual):
#     def fit(self, X, y, sample_weight):
#     def __call__(self, y_pred):
#     def negative_gradient(self, y_pred):
#     def hessian(self, y_pred):
#     def __init__(self, uniform_variables):
#     def fit(self, X, y, sample_weight):
#     def __call__(self, y_pred):
#     def negative_gradient(self, y_pred):
#     def hessian(self, y_pred):
#     def compute_parameters(self, trainX, trainY):
#     def update_tree(self, tree, X, y, y_pred, sample_weight, update_mask, residual):
#     def update_tree_leaf(self, leaf, indices_in_leaf, X, y, y_pred, sample_weight, update_mask, residual):
#     def __init__(self, uniform_variables, knn=10, uniform_label=1, distinguish_classes=True, row_norm=1.):
#     def compute_parameters(self, trainX, trainY):
# def exp_margin(margin):
#     def __init__(self, uniform_variables, uniform_label=1, power=2., ada_coefficient=1.,
#                  allow_wrong_signs=True, use_median=False,
#                  keep_debug_info=False):
#     def fit(self, X, y, sample_weight=None):
#     def compute_groups_indices(self, X, y, label):
#     def __call__(self, pred):
#     def negative_gradient(self, y_pred):
#     def update_tree_leaf(self, leaf, indices_in_leaf,
#                          X, y, y_pred, sample_weight, update_mask, residual):
#     def __init__(self, uniform_variables, n_bins=10, uniform_label=1, power=2., ada_coefficient=1.,
#                  allow_wrong_signs=True, use_median=False, keep_debug_info=False):
#     def compute_groups_indices(self, X, y, label):
#     def __init__(self, uniform_variables, n_neighbours=100, uniform_label=1, power=2., ada_coefficient=1.,
#                  max_groups_on_iteration=3000, allow_wrong_signs=True, use_median=False, keep_debug_info=False,
#                  random_state=None):
#     def compute_groups_indices(self, X, y, label):
# class AbstractLossFunction(BaseEstimator):
# class AdaLossFunction(AbstractLossFunction):
# class BinomialDevianceLossFunction(AbstractLossFunction):
# class CompositeLossFunction(AbstractLossFunction):
# class AbstractMatrixLossFunction(AbstractLossFunction):
# class SimpleKnnLossFunction(AbstractMatrixLossFunction):
# class AbstractFlatnessLossFunction(AbstractLossFunction):
# class BinFlatnessLossFunction(AbstractFlatnessLossFunction):
# class KnnFlatnessLossFunction(AbstractFlatnessLossFunction):
#         A = sparse.vstack(A_parts, format='csr', dtype=float)
#         X = pandas.DataFrame(X)
# 
# Path: hep_ml/commonutils.py
# def generate_sample(n_samples, n_features, distance=2.0):
#     """Generates some test distribution,
#     signal and background distributions are gaussian with same dispersion and different centers,
#     all variables are independent (gaussian correlation matrix is identity)"""
#     from sklearn.datasets import make_blobs
# 
#     centers = numpy.zeros((2, n_features))
#     centers[0, :] = - distance / 2
#     centers[1, :] = distance / 2
# 
#     X, y = make_blobs(n_samples=n_samples, n_features=n_features, centers=centers)
#     columns = ["column" + str(x) for x in range(n_features)]
#     X = pandas.DataFrame(X, columns=columns)
#     return X, y


import numpy
from hep_ml import losses
from hep_ml.commonutils import generate_sample
from __future__ import division, print_function, absolute_import


__author__ = 'Alex Rogozhnikov'


def test_loss_functions(size=50, epsilon=1e-3):
    """
    Testing that hessians and gradients of loss functions coincide with numerical
    """
    X, y = generate_sample(size, n_features=10)
    sample_weight = numpy.random.exponential(size=size)
    tested_losses = [
        losses.BinomialDevianceLossFunction(),
        losses.AdaLossFunction(),

# Path: hep_ml/losses.py
# def compute_positions(y_pred, sample_weight):
#     def fit(self, X, y, sample_weight):
#     def negative_gradient(self, y_pred):
#     def __call__(self, y_pred):
#     def update_tree(self, tree, X, y, y_pred, sample_weight, update_mask, residual):
#     def update_fast_tree(self, fast_tree, X, y, y_pred, sample_weight, update_mask, residual):
#     def update_tree_leaf(self, leaf, indices_in_leaf,
#                          X, y, y_pred, sample_weight, update_mask, residual):
#     def __init__(self, regularization=1e-2):
#     def fit(self, X, y, sample_weight):
#     def __call__(self, y_pred):
#     def negative_gradient(self, y_pred):
#     def hessian(self, y_pred):
#     def update_tree_leaf(self, leaf, indices_in_leaf, X, y, y_pred, sample_weight, update_mask, residual):
#     def __init__(self, regularization=1.):
#     def fit(self, X, y, sample_weight):
#     def __call__(self, y_pred):
#     def negative_gradient(self, y_pred):
#     def hessian(self, y_pred):
#     def update_tree_leaf(self, leaf, indices_in_leaf, X, y, y_pred, sample_weight, update_mask, residual):
#     def fit(self, X, y, sample_weight):
#     def __call__(self, y_pred):
#     def negative_gradient(self, y_pred):
#     def hessian(self, y_pred):
#     def __init__(self, uniform_variables):
#     def fit(self, X, y, sample_weight):
#     def __call__(self, y_pred):
#     def negative_gradient(self, y_pred):
#     def hessian(self, y_pred):
#     def compute_parameters(self, trainX, trainY):
#     def update_tree(self, tree, X, y, y_pred, sample_weight, update_mask, residual):
#     def update_tree_leaf(self, leaf, indices_in_leaf, X, y, y_pred, sample_weight, update_mask, residual):
#     def __init__(self, uniform_variables, knn=10, uniform_label=1, distinguish_classes=True, row_norm=1.):
#     def compute_parameters(self, trainX, trainY):
# def exp_margin(margin):
#     def __init__(self, uniform_variables, uniform_label=1, power=2., ada_coefficient=1.,
#                  allow_wrong_signs=True, use_median=False,
#                  keep_debug_info=False):
#     def fit(self, X, y, sample_weight=None):
#     def compute_groups_indices(self, X, y, label):
#     def __call__(self, pred):
#     def negative_gradient(self, y_pred):
#     def update_tree_leaf(self, leaf, indices_in_leaf,
#                          X, y, y_pred, sample_weight, update_mask, residual):
#     def __init__(self, uniform_variables, n_bins=10, uniform_label=1, power=2., ada_coefficient=1.,
#                  allow_wrong_signs=True, use_median=False, keep_debug_info=False):
#     def compute_groups_indices(self, X, y, label):
#     def __init__(self, uniform_variables, n_neighbours=100, uniform_label=1, power=2., ada_coefficient=1.,
#                  max_groups_on_iteration=3000, allow_wrong_signs=True, use_median=False, keep_debug_info=False,
#                  random_state=None):
#     def compute_groups_indices(self, X, y, label):
# class AbstractLossFunction(BaseEstimator):
# class AdaLossFunction(AbstractLossFunction):
# class BinomialDevianceLossFunction(AbstractLossFunction):
# class CompositeLossFunction(AbstractLossFunction):
# class AbstractMatrixLossFunction(AbstractLossFunction):
# class SimpleKnnLossFunction(AbstractMatrixLossFunction):
# class AbstractFlatnessLossFunction(AbstractLossFunction):
# class BinFlatnessLossFunction(AbstractFlatnessLossFunction):
# class KnnFlatnessLossFunction(AbstractFlatnessLossFunction):
#         A = sparse.vstack(A_parts, format='csr', dtype=float)
#         X = pandas.DataFrame(X)
# 
# Path: hep_ml/commonutils.py
# def generate_sample(n_samples, n_features, distance=2.0):
#     """Generates some test distribution,
#     signal and background distributions are gaussian with same dispersion and different centers,
#     all variables are independent (gaussian correlation matrix is identity)"""
#     from sklearn.datasets import make_blobs
# 
#     centers = numpy.zeros((2, n_features))
#     centers[0, :] = - distance / 2
#     centers[1, :] = distance / 2
# 
#     X, y = make_blobs(n_samples=n_samples, n_features=n_features, centers=centers)
#     columns = ["column" + str(x) for x in range(n_features)]
#     X = pandas.DataFrame(X, columns=columns)
#     return X, y


# Path: tests/test_losses.py
import numpy
from hep_ml import losses
from hep_ml.commonutils import generate_sample

from __future__ import division, print_function, absolute_import


__author__ = 'Alex Rogozhnikov'


def test_loss_functions(size=50, epsilon=1e-3):
    """
    Testing that hessians and gradients of loss functions coincide with numerical
    """
    X, y = generate_sample(size, n_features=10)
    sample_weight = numpy.random.exponential(size=size)
    tested_losses = [
        losses.BinomialDevianceLossFunction(),
        losses.AdaLossFunction(),

        losses.SimpleKnnLossFunction(X.columns[:1], knn=5),