You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自行实现的Lasso与scikit-learn的lasso_path求解路径差异原因是什么?

二者结果差异的核心原因
  • L1正则次梯度实现错误:你当前写的abs(self.B)/self.B * self.alpha逻辑存在两个致命问题:一是当权重B_j为0时会出现除以0的错误,二是完全无法匹配L1正则的次梯度定义,自然不可能得到和sklearn一致的稀疏解(比如你测试集中的b_2=0的结果)。此外你加了if j:的判断,第一次迭代完全不加入正则项的梯度,也会导致权重更新逻辑偏离优化目标。
  • 特征预处理未对齐sklearn默认逻辑:sklearn的lasso_path默认会对输入特征做标准化处理,同时自动拟合截距项。如果你的输入数据没有做标准化,两者的alpha参数的实际作用尺度完全不同,结果自然差异巨大。
  • 求解器实现逻辑差异:sklearn的Lasso求解默认使用坐标下降法或者LARS算法,专门针对L1正则的稀疏特性做了优化,数值稳定性远高于你实现的朴素梯度下降。你的朴素梯度下降如果学习率设置不合理、迭代次数不足,很可能根本没有收敛到最优解。
需要补充/修改的代码内容

首先要把错误的次梯度更新替换为软阈值操作,这是Lasso得到稀疏解的核心逻辑;其次要补充特征标准化、截距项拟合的逻辑,对齐sklearn的默认处理;最后调整迭代逻辑保证收敛,修改后的完整代码如下:

import numpy as np

class custom_lasso():
    def __init__(self, lr=0.001, max_iter=10000, lamb=1.0, fit_intercept=True, standardize=True):
        self.eta = lr
        self.max_iter = max_iter
        self.alpha = lamb
        self.fit_intercept = fit_intercept
        self.standardize = standardize

    def _preprocess_data(self, X, Y):
        # 拟合截距的前置处理:对X、Y去均值
        if self.fit_intercept:
            self.y_mean = np.mean(Y)
            Y = Y - self.y_mean
            self.x_mean = np.mean(X, axis=0)
            X = X - self.x_mean
        # 特征标准化
        if self.standardize:
            self.x_std = np.std(X, axis=0)
            X = X / self.x_std
        return X, Y

    def _soft_threshold(self, x, lambda_):
        # L1正则对应的软阈值函数,实现系数稀疏化
        return np.sign(x) * np.maximum(np.abs(x) - lambda_, 0)

    def fit(self, X, Y):
        X, Y = self._preprocess_data(X, Y)
        self.n, self.p = X.shape
        self.B = np.zeros(self.p)

        for i in range(self.max_iter):
            # 计算平方误差项的梯度
            dB = X.T @ (X @ self.B - Y)
            # 梯度下降更新权重
            self.B -= self.eta * dB
            # 软阈值操作处理L1正则
            self.B = self._soft_threshold(self.B, self.eta * self.alpha)

        # 将系数还原回原始数据尺度
        if self.standardize:
            self.B = self.B / self.x_std
        if self.fit_intercept:
            self.intercept_ = self.y_mean - self.x_mean @ self.B
        else:
            self.intercept_ = 0
        return self

内容的提问来源于stack exchange,提问作者Yuki.F

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 17:06:04