Lasso 的 python实现
由于最近一些任务需要在Lasso的基础上修改一些细节,需要重写Lasso的代码。而python的sklearn模块中, Lasso的坐标梯度下降是由c语言编写。于是自己重新写了一份代码,优化方法选择坐标梯度下降法。
代码在最下边。
sklearn中使用坐标梯度下降法求解
sklearn中的Lasso类的fit方法调用了sklearn.linear_model.coordinate_descent 的 enet_path方法。
而 enet_path 方法调用了 enet_coordinate_descent_multi_task 方法。
这个方法是由cpython所写,写在cd_fast.cp37-win_amd64.pyd中,具体内容看不见。
下边是代码片段:
enet_path方法片段:
if not multi_output and sparse.isspmatrix(X):
model = cd_fast.sparse_enet_coordinate_descent(
coef_, l1_reg, l2_reg, X.data, X.indices,
X.indptr, y, X_sparse_scaling,
max_iter, tol, rng, random, positive)
elif multi_output:
model = cd_fast.enet_coordinate_descent_multi_task(
coef_, l1_reg, l2_reg, X, y, max_iter, tol, rng, random)
cd_fast中的enet_coordinate_descent_multi_task方法:
def enet_coordinate_descent_multi_task(*args, **kwargs): # real signature unknown
"""
Cython version of the coordinate descent algorithm
for Elastic-Net mult-task regression
We minimize
(1/2) * norm(y - X w, 2)^2 + l1_reg ||w||_21 + (1/2) * l2_reg norm(w, 2)^2
"""
pass
因此,考虑自己写一个代码。
使用坐标梯度下降法求解
论文:
Penalized Regressions: The Bridge versus the Lasso
论文地址:
http://www.gautampendse.com/software/lasso/webpage/Fu1998.pdf
参考文章:
https://blog.csdn.net/u012151283/article/details/77487729
代码
必须要说明,编写过程中的下标选取比较混乱。这可能会造成阅读上的障碍。但这似乎也没有啥好的办法。。。
比较麻烦的在于使用numpy的向量化处理减少了for循环的使用。
有以下几点需要注意:
1.sklearn中的损失函数如下:
注意二范数前的系数。不同的论文中系数不同,虽然是等价的,但是不确认的话,调参时会遇到麻烦。
2.sklearn中Lasso的截距项不在损失函数中的正则化部分中,所以在更新时需要单独拿出来处理。
代码如下
def coor_decent(X, y, w0, max_iter, alpha, max_e):
w = w0
nrows_w = X.shape[1