From 8a3532f57dc9804c00ec73abe93d7a843de0a84a Mon Sep 17 00:00:00 2001 From: martincousi Date: Mon, 26 Mar 2018 16:45:55 -0400 Subject: [PATCH 1/2] added asym_rmse and asym_mae --- surprise/accuracy.py | 75 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/surprise/accuracy.py b/surprise/accuracy.py index 1e9e4855..04ffca0f 100644 --- a/surprise/accuracy.py +++ b/surprise/accuracy.py @@ -88,6 +88,81 @@ def mae(predictions, verbose=True): return mae_ +def asym_rmse(predictions, weight=0.5, verbose=True): + """Compute Asymmetric RMSE (Root Mean Squared Error). + + .. math:: + \\text{Asymmetric RMSE} = \\sqrt{\\frac{1}{|\\hat{R}|} + \\sum_{\\hat{r}_{ui} \in \\hat{R}}(r_{ui} - \\hat{r}_{ui})^2 |\\omega + - 1_{r_{ui} - \\hat{r}_{ui} < 0}|}. + + Args: + predictions (:obj:`list` of :obj:`Prediction\ + `): + A list of predictions, as returned by the :meth:`test() + ` method. + weight (int): Weight used to characterize asymmetry. + verbose: If True, will print computed value. Default is ``True``. + + + Returns: + The Asymmetric Root Mean Squared Error of predictions. + + Raises: + ValueError: When ``predictions`` is empty. + """ + + if not predictions: + raise ValueError('Prediction list is empty.') + + res = np.array([float(true_r - est) + for (_, _, true_r, est, _) in predictions]) + asym_rmse_ = np.sqrt(np.mean(res**2 * np.abs(weight - + (res<0).astype(int)))) + + if verbose: + print('Asymmetric RMSE: {0:1.4f}'.format(asym_rmse_)) + + return asym_rmse_ + + +def asym_mae(predictions, weight=0.5, verbose=True): + """Compute Asymmetric MAE (Mean Absolute Error). + + .. math:: + \\text{Asymmetric MAE} = \\frac{1}{|\\hat{R}|} \\sum_{\\hat{r}_{ui} \in + \\hat{R}}|r_{ui} - \\hat{r}_{ui}| |\\omega - 1_{r_{ui} - \\hat{r}_{ui} + < 0}|. + + Args: + predictions (:obj:`list` of :obj:`Prediction\ + `): + A list of predictions, as returned by the :meth:`test() + ` method. + weight (int): Weight used to characterize asymmetry. + verbose: If True, will print computed value. Default is ``True``. + + + Returns: + The Asymmetric Mean Absolute Error of predictions. + + Raises: + ValueError: When ``predictions`` is empty. + """ + + if not predictions: + raise ValueError('Prediction list is empty.') + + res = np.array([float(true_r - est) + for (_, _, true_r, est, _) in predictions]) + asym_mae_ = np.mean(np.abs(res) * np.abs(weight - (res<0).astype(int))) + + if verbose: + print('Asymmetric MAE: {0:1.4f}'.format(asym_mae_)) + + return asym_mae_ + + def fcp(predictions, verbose=True): """Compute FCP (Fraction of Concordant Pairs). From 93690015a0c4ec40a0c544c465fc42c05a4f85e3 Mon Sep 17 00:00:00 2001 From: martincousi Date: Thu, 29 Mar 2018 07:31:15 -0400 Subject: [PATCH 2/2] pep8 issues --- surprise/accuracy.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/surprise/accuracy.py b/surprise/accuracy.py index 04ffca0f..99a7bc53 100644 --- a/surprise/accuracy.py +++ b/surprise/accuracy.py @@ -92,8 +92,8 @@ def asym_rmse(predictions, weight=0.5, verbose=True): """Compute Asymmetric RMSE (Root Mean Squared Error). .. math:: - \\text{Asymmetric RMSE} = \\sqrt{\\frac{1}{|\\hat{R}|} - \\sum_{\\hat{r}_{ui} \in \\hat{R}}(r_{ui} - \\hat{r}_{ui})^2 |\\omega + \\text{Asymmetric RMSE} = \\sqrt{\\frac{1}{|\\hat{R}|} + \\sum_{\\hat{r}_{ui} \in \\hat{R}}(r_{ui} - \\hat{r}_{ui})^2 |\\omega - 1_{r_{ui} - \\hat{r}_{ui} < 0}|}. Args: @@ -117,8 +117,8 @@ def asym_rmse(predictions, weight=0.5, verbose=True): res = np.array([float(true_r - est) for (_, _, true_r, est, _) in predictions]) - asym_rmse_ = np.sqrt(np.mean(res**2 * np.abs(weight - - (res<0).astype(int)))) + asym_rmse_ = np.sqrt(np.mean(res**2 * np.abs(weight - + (res < 0).astype(int)))) if verbose: print('Asymmetric RMSE: {0:1.4f}'.format(asym_rmse_)) @@ -131,7 +131,7 @@ def asym_mae(predictions, weight=0.5, verbose=True): .. math:: \\text{Asymmetric MAE} = \\frac{1}{|\\hat{R}|} \\sum_{\\hat{r}_{ui} \in - \\hat{R}}|r_{ui} - \\hat{r}_{ui}| |\\omega - 1_{r_{ui} - \\hat{r}_{ui} + \\hat{R}}|r_{ui} - \\hat{r}_{ui}| |\\omega - 1_{r_{ui} - \\hat{r}_{ui} < 0}|. Args: @@ -155,7 +155,7 @@ def asym_mae(predictions, weight=0.5, verbose=True): res = np.array([float(true_r - est) for (_, _, true_r, est, _) in predictions]) - asym_mae_ = np.mean(np.abs(res) * np.abs(weight - (res<0).astype(int))) + asym_mae_ = np.mean(np.abs(res) * np.abs(weight - (res < 0).astype(int))) if verbose: print('Asymmetric MAE: {0:1.4f}'.format(asym_mae_))