本文目录导读:

我来详细说明如何使用Scikit-learn计算平均绝对误差(MAE)。
基本用法
from sklearn.metrics import mean_absolute_error
import numpy as np
# 示例数据
y_true = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
y_pred = np.array([1.1, 1.9, 3.2, 3.8, 5.1])
# 计算MAE
mae = mean_absolute_error(y_true, y_pred)
print(f"MAE: {mae:.4f}") # 输出: MAE: 0.1200
完整案例:线性回归模型评估
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
# 1. 生成模拟数据
np.random.seed(42)
X = np.random.rand(100, 1) * 10 # 特征值 0-10
y = 2 * X + 1 + np.random.randn(100, 1) * 0.5 # y = 2x + 1 + 噪声
# 2. 分割数据
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 3. 训练模型
model = LinearRegression()
model.fit(X_train, y_train)
# 4. 预测
y_pred = model.predict(X_test)
# 5. 计算各项指标
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)
print(f"模型评估结果:")
print(f"MAE (平均绝对误差): {mae:.4f}")
print(f"MSE (均方误差): {mse:.4f}")
print(f"RMSE (均方根误差): {rmse:.4f}")
print(f"R² (决定系数): {r2:.4f}")
多模型对比案例
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
# 准备数据
X = np.random.rand(200, 5) # 5个特征
true_coef = [1.5, -2.0, 0.8, -1.2, 0.5]
y = X @ true_coef + np.random.randn(200) * 0.3
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 定义多个模型
models = {
'Linear Regression': LinearRegression(),
'Decision Tree': DecisionTreeRegressor(max_depth=5, random_state=42),
'Random Forest': RandomForestRegressor(n_estimators=100, random_state=42)
}
# 训练并评估
results = []
for name, model in models.items():
# 创建管道(包括标准化)
pipeline = Pipeline([
('scaler', StandardScaler()),
('model', model)
])
# 训练
pipeline.fit(X_train, y_train)
# 预测
y_pred = pipeline.predict(X_test)
# 计算MAE
mae = mean_absolute_error(y_test, y_pred)
results.append({'Model': name, 'MAE': mae})
print(f"{name}: MAE = {mae:.4f}")
# 创建结果DataFrame
results_df = pd.DataFrame(results)
print("\n模型对比结果:")
print(results_df.to_string(index=False))
交叉验证中的MAE
from sklearn.model_selection import cross_val_score, cross_validate
from sklearn.linear_model import Ridge
# 准备数据
X, y = np.random.rand(150, 10), np.random.rand(150)
# 使用交叉验证评估模型
model = Ridge(alpha=1.0)
# 计算各折的MAE
mae_scores = cross_val_score(
model, X, y,
cv=5,
scoring='neg_mean_absolute_error' # 注意:sklearn返回负值
)
# 转换为正值
mae_scores = -mae_scores
print(f"5折交叉验证MAE:")
print(f"各折MAE: {mae_scores}")
print(f"平均MAE: {mae_scores.mean():.4f}")
print(f"MAE标准差: {mae_scores.std():.4f}")
# 获取更多详细信息
cv_results = cross_validate(
model, X, y,
cv=5,
scoring=['neg_mean_absolute_error', 'neg_mean_squared_error'],
return_train_score=True
)
print("\n详细交叉验证结果:")
print(f"测试集MAE: {-cv_results['test_neg_mean_absolute_error']}")
print(f"训练集MAE: {-cv_results['train_neg_mean_absolute_error']}")
实际应用案例:房价预测
from sklearn.datasets import fetch_california_housing
from sklearn.ensemble import GradientBoostingRegressor
# 加载加州房价数据集
housing = fetch_california_housing()
X, y = housing.data[:1000], housing.target[:1000] # 取前1000条
# 分割数据
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 训练梯度提升回归模型
gbr = GradientBoostingRegressor(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
random_state=42
)
gbr.fit(X_train, y_train)
# 预测
y_pred = gbr.predict(X_test)
# 计算MAE
mae = mean_absolute_error(y_test, y_pred)
# 可视化结果
plt.figure(figsize=(10, 6))
# 绘制预测值与真实值的对比
plt.subplot(1, 2, 1)
plt.scatter(y_test, y_pred, alpha=0.5)
plt.plot([y_test.min(), y_test.max()],
[y_test.min(), y_test.max()],
'r--', lw=2)
plt.xlabel('True Values')
plt.ylabel('Predictions')f'House Price Prediction (MAE: ${mae*100000:.0f})')
# 绘制误差分布
plt.subplot(1, 2, 2)
errors = y_test - y_pred
plt.hist(errors, bins=30, edgecolor='black')
plt.xlabel('Prediction Error')
plt.ylabel('Frequency')'Error Distribution')
plt.axvline(x=0, color='r', linestyle='--')
print(f"加州房价预测结果:")
print(f"平均绝对误差: ${mae*100000:.0f}")
print(f"平均真实价格: ${np.mean(y_test)*100000:.0f}")
print(f"相对误差: {mae/np.mean(y_test)*100:.2f}%")
plt.tight_layout()
plt.show()
自定义MAE函数(理解原理)
def calculate_mae_manual(y_true, y_pred):
"""
手动计算平均绝对误差
"""
# 计算绝对误差
absolute_errors = np.abs(y_true - y_pred)
# 计算平均值
mae = np.mean(absolute_errors)
return mae
# 与sklearn对比
y_true = np.array([2.0, 3.5, 5.0, 7.2])
y_pred = np.array([2.1, 3.3, 5.2, 7.0])
mae_manual = calculate_mae_manual(y_true, y_pred)
mae_sklearn = mean_absolute_error(y_true, y_pred)
print(f"手动计算MAE: {mae_manual:.4f}")
print(f"Sklearn MAE: {mae_sklearn:.4f}")
print(f"结果一致: {np.isclose(mae_manual, mae_sklearn)}")
网格搜索优化模型(使用MAE作为指标)
from sklearn.model_selection import GridSearchCV
# 定义参数网格
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [3, 5, 7],
'learning_rate': [0.01, 0.1, 0.2]
}
# 创建模型
gbr = GradientBoostingRegressor(random_state=42)
# 网格搜索
grid_search = GridSearchCV(
gbr, param_grid,
cv=5,
scoring='neg_mean_absolute_error',
n_jobs=-1
)
grid_search.fit(X_train, y_train)
print("最优参数:", grid_search.best_params_)
print(f"最优MAE: {-grid_search.best_score_:.4f}")
# 使用最优模型
best_gbr = grid_search.best_estimator_
y_pred_best = best_gbr.predict(X_test)
test_mae = mean_absolute_error(y_test, y_pred_best)
print(f"测试集MAE: {test_mae:.4f}")
关键要点
- MAE是绝对值:计算预测值与真实值之差的绝对值平均
- sklearn返回负值:在交叉验证中,sklearn返回负的MAE,因为sklearn总是最大化的分数
- 对异常值不敏感:相比于MSE,MAE对异常值更加鲁棒
- 单位相同:MAE的单位与原始数据相同,易于解释
- 用于回归问题:MAE主要用于回归任务的评估
希望这些案例能帮助你掌握Scikit-learn中MAE的使用方法!