如何在Python的sklearn中训练以MAE为损失的线性模型?
如何在Python中用纯MAE损失训练线性模型
你观察得很准:sklearn.linear_model.LinearRegression确实是OLS(最小二乘)回归器,只支持MSE损失;HuberRegressor是混合了MSE和MAE的鲁棒损失模型,没法调成纯MAE。不过SGDRegressor其实完全可以配置成纯MAE损失的线性回归,这是sklearn体系内最直接的解决方案。
在sklearn中实现纯MAE损失的线性回归
SGDRegressor通过loss参数指定损失函数,你只需要把它设为'epsilon_insensitive',再将epsilon设为0——这样就完全退化成了MAE损失(也就是最小绝对偏差LAD回归,纯L1损失的线性模型)。
代码示例:
from sklearn.linear_model import SGDRegressor from sklearn.datasets import make_regression from sklearn.model_selection import train_test_split from sklearn.metrics import mean_absolute_error # 生成模拟回归数据 X, y = make_regression(n_samples=1000, n_features=10, random_state=42) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 配置纯MAE损失的SGD回归器 mae_reg = SGDRegressor( loss='epsilon_insensitive', epsilon=0.0, # 关键参数:设为0就是纯MAE损失 penalty=None, # 不需要正则化就设为None,需要的话可改为'l1'/'l2' max_iter=1000, tol=1e-3, random_state=42 ) mae_reg.fit(X_train, y_train) y_pred = mae_reg.predict(X_test) print(f"测试集MAE: {mean_absolute_error(y_test, y_pred):.4f}")
如果需要给模型加正则约束,保留penalty参数即可;要是想做完全无正则的纯LAD回归,就把penalty设为None。
其他易用的Python工具包选项
如果觉得SGD的迭代方式不够直观,或者需要更完善的统计推断支持,可以用statsmodels的QuantReg(分位数回归)——当分位数设为0.5时,就是最小绝对偏差回归,完全等价于纯MAE损失的线性模型。
代码示例:
import statsmodels.api as sm from sklearn.datasets import make_regression from sklearn.model_selection import train_test_split from sklearn.metrics import mean_absolute_error X, y = make_regression(n_samples=1000, n_features=10, random_state=42) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 添加截距项(statsmodels默认不包含截距) X_train_sm = sm.add_constant(X_train) X_test_sm = sm.add_constant(X_test) # 分位数q=0.5对应纯MAE损失的LAD回归 lad_reg = sm.QuantReg(y_train, X_train_sm) lad_results = lad_reg.fit(q=0.5) y_pred = lad_results.predict(X_test_sm) print(f"测试集MAE: {mean_absolute_error(y_test, y_pred):.4f}")
statsmodels的优势是能输出详细的统计结果(比如系数的p值、置信区间等),适合需要做统计分析的场景。
补充说明
HuberRegressor确实无法调成纯MAE,它的设计初衷就是在误差较小时用MSE、误差超过阈值时切换到MAE,本质是鲁棒损失,并非纯L1损失模型。- 如果你不需要兼容sklearn的API,也可以用
scipy.optimize手动实现LAD回归,但上面的两个工具包已经足够易用,没必要重复造轮子。
内容的提问来源于stack exchange,提问作者Lennart
相关产品推荐
相关产品推荐

