def test_regression_metrics(n_samples=50):
    y_true = np.arange(n_samples)
    y_pred = y_true + 1
    y_pred_2 = y_true - 1

    assert_almost_equal(mean_squared_error(y_true, y_pred), 1.0)
    assert_almost_equal(
        mean_squared_log_error(y_true, y_pred),
        mean_squared_error(np.log(1 + y_true), np.log(1 + y_pred)),
    )
    assert_almost_equal(mean_absolute_error(y_true, y_pred), 1.0)
    assert_almost_equal(mean_pinball_loss(y_true, y_pred), 0.5)
    assert_almost_equal(mean_pinball_loss(y_true, y_pred_2), 0.5)
    assert_almost_equal(mean_pinball_loss(y_true, y_pred, alpha=0.4), 0.6)
    assert_almost_equal(mean_pinball_loss(y_true, y_pred_2, alpha=0.4), 0.4)
    assert_almost_equal(median_absolute_error(y_true, y_pred), 1.0)
    mape = mean_absolute_percentage_error(y_true, y_pred)
    assert np.isfinite(mape)
    assert mape > 1e6
    assert_almost_equal(max_error(y_true, y_pred), 1.0)
    assert_almost_equal(r2_score(y_true, y_pred), 0.995, 2)
    assert_almost_equal(explained_variance_score(y_true, y_pred), 1.0)
    assert_almost_equal(
        mean_tweedie_deviance(y_true, y_pred, power=0),
        mean_squared_error(y_true, y_pred),
    )
    assert_almost_equal(d2_tweedie_score(y_true, y_pred, power=0),
                        r2_score(y_true, y_pred))

    # Tweedie deviance needs positive y_pred, except for p=0,
    # p>=2 needs positive y_true
    # results evaluated by sympy
    y_true = np.arange(1, 1 + n_samples)
    y_pred = 2 * y_true
    n = n_samples
    assert_almost_equal(
        mean_tweedie_deviance(y_true, y_pred, power=-1),
        5 / 12 * n * (n**2 + 2 * n + 1),
    )
    assert_almost_equal(mean_tweedie_deviance(y_true, y_pred, power=1),
                        (n + 1) * (1 - np.log(2)))
    assert_almost_equal(mean_tweedie_deviance(y_true, y_pred, power=2),
                        2 * np.log(2) - 1)
    assert_almost_equal(
        mean_tweedie_deviance(y_true, y_pred, power=3 / 2),
        ((6 * np.sqrt(2) - 8) / n) * np.sqrt(y_true).sum(),
    )
    assert_almost_equal(mean_tweedie_deviance(y_true, y_pred, power=3),
                        np.sum(1 / y_true) / (4 * n))

    dev_mean = 2 * np.mean(xlogy(y_true, 2 * y_true / (n + 1)))
    assert_almost_equal(
        d2_tweedie_score(y_true, y_pred, power=1),
        1 - (n + 1) * (1 - np.log(2)) / dev_mean,
    )

    dev_mean = 2 * np.log((n + 1) / 2) - 2 / n * np.log(factorial(n))
    assert_almost_equal(d2_tweedie_score(y_true, y_pred, power=2),
                        1 - (2 * np.log(2) - 1) / dev_mean)
Beispiel #2
0
def test_mean_pinball_loss_on_constant_predictions(distribution,
                                                   target_quantile):
    if not hasattr(np, "quantile"):
        pytest.skip("This test requires a more recent version of numpy "
                    "with support for np.quantile.")

    # Check that the pinball loss is minimized by the empirical quantile.
    n_samples = 3000
    rng = np.random.RandomState(42)
    data = getattr(rng, distribution)(size=n_samples)

    # Compute the best possible pinball loss for any constant predictor:
    best_pred = np.quantile(data, target_quantile)
    best_constant_pred = np.full(n_samples, fill_value=best_pred)
    best_pbl = mean_pinball_loss(data,
                                 best_constant_pred,
                                 alpha=target_quantile)

    # Evaluate the loss on a grid of quantiles
    candidate_predictions = np.quantile(data, np.linspace(0, 1, 100))
    for pred in candidate_predictions:
        # Compute the pinball loss of a constant predictor:
        constant_pred = np.full(n_samples, fill_value=pred)
        pbl = mean_pinball_loss(data, constant_pred, alpha=target_quantile)

        # Check that the loss of this constant predictor is greater or equal
        # than the loss of using the optimal quantile (up to machine
        # precision):
        assert pbl >= best_pbl - np.finfo(best_pbl.dtype).eps

        # Check that the value of the pinball loss matches the analytical
        # formula.
        expected_pbl = (pred - data[data < pred]).sum() * (
            1 - target_quantile) + (data[data >= pred] -
                                    pred).sum() * target_quantile
        expected_pbl /= n_samples
        assert_almost_equal(expected_pbl, pbl)

    # Check that we can actually recover the target_quantile by minimizing the
    # pinball loss w.r.t. the constant prediction quantile.
    def objective_func(x):
        constant_pred = np.full(n_samples, fill_value=x)
        return mean_pinball_loss(data, constant_pred, alpha=target_quantile)

    result = optimize.minimize(objective_func,
                               data.mean(),
                               method="Nelder-Mead")
    assert result.success
    # The minimum is not unique with limited data, hence the large tolerance.
    assert result.x == pytest.approx(best_pred, rel=1e-2)
    assert result.fun == pytest.approx(best_pbl)
Beispiel #3
0
def test_multioutput_regression():
    y_true = np.array([[1, 0, 0, 1], [0, 1, 1, 1], [1, 1, 0, 1]])
    y_pred = np.array([[0, 0, 0, 1], [1, 0, 1, 1], [0, 0, 0, 1]])

    error = mean_squared_error(y_true, y_pred)
    assert_almost_equal(error, (1.0 / 3 + 2.0 / 3 + 2.0 / 3) / 4.0)

    error = mean_squared_error(y_true, y_pred, squared=False)
    assert_almost_equal(error, 0.454, decimal=2)

    error = mean_squared_log_error(y_true, y_pred)
    assert_almost_equal(error, 0.200, decimal=2)

    # mean_absolute_error and mean_squared_error are equal because
    # it is a binary problem.
    error = mean_absolute_error(y_true, y_pred)
    assert_almost_equal(error, (1.0 + 2.0 / 3) / 4.0)

    error = mean_pinball_loss(y_true, y_pred)
    assert_almost_equal(error, (1.0 + 2.0 / 3) / 8.0)

    error = np.around(mean_absolute_percentage_error(y_true, y_pred),
                      decimals=2)
    assert np.isfinite(error)
    assert error > 1e6
    error = median_absolute_error(y_true, y_pred)
    assert_almost_equal(error, (1.0 + 1.0) / 4.0)

    error = r2_score(y_true, y_pred, multioutput="variance_weighted")
    assert_almost_equal(error, 1.0 - 5.0 / 2)
    error = r2_score(y_true, y_pred, multioutput="uniform_average")
    assert_almost_equal(error, -0.875)
def test_lad_equals_quantiles(seed, alpha):
    # Make sure quantile loss with alpha = .5 is equivalent to LAD
    lad = LeastAbsoluteError()
    ql = QuantileLossFunction(alpha=alpha)

    n_samples = 50
    rng = np.random.RandomState(seed)
    raw_predictions = rng.normal(size=(n_samples))
    y_true = rng.normal(size=(n_samples))

    lad_loss = lad(y_true, raw_predictions)
    ql_loss = ql(y_true, raw_predictions)
    if alpha == 0.5:
        assert lad_loss == approx(2 * ql_loss)

    weights = np.linspace(0, 1, n_samples)**2
    lad_weighted_loss = lad(y_true, raw_predictions, sample_weight=weights)
    ql_weighted_loss = ql(y_true, raw_predictions, sample_weight=weights)
    if alpha == 0.5:
        assert lad_weighted_loss == approx(2 * ql_weighted_loss)
    pbl_weighted_loss = mean_pinball_loss(y_true,
                                          raw_predictions,
                                          sample_weight=weights,
                                          alpha=alpha)
    assert pbl_weighted_loss == approx(ql_weighted_loss)
Beispiel #5
0
def test_pinball_loss_relation_with_mae():
    # Test that mean_pinball loss with alpha=0.5 if half of mean absolute error
    rng = np.random.RandomState(714)
    n = 100
    y_true = rng.normal(size=n)
    y_pred = y_true.copy() + rng.uniform(n)
    assert (mean_absolute_error(
        y_true, y_pred) == mean_pinball_loss(y_true, y_pred, alpha=0.5) * 2)
def test_quantile_loss_function():
    # Non regression test for the QuantileLossFunction object
    # There was a sign problem when evaluating the function
    # for negative values of 'ytrue - ypred'
    x = np.asarray([-1.0, 0.0, 1.0])
    y_found = QuantileLossFunction(0.9)(x, np.zeros_like(x))
    y_expected = np.asarray([0.1, 0.0, 0.9]).mean()
    np.testing.assert_allclose(y_found, y_expected)
    y_found_p = mean_pinball_loss(x, np.zeros_like(x), alpha=0.9)
    np.testing.assert_allclose(y_found, y_found_p)
# Measure the models with :func:`mean_squared_error` and
# :func:`mean_pinball_loss` metrics on the training dataset.
import pandas as pd


def highlight_min(x):
    x_min = x.min()
    return ["font-weight: bold" if v == x_min else "" for v in x]


results = []
for name, gbr in sorted(all_models.items()):
    metrics = {"model": name}
    y_pred = gbr.predict(X_train)
    for alpha in [0.05, 0.5, 0.95]:
        metrics["pbl=%1.2f" % alpha] = mean_pinball_loss(y_train, y_pred, alpha=alpha)
    metrics["MSE"] = mean_squared_error(y_train, y_pred)
    results.append(metrics)

pd.DataFrame(results).set_index("model").style.apply(highlight_min)

# %%
# One column shows all models evaluated by the same metric. The minimum number
# on a column should be obtained when the model is trained and measured with
# the same metric. This should be always the case on the training set if the
# training converged.
#
# Note that because the target distribution is asymmetric, the expected
# conditional mean and conditional median are signficiantly different and
# therefore one could not use the squared error model get a good estimation of
# the conditional median nor the converse.
Beispiel #8
0
 def objective_func(x):
     constant_pred = np.full(n_samples, fill_value=x)
     return mean_pinball_loss(data, constant_pred, alpha=target_quantile)
Beispiel #9
0
def test_regression_multioutput_array():
    y_true = [[1, 2], [2.5, -1], [4.5, 3], [5, 7]]
    y_pred = [[1, 1], [2, -1], [5, 4], [5, 6.5]]

    mse = mean_squared_error(y_true, y_pred, multioutput="raw_values")
    mae = mean_absolute_error(y_true, y_pred, multioutput="raw_values")
    err_msg = ("multioutput is expected to be 'raw_values' "
               "or 'uniform_average' but we got 'variance_weighted' instead.")
    with pytest.raises(ValueError, match=err_msg):
        mean_pinball_loss(y_true, y_pred, multioutput="variance_weighted")

    with pytest.raises(ValueError, match=err_msg):
        d2_pinball_score(y_true, y_pred, multioutput="variance_weighted")

    pbl = mean_pinball_loss(y_true, y_pred, multioutput="raw_values")
    mape = mean_absolute_percentage_error(y_true,
                                          y_pred,
                                          multioutput="raw_values")
    r = r2_score(y_true, y_pred, multioutput="raw_values")
    evs = explained_variance_score(y_true, y_pred, multioutput="raw_values")
    d2ps = d2_pinball_score(y_true,
                            y_pred,
                            alpha=0.5,
                            multioutput="raw_values")
    evs2 = explained_variance_score(y_true,
                                    y_pred,
                                    multioutput="raw_values",
                                    force_finite=False)

    assert_array_almost_equal(mse, [0.125, 0.5625], decimal=2)
    assert_array_almost_equal(mae, [0.25, 0.625], decimal=2)
    assert_array_almost_equal(pbl, [0.25 / 2, 0.625 / 2], decimal=2)
    assert_array_almost_equal(mape, [0.0778, 0.2262], decimal=2)
    assert_array_almost_equal(r, [0.95, 0.93], decimal=2)
    assert_array_almost_equal(evs, [0.95, 0.93], decimal=2)
    assert_array_almost_equal(d2ps, [0.833, 0.722], decimal=2)
    assert_array_almost_equal(evs2, [0.95, 0.93], decimal=2)

    # mean_absolute_error and mean_squared_error are equal because
    # it is a binary problem.
    y_true = [[0, 0]] * 4
    y_pred = [[1, 1]] * 4
    mse = mean_squared_error(y_true, y_pred, multioutput="raw_values")
    mae = mean_absolute_error(y_true, y_pred, multioutput="raw_values")
    pbl = mean_pinball_loss(y_true, y_pred, multioutput="raw_values")
    r = r2_score(y_true, y_pred, multioutput="raw_values")
    d2ps = d2_pinball_score(y_true, y_pred, multioutput="raw_values")
    assert_array_almost_equal(mse, [1.0, 1.0], decimal=2)
    assert_array_almost_equal(mae, [1.0, 1.0], decimal=2)
    assert_array_almost_equal(pbl, [0.5, 0.5], decimal=2)
    assert_array_almost_equal(r, [0.0, 0.0], decimal=2)
    assert_array_almost_equal(d2ps, [0.0, 0.0], decimal=2)

    r = r2_score([[0, -1], [0, 1]], [[2, 2], [1, 1]], multioutput="raw_values")
    assert_array_almost_equal(r, [0, -3.5], decimal=2)
    assert np.mean(r) == r2_score([[0, -1], [0, 1]], [[2, 2], [1, 1]],
                                  multioutput="uniform_average")
    evs = explained_variance_score([[0, -1], [0, 1]], [[2, 2], [1, 1]],
                                   multioutput="raw_values")
    assert_array_almost_equal(evs, [0, -1.25], decimal=2)
    evs2 = explained_variance_score(
        [[0, -1], [0, 1]],
        [[2, 2], [1, 1]],
        multioutput="raw_values",
        force_finite=False,
    )
    assert_array_almost_equal(evs2, [-np.inf, -1.25], decimal=2)

    # Checking for the condition in which both numerator and denominator is
    # zero.
    y_true = [[1, 3], [1, 2]]
    y_pred = [[1, 4], [1, 1]]
    r2 = r2_score(y_true, y_pred, multioutput="raw_values")
    assert_array_almost_equal(r2, [1.0, -3.0], decimal=2)
    assert np.mean(r2) == r2_score(y_true,
                                   y_pred,
                                   multioutput="uniform_average")
    r22 = r2_score(y_true,
                   y_pred,
                   multioutput="raw_values",
                   force_finite=False)
    assert_array_almost_equal(r22, [np.nan, -3.0], decimal=2)
    assert_almost_equal(
        np.mean(r22),
        r2_score(y_true,
                 y_pred,
                 multioutput="uniform_average",
                 force_finite=False),
    )

    evs = explained_variance_score(y_true, y_pred, multioutput="raw_values")
    assert_array_almost_equal(evs, [1.0, -3.0], decimal=2)
    assert np.mean(evs) == explained_variance_score(y_true, y_pred)
    d2ps = d2_pinball_score(y_true,
                            y_pred,
                            alpha=0.5,
                            multioutput="raw_values")
    assert_array_almost_equal(d2ps, [1.0, -1.0], decimal=2)
    evs2 = explained_variance_score(y_true,
                                    y_pred,
                                    multioutput="raw_values",
                                    force_finite=False)
    assert_array_almost_equal(evs2, [np.nan, -3.0], decimal=2)
    assert_almost_equal(
        np.mean(evs2),
        explained_variance_score(y_true, y_pred, force_finite=False))

    # Handling msle separately as it does not accept negative inputs.
    y_true = np.array([[0.5, 1], [1, 2], [7, 6]])
    y_pred = np.array([[0.5, 2], [1, 2.5], [8, 8]])
    msle = mean_squared_log_error(y_true, y_pred, multioutput="raw_values")
    msle2 = mean_squared_error(np.log(1 + y_true),
                               np.log(1 + y_pred),
                               multioutput="raw_values")
    assert_array_almost_equal(msle, msle2, decimal=2)
Beispiel #10
0
def test_regression_metrics_at_limits():
    # Single-sample case
    # Note: for r2 and d2_tweedie see also test_regression_single_sample
    assert_almost_equal(mean_squared_error([0.0], [0.0]), 0.0)
    assert_almost_equal(mean_squared_error([0.0], [0.0], squared=False), 0.0)
    assert_almost_equal(mean_squared_log_error([0.0], [0.0]), 0.0)
    assert_almost_equal(mean_absolute_error([0.0], [0.0]), 0.0)
    assert_almost_equal(mean_pinball_loss([0.0], [0.0]), 0.0)
    assert_almost_equal(mean_absolute_percentage_error([0.0], [0.0]), 0.0)
    assert_almost_equal(median_absolute_error([0.0], [0.0]), 0.0)
    assert_almost_equal(max_error([0.0], [0.0]), 0.0)
    assert_almost_equal(explained_variance_score([0.0], [0.0]), 1.0)

    # Perfect cases
    assert_almost_equal(r2_score([0.0, 1], [0.0, 1]), 1.0)
    assert_almost_equal(d2_pinball_score([0.0, 1], [0.0, 1]), 1.0)

    # Non-finite cases
    # R² and explained variance have a fix by default for non-finite cases
    for s in (r2_score, explained_variance_score):
        assert_almost_equal(s([0, 0], [1, -1]), 0.0)
        assert_almost_equal(s([0, 0], [1, -1], force_finite=False), -np.inf)
        assert_almost_equal(s([1, 1], [1, 1]), 1.0)
        assert_almost_equal(s([1, 1], [1, 1], force_finite=False), np.nan)
    msg = ("Mean Squared Logarithmic Error cannot be used when targets "
           "contain negative values.")
    with pytest.raises(ValueError, match=msg):
        mean_squared_log_error([-1.0], [-1.0])
    msg = ("Mean Squared Logarithmic Error cannot be used when targets "
           "contain negative values.")
    with pytest.raises(ValueError, match=msg):
        mean_squared_log_error([1.0, 2.0, 3.0], [1.0, -2.0, 3.0])
    msg = ("Mean Squared Logarithmic Error cannot be used when targets "
           "contain negative values.")
    with pytest.raises(ValueError, match=msg):
        mean_squared_log_error([1.0, -2.0, 3.0], [1.0, 2.0, 3.0])

    # Tweedie deviance error
    power = -1.2
    assert_allclose(mean_tweedie_deviance([0], [1.0], power=power),
                    2 / (2 - power),
                    rtol=1e-3)
    msg = "can only be used on strictly positive y_pred."
    with pytest.raises(ValueError, match=msg):
        mean_tweedie_deviance([0.0], [0.0], power=power)
    with pytest.raises(ValueError, match=msg):
        d2_tweedie_score([0.0] * 2, [0.0] * 2, power=power)

    assert_almost_equal(mean_tweedie_deviance([0.0], [0.0], power=0), 0.0, 2)

    power = 1.0
    msg = "only be used on non-negative y and strictly positive y_pred."
    with pytest.raises(ValueError, match=msg):
        mean_tweedie_deviance([0.0], [0.0], power=power)
    with pytest.raises(ValueError, match=msg):
        d2_tweedie_score([0.0] * 2, [0.0] * 2, power=power)

    power = 1.5
    assert_allclose(mean_tweedie_deviance([0.0], [1.0], power=power),
                    2 / (2 - power))
    msg = "only be used on non-negative y and strictly positive y_pred."
    with pytest.raises(ValueError, match=msg):
        mean_tweedie_deviance([0.0], [0.0], power=power)
    with pytest.raises(ValueError, match=msg):
        d2_tweedie_score([0.0] * 2, [0.0] * 2, power=power)

    power = 2.0
    assert_allclose(mean_tweedie_deviance([1.0], [1.0], power=power),
                    0.00,
                    atol=1e-8)
    msg = "can only be used on strictly positive y and y_pred."
    with pytest.raises(ValueError, match=msg):
        mean_tweedie_deviance([0.0], [0.0], power=power)
    with pytest.raises(ValueError, match=msg):
        d2_tweedie_score([0.0] * 2, [0.0] * 2, power=power)

    power = 3.0
    assert_allclose(mean_tweedie_deviance([1.0], [1.0], power=power),
                    0.00,
                    atol=1e-8)
    msg = "can only be used on strictly positive y and y_pred."
    with pytest.raises(ValueError, match=msg):
        mean_tweedie_deviance([0.0], [0.0], power=power)
    with pytest.raises(ValueError, match=msg):
        d2_tweedie_score([0.0] * 2, [0.0] * 2, power=power)

    power = 0.5
    with pytest.raises(ValueError,
                       match="is only defined for power<=0 and power>=1"):
        mean_tweedie_deviance([0.0], [0.0], power=power)
    with pytest.raises(ValueError,
                       match="is only defined for power<=0 and power>=1"):
        d2_tweedie_score([0.0] * 2, [0.0] * 2, power=power)
Beispiel #11
0
def test_multioutput_regression():
    y_true = np.array([[1, 0, 0, 1], [0, 1, 1, 1], [1, 1, 0, 1]])
    y_pred = np.array([[0, 0, 0, 1], [1, 0, 1, 1], [0, 0, 0, 1]])

    error = mean_squared_error(y_true, y_pred)
    assert_almost_equal(error, (1.0 / 3 + 2.0 / 3 + 2.0 / 3) / 4.0)

    error = mean_squared_error(y_true, y_pred, squared=False)
    assert_almost_equal(error, 0.454, decimal=2)

    error = mean_squared_log_error(y_true, y_pred)
    assert_almost_equal(error, 0.200, decimal=2)

    # mean_absolute_error and mean_squared_error are equal because
    # it is a binary problem.
    error = mean_absolute_error(y_true, y_pred)
    assert_almost_equal(error, (1.0 + 2.0 / 3) / 4.0)

    error = mean_pinball_loss(y_true, y_pred)
    assert_almost_equal(error, (1.0 + 2.0 / 3) / 8.0)

    error = np.around(mean_absolute_percentage_error(y_true, y_pred),
                      decimals=2)
    assert np.isfinite(error)
    assert error > 1e6
    error = median_absolute_error(y_true, y_pred)
    assert_almost_equal(error, (1.0 + 1.0) / 4.0)

    error = r2_score(y_true, y_pred, multioutput="variance_weighted")
    assert_almost_equal(error, 1.0 - 5.0 / 2)
    error = r2_score(y_true, y_pred, multioutput="uniform_average")
    assert_almost_equal(error, -0.875)

    score = d2_pinball_score(y_true,
                             y_pred,
                             alpha=0.5,
                             multioutput="raw_values")
    raw_expected_score = [
        1 - np.abs(y_true[:, i] - y_pred[:, i]).sum() /
        np.abs(y_true[:, i] - np.median(y_true[:, i])).sum()
        for i in range(y_true.shape[1])
    ]
    # in the last case, the denominator vanishes and hence we get nan,
    # but since the numerator vanishes as well the expected score is 1.0
    raw_expected_score = np.where(np.isnan(raw_expected_score), 1,
                                  raw_expected_score)
    assert_array_almost_equal(score, raw_expected_score)

    score = d2_pinball_score(y_true,
                             y_pred,
                             alpha=0.5,
                             multioutput="uniform_average")
    assert_almost_equal(score, raw_expected_score.mean())
    # constant `y_true` with force_finite=True leads to 1. or 0.
    yc = [5.0, 5.0]
    error = r2_score(yc, [5.0, 5.0], multioutput="variance_weighted")
    assert_almost_equal(error, 1.0)
    error = r2_score(yc, [5.0, 5.1], multioutput="variance_weighted")
    assert_almost_equal(error, 0.0)

    # Setting force_finite=False results in the nan for 4th output propagating
    error = r2_score(y_true,
                     y_pred,
                     multioutput="variance_weighted",
                     force_finite=False)
    assert_almost_equal(error, np.nan)
    error = r2_score(y_true,
                     y_pred,
                     multioutput="uniform_average",
                     force_finite=False)
    assert_almost_equal(error, np.nan)

    # Dropping the 4th output to check `force_finite=False` for nominal
    y_true = y_true[:, :-1]
    y_pred = y_pred[:, :-1]
    error = r2_score(y_true, y_pred, multioutput="variance_weighted")
    error2 = r2_score(y_true,
                      y_pred,
                      multioutput="variance_weighted",
                      force_finite=False)
    assert_almost_equal(error, error2)
    error = r2_score(y_true, y_pred, multioutput="uniform_average")
    error2 = r2_score(y_true,
                      y_pred,
                      multioutput="uniform_average",
                      force_finite=False)
    assert_almost_equal(error, error2)

    # constant `y_true` with force_finite=False leads to NaN or -Inf.
    error = r2_score(yc, [5.0, 5.0],
                     multioutput="variance_weighted",
                     force_finite=False)
    assert_almost_equal(error, np.nan)
    error = r2_score(yc, [5.0, 6.0],
                     multioutput="variance_weighted",
                     force_finite=False)
    assert_almost_equal(error, -np.inf)
def test_multioutput_regression():
    y_true = np.array([[1, 0, 0, 1], [0, 1, 1, 1], [1, 1, 0, 1]])
    y_pred = np.array([[0, 0, 0, 1], [1, 0, 1, 1], [0, 0, 0, 1]])

    error = mean_squared_error(y_true, y_pred)
    assert_almost_equal(error, (1.0 / 3 + 2.0 / 3 + 2.0 / 3) / 4.0)

    error = mean_squared_error(y_true, y_pred, squared=False)
    assert_almost_equal(error, 0.454, decimal=2)

    error = mean_squared_log_error(y_true, y_pred)
    assert_almost_equal(error, 0.200, decimal=2)

    # mean_absolute_error and mean_squared_error are equal because
    # it is a binary problem.
    error = mean_absolute_error(y_true, y_pred)
    assert_almost_equal(error, (1.0 + 2.0 / 3) / 4.0)

    error = mean_pinball_loss(y_true, y_pred)
    assert_almost_equal(error, (1.0 + 2.0 / 3) / 8.0)

    error = np.around(mean_absolute_percentage_error(y_true, y_pred), decimals=2)
    assert np.isfinite(error)
    assert error > 1e6
    error = median_absolute_error(y_true, y_pred)
    assert_almost_equal(error, (1.0 + 1.0) / 4.0)

    error = r2_score(y_true, y_pred, multioutput="variance_weighted")
    assert_almost_equal(error, 1.0 - 5.0 / 2)
    error = r2_score(y_true, y_pred, multioutput="uniform_average")
    assert_almost_equal(error, -0.875)

    # constant `y_true` with force_finite=True leads to 1. or 0.
    yc = [5.0, 5.0]
    error = r2_score(yc, [5.0, 5.0], multioutput="variance_weighted")
    assert_almost_equal(error, 1.0)
    error = r2_score(yc, [5.0, 5.1], multioutput="variance_weighted")
    assert_almost_equal(error, 0.0)

    # Setting force_finite=False results in the nan for 4th output propagating
    error = r2_score(
        y_true, y_pred, multioutput="variance_weighted", force_finite=False
    )
    assert_almost_equal(error, np.nan)
    error = r2_score(y_true, y_pred, multioutput="uniform_average", force_finite=False)
    assert_almost_equal(error, np.nan)

    # Dropping the 4th output to check `force_finite=False` for nominal
    y_true = y_true[:, :-1]
    y_pred = y_pred[:, :-1]
    error = r2_score(y_true, y_pred, multioutput="variance_weighted")
    error2 = r2_score(
        y_true, y_pred, multioutput="variance_weighted", force_finite=False
    )
    assert_almost_equal(error, error2)
    error = r2_score(y_true, y_pred, multioutput="uniform_average")
    error2 = r2_score(y_true, y_pred, multioutput="uniform_average", force_finite=False)
    assert_almost_equal(error, error2)

    # constant `y_true` with force_finite=False leads to NaN or -Inf.
    error = r2_score(
        yc, [5.0, 5.0], multioutput="variance_weighted", force_finite=False
    )
    assert_almost_equal(error, np.nan)
    error = r2_score(
        yc, [5.0, 6.0], multioutput="variance_weighted", force_finite=False
    )
    assert_almost_equal(error, -np.inf)
 def func(coef):
     loss = mean_pinball_loss(y, X @ coef[1:] + coef[0], alpha=quantile)
     L1 = np.sum(np.abs(coef[1:]))
     return loss + alpha * L1
Beispiel #14
0
def test_regression_metrics_at_limits():
    assert_almost_equal(mean_squared_error([0.0], [0.0]), 0.0)
    assert_almost_equal(mean_squared_error([0.0], [0.0], squared=False), 0.0)
    assert_almost_equal(mean_squared_log_error([0.0], [0.0]), 0.0)
    assert_almost_equal(mean_absolute_error([0.0], [0.0]), 0.0)
    assert_almost_equal(mean_pinball_loss([0.0], [0.0]), 0.0)
    assert_almost_equal(mean_absolute_percentage_error([0.0], [0.0]), 0.0)
    assert_almost_equal(median_absolute_error([0.0], [0.0]), 0.0)
    assert_almost_equal(max_error([0.0], [0.0]), 0.0)
    assert_almost_equal(explained_variance_score([0.0], [0.0]), 1.0)
    assert_almost_equal(r2_score([0.0, 1], [0.0, 1]), 1.0)
    err_msg = ("Mean Squared Logarithmic Error cannot be used when targets "
               "contain negative values.")
    with pytest.raises(ValueError, match=err_msg):
        mean_squared_log_error([-1.0], [-1.0])
    err_msg = ("Mean Squared Logarithmic Error cannot be used when targets "
               "contain negative values.")
    with pytest.raises(ValueError, match=err_msg):
        mean_squared_log_error([1.0, 2.0, 3.0], [1.0, -2.0, 3.0])
    err_msg = ("Mean Squared Logarithmic Error cannot be used when targets "
               "contain negative values.")
    with pytest.raises(ValueError, match=err_msg):
        mean_squared_log_error([1.0, -2.0, 3.0], [1.0, 2.0, 3.0])

    # Tweedie deviance error
    power = -1.2
    assert_allclose(mean_tweedie_deviance([0], [1.0], power=power),
                    2 / (2 - power),
                    rtol=1e-3)
    with pytest.raises(ValueError,
                       match="can only be used on strictly positive y_pred."):
        mean_tweedie_deviance([0.0], [0.0], power=power)
    assert_almost_equal(mean_tweedie_deviance([0.0], [0.0], power=0), 0.00, 2)

    msg = "only be used on non-negative y and strictly positive y_pred."
    with pytest.raises(ValueError, match=msg):
        mean_tweedie_deviance([0.0], [0.0], power=1.0)

    power = 1.5
    assert_allclose(mean_tweedie_deviance([0.0], [1.0], power=power),
                    2 / (2 - power))
    msg = "only be used on non-negative y and strictly positive y_pred."
    with pytest.raises(ValueError, match=msg):
        mean_tweedie_deviance([0.0], [0.0], power=power)
    power = 2.0
    assert_allclose(mean_tweedie_deviance([1.0], [1.0], power=power),
                    0.00,
                    atol=1e-8)
    msg = "can only be used on strictly positive y and y_pred."
    with pytest.raises(ValueError, match=msg):
        mean_tweedie_deviance([0.0], [0.0], power=power)
    power = 3.0
    assert_allclose(mean_tweedie_deviance([1.0], [1.0], power=power),
                    0.00,
                    atol=1e-8)

    msg = "can only be used on strictly positive y and y_pred."
    with pytest.raises(ValueError, match=msg):
        mean_tweedie_deviance([0.0], [0.0], power=power)

    with pytest.raises(ValueError,
                       match="is only defined for power<=0 and power>=1"):
        mean_tweedie_deviance([0.0], [0.0], power=0.5)