Skip to content

Commit

Permalink
ENH Add RMSE (root-mean-square error) metric and scorer (#13467)
Browse files Browse the repository at this point in the history
  • Loading branch information
urvang96 authored and rth committed Aug 7, 2019
1 parent 7966207 commit 6425a8f
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 3 deletions.
1 change: 1 addition & 0 deletions doc/modules/model_evaluation.rst
Expand Up @@ -88,6 +88,7 @@ Scoring Function
'max_error' :func:`metrics.max_error`
'neg_mean_absolute_error' :func:`metrics.mean_absolute_error`
'neg_mean_squared_error' :func:`metrics.mean_squared_error`
'neg_root_mean_squared_error' :func:`metrics.mean_squared_error`
'neg_mean_squared_log_error' :func:`metrics.mean_squared_log_error`
'neg_median_absolute_error' :func:`metrics.median_absolute_error`
'r2' :func:`metrics.r2_score`
Expand Down
4 changes: 4 additions & 0 deletions doc/whats_new/v0.22.rst
Expand Up @@ -216,6 +216,10 @@ Changelog
updated to accept the zero and `float('+inf')` value.
:pr:`13231` by :user:`Dong-hee Na <corona10>`.

- |Enhancement| Added parameter ``squared`` in :func:`metrics.mean_squared_error`
to return root mean squared error.
:pr:`13467` by :user:`Urvang Patel <urvang96>`.

:mod:`sklearn.model_selection`
...............................

Expand Down
12 changes: 10 additions & 2 deletions sklearn/metrics/regression.py
Expand Up @@ -191,7 +191,7 @@ def mean_absolute_error(y_true, y_pred,

def mean_squared_error(y_true, y_pred,
sample_weight=None,
multioutput='uniform_average'):
multioutput='uniform_average', squared=True):
"""Mean squared error regression loss
Read more in the :ref:`User Guide <mean_squared_error>`.
Expand All @@ -218,6 +218,9 @@ def mean_squared_error(y_true, y_pred,
'uniform_average' :
Errors of all outputs are averaged with uniform weight.
squared : boolean value, optional (default = True)
If True returns MSE value, if False returns RMSE value.
Returns
-------
loss : float or ndarray of floats
Expand All @@ -231,6 +234,10 @@ def mean_squared_error(y_true, y_pred,
>>> y_pred = [2.5, 0.0, 2, 8]
>>> mean_squared_error(y_true, y_pred)
0.375
>>> y_true = [3, -0.5, 2, 7]
>>> y_pred = [2.5, 0.0, 2, 8]
>>> mean_squared_error(y_true, y_pred, squared=False)
0.612...
>>> y_true = [[0.5, 1],[-1, 1],[7, -6]]
>>> y_pred = [[0, 2],[-1, 2],[8, -5]]
>>> mean_squared_error(y_true, y_pred)
Expand All @@ -253,7 +260,8 @@ def mean_squared_error(y_true, y_pred,
# pass None as weights to np.average: uniform mean
multioutput = None

return np.average(output_errors, weights=multioutput)
mse = np.average(output_errors, weights=multioutput)
return mse if squared else np.sqrt(mse)


def mean_squared_log_error(y_true, y_pred,
Expand Down
4 changes: 4 additions & 0 deletions sklearn/metrics/scorer.py
Expand Up @@ -495,6 +495,9 @@ def make_scorer(score_func, greater_is_better=True, needs_proba=False,
greater_is_better=False)
neg_median_absolute_error_scorer = make_scorer(median_absolute_error,
greater_is_better=False)
neg_root_mean_squared_error_scorer = make_scorer(mean_squared_error,
greater_is_better=False,
squared=False)
neg_mean_poisson_deviance_scorer = make_scorer(
mean_tweedie_deviance, p=1., greater_is_better=False
)
Expand Down Expand Up @@ -549,6 +552,7 @@ def make_scorer(score_func, greater_is_better=True, needs_proba=False,
neg_mean_absolute_error=neg_mean_absolute_error_scorer,
neg_mean_squared_error=neg_mean_squared_error_scorer,
neg_mean_squared_log_error=neg_mean_squared_log_error_scorer,
neg_root_mean_squared_error=neg_root_mean_squared_error_scorer,
neg_mean_poisson_deviance=neg_mean_poisson_deviance_scorer,
neg_mean_gamma_deviance=neg_mean_gamma_deviance_scorer,
accuracy=accuracy_scorer, roc_auc=roc_auc_scorer,
Expand Down
7 changes: 7 additions & 0 deletions sklearn/metrics/tests/test_regression.py
Expand Up @@ -64,6 +64,9 @@ def test_multioutput_regression():
error = mean_squared_error(y_true, y_pred)
assert_almost_equal(error, (1. / 3 + 2. / 3 + 2. / 3) / 4.)

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

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

Expand All @@ -80,6 +83,7 @@ def test_multioutput_regression():

def test_regression_metrics_at_limits():
assert_almost_equal(mean_squared_error([0.], [0.]), 0.00, 2)
assert_almost_equal(mean_squared_error([0.], [0.], squared=False), 0.00, 2)
assert_almost_equal(mean_squared_log_error([0.], [0.]), 0.00, 2)
assert_almost_equal(mean_absolute_error([0.], [0.]), 0.00, 2)
assert_almost_equal(median_absolute_error([0.], [0.]), 0.00, 2)
Expand Down Expand Up @@ -231,11 +235,14 @@ def test_regression_custom_weights():
y_pred = [[1, 1], [2, -1], [5, 4], [5, 6.5]]

msew = mean_squared_error(y_true, y_pred, multioutput=[0.4, 0.6])
rmsew = mean_squared_error(y_true, y_pred, multioutput=[0.4, 0.6],
squared=False)
maew = mean_absolute_error(y_true, y_pred, multioutput=[0.4, 0.6])
rw = r2_score(y_true, y_pred, multioutput=[0.4, 0.6])
evsw = explained_variance_score(y_true, y_pred, multioutput=[0.4, 0.6])

assert_almost_equal(msew, 0.39, decimal=2)
assert_almost_equal(rmsew, 0.62, decimal=2)
assert_almost_equal(maew, 0.475, decimal=3)
assert_almost_equal(rw, 0.94, decimal=2)
assert_almost_equal(evsw, 0.94, decimal=2)
Expand Down
4 changes: 3 additions & 1 deletion sklearn/metrics/tests/test_score_objects.py
Expand Up @@ -41,7 +41,9 @@
REGRESSION_SCORERS = ['explained_variance', 'r2',
'neg_mean_absolute_error', 'neg_mean_squared_error',
'neg_mean_squared_log_error',
'neg_median_absolute_error', 'mean_absolute_error',
'neg_median_absolute_error',
'neg_root_mean_squared_error',
'mean_absolute_error',
'mean_squared_error', 'median_absolute_error',
'max_error', 'neg_mean_poisson_deviance',
'neg_mean_gamma_deviance']
Expand Down

0 comments on commit 6425a8f

Please sign in to comment.