推导Lasso回归「建议收藏」

推导Lasso回归「建议收藏」推导Lasso回归文章目录推导Lasso回归一、推导过程二、用python编写求解函数三、Lasso求解稀疏表示做人脸识别代码展示:运行结果四、调整不同的超参lambda,对seta的影响代码展示一、推导过程​ Lasso方法是在普通线性模型中增加L1L_1L1​惩罚项,有助于降低过拟合风险,更容易获得稀疏解,求得的θ\thetaθ会有更少的非零分量。与岭回归的不同在于,此约束条件使用了绝对值的一阶惩罚函数代替了平方和的二阶函数。Lasso回归原式: arg⁡min⁡θ∣∣Aθ−

大家好,又见面了,我是你们的朋友全栈君。

推导Lasso回归

一、推导过程

​ Lasso方法是在普通线性模型中增加 L 1 L_1 L1惩罚项,有助于降低过拟合风险,更容易获得稀疏解,求得的 θ \theta θ会有更少的非零分量。与岭回归的不同在于,此约束条件使用了绝对值的一阶惩罚函数代替了平方和的二阶函数。

Lasso回归原式: arg ⁡ min ⁡ θ ∣ ∣ A θ − y ∣ ∣ 2 2 + λ ∣ ∣ θ ∣ ∣ 1 \mathop{\arg\min}\limits_{\theta}||A\theta-y||_2^2+\lambda||\theta||_1 θargminAθy22+λθ1

公式转换为: arg ⁡ min ⁡ θ 1 2 ∣ ∣ A θ − y ∣ ∣ 2 2 + 1 2 λ ∣ ∣ W θ ∣ ∣ 2 2 \mathop{\arg\min}\limits_{\theta}\frac{1}{2}||A\theta-y||_2^2+\frac{1}{2}\lambda||W\theta||_2^2 θargmin21Aθy22+21λWθ22

​ = arg ⁡ min ⁡ θ 1 2 ( A θ − y ) T ( A θ − y ) + 1 2 λ ( W θ ) T W θ \mathop{\arg\min}\limits_{\theta}\frac{1}{2}(A\theta-y)^T(A\theta-y)+\frac{1}{2}\lambda(W\theta)^TW\theta θargmin21(Aθy)T(Aθy)+21λ(Wθ)TWθ

上式对求导,

= 1 2 ( 2 A T A θ − 2 A T y ) + λ W T W θ =\frac{1}{2}(2A^TA\theta-2A^Ty)+\lambda W^TW\theta =21(2ATAθ2ATy)+λWTWθ

= A T A θ − A T y + λ W T W θ =A^TA\theta-A^Ty+\lambda W^TW\theta =ATAθATy+λWTWθ

令求导结果等于0,

θ = ( A T A + λ W T W ) − 1 A T y , 其 中 w i = 1 ∣ e i ∣ + ϵ , ϵ 是 一 个 接 近 于 0 的 数 ( 例 1 e − 5 ) \theta=(A^TA+\lambda W^TW)^{-1}A^Ty, 其中w_i=\frac{1}{\sqrt{|e_i|}+\epsilon},\epsilon 是一个接近于0的数(例1e-5) θ=(ATA+λWTW)1ATy,wi=ei
+ϵ
1
,ϵ01e
5

二、用python编写求解函数

def lasso(X, W, lr, Y):
    A = np.mat(X.copy())
    Y = np.mat(Y).reshape(-1,1)
    for i in range(10):
        seta = (A.T * A + lr* W.T *W).I*(A.T*Y)
        W = np.diag(1/(np.sqrt(np.abs(seta)) + 1e-5))
return seta

三、Lasso求解稀疏表示做人脸识别

​ 数据集的大小为(867,897),数据一共有867个样本,每个样本有896个属性,数据最后一列为标签,表示此样本属于某个人的,数据集一共有38个人的人脸数据。测试样本为,每人抽取两个人脸数据作为测试样本,即数据集表示为[A1, A2, …, A75, A76],y从总的数据集中随机抽选一个。

用lasso回归函数求解数据集的稀疏表示:

理论公式如下:
θ = ( A T A + λ W T W ) − 1 A T y , \theta=(A^TA+\lambda W^TW)^{-1}A^Ty, θ=(ATA+λWTW)1ATy,

其 中 w i = 1 ∣ e i ∣ + ϵ , ϵ 是 一 个 接 近 于 0 的 数 ( 例 1 e − 5 ) 其中w_i=\frac{1}{\sqrt{|e_i|}+\epsilon},\epsilon 是一个接近于0的数(例1e-5) wi=ei
+ϵ
1
,ϵ01e
5

其中W为系数矩阵。

代码展示:

import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt
import math

csv_data = pd.read_csv('test_YB_32_28.csv', header = None) #读取训练数据集,数据类型dataframe
csv_data = csv_data.values #将数据转换为矩阵形式
print(csv_data.shape)#输出数据大小

#选取训练数据编号
x = [] #生成列表,每个人选择前两张照片作为数据集
t = -1
for i in range(76):
    if i % 2 == 0 and i != 0:
        t +=22
    else:
        t += 1
    x.append(t)
#print(x)
y = np.random.randint(0,867) #随机挑选一张照片作为目标数据y
#print(y)

#提取训练数据X,y
train_data = csv_data[x, :896]/255 #提取训练数据
train_target = csv_data[y, :896]/255 #提取目标数据
train_label = csv_data[y, -1]#提取y的标签
#np.savetxt('data.csv', train_data, delimiter = ',')
#np.savetxt('target.csv', train_target, delimiter = ',')
#对系数矩阵进行处理
train_data = train_data.T #对数据进行转置
#print(train_data.shape)
#print(train_target.shape)
W = np.eye(76) #生成对角矩阵
#print(W.shape)
#print(W)
#lasso求解函数
def lasso(X, W, lr, Y):
    A = np.mat(X.copy())
    Y = np.mat(Y).reshape(-1,1)
    for i in range(10):
        seta = (A.T * A + lr* W.T *W).I*(A.T*Y) #lasso系数表示
        W = np.diag(1/(np.sqrt(np.abs(seta)) + 1e-5)) #权重对角矩阵更新
    return seta

#调用lasso函数,代入数据
seta = lasso(train_data, W, 1e-8, train_target)
#print(seta) #打印出seta系数表示
i = range(1,77, 1)
plt.plot(i, seta)
plt.show() #输出seta稀疏表示的图像
#将一维矩阵转为数组,求当前y对应人的稀疏表示稀疏
seta = list(seta)
print('当前y对应人的系数表示:')
print(seta[train_label*2-2])
print(seta[train_label*2-1])
# print(max(seta))
# print(seta[seta.index(max(seta))+1])
print('预测值:', math.ceil((seta.index(max(seta)) +1)/2))  #系数最大为预测值
print('真实值:', train_label) #真实值

运行结果

第一种情况:

在这里插入图片描述


图一 seta数据表示图

输出结果:

当前y对应人的系数表示:

[[0.81046264]]

[[0.24147223]]

预测值: 16(稀疏表示系数最大处)

真实值: 16

​ Seta稀疏表示具有稀疏性,预测结果满足预期要求。原因是,测试的样本y能够由当前的测试样本很好的表示出来,对于选取的测试集样本,能够获得具有代表性的稀疏表示。

另一种情况:

在这里插入图片描述


图二 seta数据表示图

输出结果:

当前y对应人的系数表示:

[[0.6094047]]

[[-0.30913317]]

预测值: 8(稀疏表示系数最大处)

真实值: 19

​ Seta稀疏表示表现出的稀疏性不强,预测结果不满足预期要求。产生的原因可能是某个个体的样本数量太少,测试集样本太过于特殊,还不足以能用稀疏表示来代表这个个体。解决结果是增加每个个体的训练样本,能让训练出来的稀疏表示更加具有代表性。

四、调整不同的超参lambda,对seta的影响

​ 选择不同的lambda作为惩罚项系数,在本代码中,选择lambda = [10000, 10, 0.01, 0.00001]这四种情况进行比较。此次实验每人选取两个样本共78张图片作为测试集y,剩下的691个样本作为数据集。

代码展示

import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt
import math

csv_data = pd.read_csv('test_YB_32_28.csv', header = None) #读取训练数据集,数据类型dataframe
csv_data = csv_data.values #将数据转换为矩阵形式
print(csv_data.shape)#输出数据大小

#选取训练数据编号
y = [] #生成列表,每个人选择前两张照片作为测试数据集
t = -1
X = list(range(0, 867, 1)) #训练数据
3#print(X)
for i in range(76):
    if i % 2 == 0 and i != 0:
        t +=22
    else:
        t += 1
    X.remove(t) #剔除掉用于测试的数据y
    y.append(t) #生成用于测试的数据集Y
#print(x)
#y = np.random.randint(0, 867) #随机挑选一张照片作为目标数据y
#print(y)

#提取训练数据X,y
train_data = csv_data[X, :896]/255 #提取训练数据
train_target = csv_data[y, :896]/255 #提取目标数据
#train_label = csv_data[x, -1]#提取y的标签
#np.savetxt('data.csv', train_data, delimiter = ',')
#np.savetxt('target.csv', train_target, delimiter = ',')

#对系数矩阵进行处理
train_data = train_data.T #对数据进行转置
#print(train_data.shape)
#print(train_target.shape)

#print(W.shape)
#print(W)

lambda = [10000, 10, 1e-2, 1e-5]
s_seta = []
#lasso求解函数
def lasso(X, W, lb, Y):
    A = np.mat(X.copy())
    Y = np.mat(Y).reshape(-1,1)
    for i in range(10):
        seta = (A.T * A + lb* W.T *W).I*(A.T*Y) #lasso系数表示
        W = 1/(np.sqrt(np.abs(seta)) + 1e-5)#权重对角矩阵更新
        W = np.diag(W/sum(W)) 
    return seta

#调用lasso函数,代入数据
for i in range(4):
    W = np.eye(791) #生成对角矩阵
    lb = lambd[i]
    seta = lasso(train_data, W, lb, train_target)
    s_seta.append(seta) 

#print(seta) #打印出seta系数表示
i = range(1,101, 1)
plt.plot(i, s_seta[0][:100], label = '1e4') #选取前100个数据进行打印
plt.plot(i, s_seta[1][:100], label = '10')
plt.plot(i, s_seta[2][:100], label = '1e-2')
plt.plot(i, s_seta[3][:100], label = '1e-5')
plt.xlabel('number')
plt.ylabel('weight')
plt.legend()
plt.show() #输出seta稀疏表示的图像

输出结果:

本测试结果选取第一张图片的输出结果,Lambda值分别选取10000, 10, 0.01, 0.00001,选取seta稀疏表示的前100个系数,实验运行结果如下图所示,

在这里插入图片描述


图三 不同lambda下的稀疏表示seta

结论:

Lasso的主要思想是构造一个一阶惩罚函数获得一个精炼的模型, 通过最终确定一些变量的系数为0进行特征筛选。Lasso的复杂程度由λ来控制,λ越大对变量较多的线性模型的惩罚力度就越大,会压缩一些回归系数,从而最终获得一个变量较少,较为精炼的模型。当λ较大时,获得的稀疏表示就越稀疏。在上述实验过程中,选择一个较大的lambda值即可获得一个理想的seta结果输出。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/139730.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • js添加事件和移除事件:addEventListener()与removeEventListener()

    js添加事件和移除事件:addEventListener()与removeEventListener()作用:   addEventListener()与removeEventListener()用于处理指定和删除事件处理程序操作。   它们都接受3个参数:事件名、事件处理的函数和布尔值。   布尔值参数是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。示例:环境:移动端,界面禁止触摸事件要在bo

    2022年7月12日
    41
  • Java 数组转 List 的 4 种方式

    Java 数组转 List 的 4 种方式目录前言【一】最常见方式(未必最佳)【二】数组转为List后,支持增删改查的方式【三】通过集合工具类Collections.addAll()方法(最高效)问题解答总结前言本文介绍Java中数组转为List三种情况的优劣对比,以及应用场景的对比,以及程序员常犯的类型转换错误原因解析。【一】最常见方式(未必最佳)通过Arrays.asList(strArray)方式,将数组转换List后,不能对List增删,只能查改,否则抛异常。关键代码:Listlist=Arrays.asList(

    2022年8月23日
    3
  • route add添加永久静态路由_route add添加默认路由

    route add添加永久静态路由_route add添加默认路由routeadd如何增加永久路由 在机器重起后依然维持原来的路由表保持不变ipfreak回复于:2002-09-1915:51:00mkaeafilestartwithSandputunderrc2.dorrc3.d.put"routeaddwhatevershit…

    2022年8月11日
    20
  • Python – 数据类型之字符串、数字

    Python – 数据类型之字符串、数字数据类型之字符串、数字

    2022年5月29日
    26
  • PHP实现微信小程序人脸识别刷脸登录功能

    PHP实现微信小程序人脸识别刷脸登录功能

    2021年10月23日
    67
  • RS485接口定义

    RS485接口定义

    1.英式标识为 TDA(-) 、TDB(+) 、RDA(-) 、RDB(+) 、GND 
    2.美式标识为 Y 、Z 、 A 、 B 、 GND  
    3.中式标识为 TXD(+)/A 、TXD(-)/B 、RXD(-) 、RXD(+)、GND  
       rs485两线一般定义为:  
                 “A, B”或”Date+,Date-”  
       即常说的:”485+,485-”  
       rs485四线一般定

    2022年5月27日
    67

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号