def soft(z, lam):
return np.sign(z) * np.maximum(np.abs(z) - lam, 0)
soft(np.array([-1.2, -0.2, 0.7]), lam=0.5)array([-0.7, -0. , 0.2])
Robert Tibshirani (1996)
The lasso solves penalized least squares with an \(\ell_1\) constraint or penalty:
\[ \hat\beta = \arg\min_\beta \frac{1}{2n}\|y-X\beta\|_2^2+\lambda\|\beta\|_1. \]
The geometry of the \(\ell_1\) ball creates corners, so coefficient paths can hit exactly zero. In one coordinate, the update is soft-thresholding:
\[ \beta_j \leftarrow \frac{S\left(n^{-1}x_j'(y-X_{-j}\beta_{-j}),\lambda\right)} {n^{-1}x_j'x_j}, \qquad S(z,\lambda)=\operatorname{sign}(z)(|z|-\lambda)_+. \]
SymPy expression for positive-side soft-thresholding: \(S(z,\lambda)= - \lambda + z\) when \(z>\lambda\), and \(0\) otherwise.
Define the soft-thresholding map \(S(z,\lambda)=\operatorname{sign}(z)(|z|-\lambda)_+\).
array([-0.7, -0. , 0.2])
Simulate \((y,X)\) for a sparse linear model.
array([ 0. , 2. , 0. , 0. , -1.4, 0. , 0. , 0. , 1.1, 0. , 0. ,
0. , 0. , 0. , 0. , -1.8, 0. , 0. , 0. , 0. , 0. , 0. ,
0. , 0. , 0. , 0. , 0. , 0. ])
For each coordinate, form the partial residual \(r_j=y-X\beta+x_j\beta_j\) and apply the update.
array([-0. , 1.97648084, -0. , -0.12769652, -1.38689192,
-0.10110487, 0. , 0.02878179, 1.13559559, 0.07755476])
Plot the path \(\hat\beta(\lambda)\).