Métriques de régression : MAE, MSE, RMSE et R-Squared
Calculez les métriques d’erreur sur une sortie de régression, comprenez la dépendance de MAE/RMSE à l’échelle et utilisez R-squared comme mesure standardisée de la qualité d’ajustement.
Métriques de régression : MAE, MSE, RMSE et R-Squared est une leçon Machine Learning Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Machine Learning Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Machine Learning Academy comprend 4 leçons au total.
Certaines parties de cette leçon n'ont pas encore été traduites et s'affichent en anglais.
Why Regression Needs Different Metrics
Regression models predict continuous values — house prices, temperatures, sales volumes. Unlike classification, where a prediction is either correct or wrong, regression predictions are almost never exactly right. The question is: how far off is the prediction? Regression metrics quantify the difference between predicted values and actual values. Different metrics weight errors differently: some penalise large errors more than small ones, some are robust to outliers, and some are normalised to be interpretable as a fraction of variance explained. Choosing the right metric depends on the problem's error cost structure.
import numpy as np
y_true = np.array([100, 150, 200, 250, 300], dtype=float)
y_pred = np.array([110, 140, 210, 240, 320], dtype=float)
errors = y_pred - y_true
print('Actual: ', y_true)
print('Predicted:', y_pred)
print('Errors: ', errors) # Some positive, some negative
print('We need metrics that summarise these errors into a single number.')MAE: Mean Absolute Error
MAE = mean(|y_true - y_pred|). Mean Absolute Error computes the average of the absolute differences between predictions and actual values. It is in the same units as the target variable — a house price MAE of $15,000 means predictions are off by $15,000 on average. MAE treats all errors linearly: a prediction that is twice as wrong costs exactly twice as much. MAE is robust to outliers because it does not square errors. It is the recommended metric when the distribution of errors is roughly symmetric and outlier errors should not dominate the aggregate.
import numpy as np
from sklearn.metrics import mean_absolute_error
y_true = np.array([100, 150, 200, 250, 300], dtype=float)
y_pred = np.array([110, 140, 210, 240, 320], dtype=float)
# Manual calculation
mae_manual = np.mean(np.abs(y_true - y_pred))
print('Manual MAE:', mae_manual) # |10|+|10|+|10|+|10|+|20| / 5 = 12
# Sklearn
mae = mean_absolute_error(y_true, y_pred)
print('Sklearn MAE:', mae)
print(f'Interpretation: predictions are off by {mae:.1f} units on average')MSE: Mean Squared Error
MSE = mean((y_true - y_pred)^2). Mean Squared Error squares each error before averaging. This makes MSE sensitive to outliers: a single prediction with error 10 contributes 100 to MSE, while a prediction with error 1 contributes only 1 — outlier errors are amplified quadratically. MSE is the natural loss function for linear regression (minimising MSE gives the ordinary least squares solution). Its units are the square of the target variable (dollars^2 for house prices), making it less interpretable than MAE but mathematically convenient for optimisation.
import numpy as np
from sklearn.metrics import mean_squared_error
y_true = np.array([100, 150, 200, 250, 300], dtype=float)
y_pred = np.array([110, 140, 210, 240, 320], dtype=float)
# Squaring emphasises large errors
errors = y_true - y_pred
print('Squared errors:', errors**2) # 100, 100, 100, 100, 400
mse = mean_squared_error(y_true, y_pred)
print(f'MSE: {mse}') # 160.0
print(f'Units: (target units)^2 -- less interpretable than MAE')
print(f'The large error at last sample contributes 400/5=80 to MSE alone')RMSE: Root Mean Squared Error
RMSE = sqrt(MSE). Root Mean Squared Error brings MSE back to the original units of the target variable (dollars, not dollars^2) by taking the square root. It is the most widely reported regression metric because it is interpretable in the same units as the target while still penalising large errors more than small ones. An RMSE of $20,000 for house prices means the typical error magnitude is $20,000, though outlier errors are weighted more heavily than in MAE. RMSE is always >= MAE for the same predictions; the gap between them increases when outlier errors are present.
import numpy as np
from sklearn.metrics import mean_squared_error
y_true = np.array([100, 150, 200, 250, 300], dtype=float)
y_pred = np.array([110, 140, 210, 240, 320], dtype=float)
mse = mean_squared_error(y_true, y_pred)
rmse = np.sqrt(mse)
print(f'MSE: {mse:.2f} (units: target^2)')
print(f'RMSE: {rmse:.2f} (units: same as target)')
# RMSE always >= MAE
from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(y_true, y_pred)
print(f'MAE: {mae:.2f}')
print(f'MAE <= RMSE: {mae <= rmse}')MAE vs RMSE: When to Use Which
Choose MAE when: outliers are expected and you do not want them to dominate the metric; you want a metric that is easily interpretable as the average error; errors of different sizes are equally important proportionally. Choose RMSE when: large errors are much more costly than small ones (e.g., predicting power demand — being off by 10x is far more costly than being off by 1x); the loss function used in training is MSE and you want evaluation to match training; variance in predictions matters more than median error. In practice, always report both MAE and RMSE — if RMSE >> MAE, outlier errors dominate; if RMSE ≈ MAE, errors are uniformly distributed.
import numpy as np
from sklearn.metrics import mean_absolute_error, mean_squared_error
# Two prediction sets with same MAE but different RMSE
y_true = np.array([100.0, 200.0, 300.0, 400.0, 500.0])
# Set 1: uniform errors of 10
pred1 = y_true + 10
# Set 2: mostly 0 error, one huge error of 50
pred2 = y_true.copy()
pred2[-1] += 50
pred2[0:4] += 0
for name, pred in [('Uniform errors', pred1), ('One outlier error', pred2)]:
mae = mean_absolute_error(y_true, pred)
rmse = np.sqrt(mean_squared_error(y_true, pred))
print(f'{name}: MAE={mae:.2f}, RMSE={rmse:.2f}')R-Squared: Coefficient of Determination
R^2 = 1 - MSE(model) / Var(y_true). R-squared measures the fraction of variance in the target explained by the model. R^2 = 1.0 means perfect predictions (zero residual variance). R^2 = 0.0 means the model is no better than predicting the mean of y for every sample. R^2 can be negative if the model is worse than the mean baseline. R^2 is scale-independent — a value of 0.85 means the same thing whether the target is house prices or temperatures. This makes it the primary metric for comparing regression models across different problems or scales.
import numpy as np
from sklearn.metrics import r2_score
y_true = np.array([100, 150, 200, 250, 300], dtype=float)
y_pred = np.array([110, 140, 210, 240, 320], dtype=float)
y_mean = np.mean(y_true)
# Manual R^2
ss_res = np.sum((y_true - y_pred)**2) # Residual sum of squares
ss_tot = np.sum((y_true - y_mean)**2) # Total sum of squares
r2_manual = 1 - ss_res / ss_tot
print(f'SS_res (model): {ss_res}')
print(f'SS_tot (mean): {ss_tot}')
print(f'R^2 manual: {r2_manual:.4f}')
print(f'R^2 sklearn: {r2_score(y_true, y_pred):.4f}')Adjusted R-Squared: Penalising Extra Features
Adding more features to a regression model always increases R^2 (or keeps it the same) on training data — even if those features are random noise. Adjusted R^2 corrects for this by penalising the number of features: it decreases when you add a feature that does not improve the model enough to justify the additional complexity. Formula: Adj R^2 = 1 - (1 - R^2) * (n-1) / (n-p-1) where n = samples, p = features. Use adjusted R^2 when comparing models with different numbers of features to avoid selecting overly complex models.
import numpy as np
def adjusted_r2(y_true, y_pred, n_features):
n = len(y_true)
r2 = r2_score(y_true, y_pred)
return 1 - (1 - r2) * (n - 1) / (n - n_features - 1)
from sklearn.metrics import r2_score
from sklearn.linear_model import LinearRegression
import numpy as np
np.random.seed(42)
n = 100
X_2 = np.random.randn(n, 2)
X_10 = np.random.randn(n, 10) # 8 noise features added
y = X_2[:, 0] * 2 + X_2[:, 1] + np.random.randn(n) * 0.5
for X, p in [(X_2, 2), (X_10, 10)]:
pred = LinearRegression().fit(X, y).predict(X)
print(f'p={p}: R^2={r2_score(y,pred):.3f}, Adj R^2={adjusted_r2(y,pred,p):.3f}')MAPE: Mean Absolute Percentage Error
MAPE = 100 * mean(|y_true - y_pred| / |y_true|). Mean Absolute Percentage Error expresses the error as a percentage of the actual value, making it scale-independent and easily interpretable: a MAPE of 5% means predictions are off by 5% of the true value on average. Limitations: MAPE is undefined when actual values are zero (division by zero) and is asymmetric — underpredicting gives higher error than overpredicting by the same amount. Use MAPE for forecasting tasks (sales, demand) where stakeholders understand percentage deviations naturally.
import numpy as np
def mape(y_true, y_pred):
y_true = np.array(y_true, dtype=float)
# Avoid division by zero
mask = y_true != 0
return 100 * np.mean(np.abs((y_true[mask] - np.array(y_pred)[mask]) / y_true[mask]))
y_true = [100, 200, 300, 400, 500]
y_pred = [110, 190, 315, 380, 510]
print(f'MAPE: {mape(y_true, y_pred):.2f}%')
# Asymmetry example
print(f'Over by 50: MAPE = {mape([100],[150]):.1f}%')
print(f'Under by 50: MAPE = {mape([100],[50]):.1f}%')
# Underprediction by 50% gives 50% error; overprediction by 50% also 50% (same amount, asymmetric impact)Computing Regression Metrics with scikit-learn
Scikit-learn provides all major regression metrics in sklearn.metrics. When using cross_val_score, pass scoring='neg_mean_squared_error' (negative because higher is better by convention) and negate the result, or use 'neg_root_mean_squared_error' for direct RMSE. For R^2, use scoring='r2'. Always report multiple metrics: MAE for average absolute error, RMSE to show outlier sensitivity, and R^2 for explained variance. This gives a complete picture of model performance.
from sklearn.linear_model import LinearRegression
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import cross_val_score
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import numpy as np
X, y = fetch_california_housing(return_X_y=True)
for metric in ['neg_mean_absolute_error', 'neg_root_mean_squared_error', 'r2']:
scores = cross_val_score(LinearRegression(), X, y, cv=5, scoring=metric)
mean_val = scores.mean()
if 'neg' in metric:
mean_val = -mean_val
print(f'{metric.replace("neg_",""):30}: {mean_val:.4f}')Residual Analysis: Diagnosing Model Quality
Beyond summary metrics, residual analysis reveals whether model assumptions are met. Plot residuals (y_true - y_pred) vs predicted values. A good model shows: (1) residuals randomly scattered around zero with no pattern (homoscedastic), (2) no relationship between residual magnitude and predicted value (no heteroscedasticity). Warning signs: a funnel shape (residuals increase with predicted value) suggests the model needs log-transformation; a curved pattern suggests the relationship is non-linear and the model is misspecified. Always do residual analysis before deploying any regression model.
import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
X, y = fetch_california_housing(return_X_y=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, random_state=42)
model = LinearRegression()
model.fit(X_tr, y_tr)
y_pred = model.predict(X_te)
residuals = y_te - y_pred
plt.figure(figsize=(8, 4))
plt.scatter(y_pred, residuals, alpha=0.3, s=10)
plt.axhline(0, color='red', linestyle='--')
plt.xlabel('Predicted Value')
plt.ylabel('Residual (Actual - Predicted)')
plt.title('Residual Plot')
plt.show()Choosing the Right Regression Metric
A practical guide: use MAE when you want to minimise average absolute error and outliers should not be overemphasised — robust choice for general reporting. Use RMSE when your model minimises MSE during training and you want evaluation to match, or when large errors are particularly costly (demand forecasting, energy prediction). Use R^2 to compare models on the same dataset or explain model quality to non-technical stakeholders as 'percentage of variance explained'. Use MAPE for business forecasting where percentage deviations from actual values are the natural language of stakeholders.
# Metric selection guide
def recommend_metric(has_outliers, need_interpretable_units, compare_across_scales):
if compare_across_scales:
return 'R^2 (scale-independent, 0-1 range)'
elif need_interpretable_units and has_outliers:
return 'MAE (same units as target, robust to outliers)'
elif need_interpretable_units:
return 'RMSE (same units, penalises large errors more)'
else:
return 'MSE (convenient for optimisation, same loss as linear regression)'
print(recommend_metric(True, True, False)) # MAE
print(recommend_metric(False, True, False)) # RMSE
print(recommend_metric(False, False, True)) # R^2Quick Check
Test your understanding of Machine Learning with Python concepts from this lesson.
Lesson Recap
In this lesson you learned: MAE averages absolute errors and is robust to outliers, RMSE squares errors and penalises large deviations more heavily, R^2 measures the fraction of variance explained (0 = mean baseline, 1 = perfect), and the gap between MAE and RMSE reveals outlier error concentration. Next up we explore choosing the right metric for your specific business problem.
Apprends Python avec un tuteur IA — gratuit
Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.
- Cours
- 30
- Leçons
- 120
Questions Fréquemment Posées
La leçon « Métriques de régression : MAE, MSE, RMSE et R-Squared » est-elle gratuite ?
Oui — le texte complet de « Métriques de régression : MAE, MSE, RMSE et R-Squared » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Machine Learning Academy, passe à CoddyKit PRO. Le cours Machine Learning Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Métriques de régression : MAE, MSE, RMSE et R-Squared » ?
Calculez les métriques d’erreur sur une sortie de régression, comprenez la dépendance de MAE/RMSE à l’échelle et utilisez R-squared comme mesure standardisée de la qualité d’ajustement. Tu pratiques Machine Learning Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Machine Learning Academy ?
Aucune expérience préalable n'est requise. Machine Learning Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Métriques de régression : MAE, MSE, RMSE et R-Squared » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Machine Learning Academy ?
Oui. Chaque leçon Machine Learning Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Métriques de classification : exactitude, précision, rappel et F1
- Courbes ROC et AUC-ROC
- Métriques de régression : MAE, MSE, RMSE et R-Squared
- Choisir la bonne métrique pour votre problème métier