本主题主要说明LASSO回归,LASSO回归与Ridge回归一样,都是属于广义线性回归的一种。LASSO回归与Ridge回归一样,从概率模型来讲都是属于后验概率模型。主要内容:
- LASSO回归模型
- LASSO实现(sklearn实现,其他实现在这儿暂时没有时间弄)
- Ridge回归与LASSO回归的比较
2. LASSO回归
LASSO是由1996年Robert Tibshirani首次提出,全称Least absolute shrinkage and selection operator(最小绝对收缩和选择算子)。该方法是一种压缩估计。
2.1 LASSO回归模型
- 决策模型
|-
- 损失函数模型
|-
- Bayes建模模型
误差模型:
|-
|-分布,且
分布。
|-
最大似然函数模型:
如果记: ,则可以取损失函数为:
|-
- LASSO与Ridge回归的关系
实际上Ridge回归与LASSO回归都是采用了后验建模,Ridge回归的权重系数服从正态分布,LASSO回归权重系数服从Laplace分布。
Ridge回归中的实际上是正态分布方差的倒数
,在LASSO分布中的
实际上由误差的正态分布方差与Laplace的方差共同决定
,如果
取标准正态的方差1,则
- 正态分布函数的方差变化
% matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
# u=0
n=lambda x,s:(np.exp(-x**2/(2.0*s**2)))
x=np.linspace(-3,3,201,dtype=np.float64)
sigma=1
y_1=n( x, sigma )
sigma=0.5
y_2=n( x, sigma )
sigma=0.01
y_3=n( x, sigma )
# 可视化
figure=plt.figure('正态函数',figsize=(10,4))
ax=figure.add_axes([0.1,0.1,0.8,0.8],xlabel='X',ylabel='Y')
ax.plot(x,y_1,color= ( 1, 0, 0, 1 ),label='$\sigma=1$')
ax.plot(x,y_2,color= ( 0, 1, 0, 1 ), label='$\sigma=0.5$')
ax.plot(x,y_3,color= ( 0, 0, 1, 1 ), label='$\sigma=0.01$')
plt.legend()
plt.grid(True)
plt.show()
正态分布方差参数的影响对比
- Laplace分布函数的方差变化
% matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
# u=0
n=lambda x,s:np.exp(-np.abs(x)/s)
x=np.linspace(-3,3,201,dtype=np.float64)
sigma=1
y_1=n( x, sigma )
sigma=0.5
y_2=n( x, sigma )
sigma=0.01
y_3=n( x, sigma )
# 可视化
figure=plt.figure('正态函数',figsize=(10,4))
ax=figure.add_axes([0.1,0.1,0.8,0.8],xlabel='X',ylabel='Y')
ax.plot(x,y_1,color= ( 1, 0, 0, 1 ),label='$\sigma=1$')
ax.plot(x,y_2,color= ( 0, 1, 0, 1 ), label='$\sigma=0.5$')
ax.plot(x,y_3,color= ( 0, 0, 1, 1 ), label='$\sigma=0.01$')
plt.legend()
plt.grid(True)
plt.show()
拉普拉斯分布的参数影响对比
- 正态分布函数与Laplace分布函数的比较
% matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
# u=0
n=lambda x,s:(np.exp(-x**2/(2.0*s**2)))
l=lambda x,s:np.exp(-np.abs(x)/s)
x=np.linspace(-3,3,201,dtype=np.float64)
sigma=0.5
y_1=n( x, sigma )
y_2=l( x, sigma)
# 可视化
figure=plt.figure('正态函数',figsize=(10,4))
ax=figure.add_axes([0.1,0.1,0.8,0.8],xlabel='X',ylabel='Y')
ax.plot(x,y_1,color= ( 1, 0, 0, 1 ),label='正态分布')
ax.plot(x,y_2,color= ( 0, 0, 1, 1 ), label='$\sigma=0.5$')
plt.legend()
plt.grid(True)
plt.show()
正态分布与拉普拉斯分布在参数为0.5的对比
可以看得出来,拉普拉斯分布,在相同的参数下,取值为0更加不容易。
2.2 LASSO实现
- sklearn实现
% matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from sklearn import linear_model
from sklearn import datasets
from sklearn import preprocessing
# 数据集
data=np.loadtxt('ex0.txt')
X_DATA=data[:,1]
Y_DATA=data[:,2]
# 数据格式化
X_DATA=X_DATA.reshape(X_DATA.shape[0],1)
Y_DATA=Y_DATA.reshape(X_DATA.shape[0],1)
#x=preprocessing.scale(x)
#y=preprocessing.scale(y)
alpha=0.001
regression =linear_model.Lasso(alpha=alpha, fit_intercept=True)
regression.fit(X_DATA,Y_DATA)
pre=regression.predict(X_DATA)
pre=pre.reshape(pre.shape[0],1)
#cor=np.corrcoef(Y_DATA.T,pre.T)
#print('相关性:',cor)
# 测试
print('评估:',regression.score(X_DATA, Y_DATA))
# 斜率
print('斜率:',regression.coef_)
# 截距
print('截距:',regression.intercept_ )
figure=plt.figure('数据集可视化',figsize=(6,4))
ax=figure.add_axes([0.1,0.1,0.8,0.8],xlabel='X',ylabel='Y')
ax.scatter(X_DATA,Y_DATA,color=(0,0,1,1),marker='.')
ax.plot(X_DATA,pre,color=(1,0,0,1))
# 有网格线,更加容易观察
plt.grid(True)
plt.show()
评估: 0.9730836494329972
斜率: [1.68361119]
截距: [3.01346217]
LASSO回归直线
3. Ridge回归与LASSO回归的比较
% matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from sklearn import linear_model
from sklearn import datasets
from sklearn import preprocessing
# 鸢尾花数据集
data,target=datasets.load_iris(return_X_y=True)
x=data[:] #改变样本个数,观察效果非常明显
y=target[:]
x=x.astype(np.float64)
y=y.astype(np.float64)
x=preprocessing.scale(x)
y=preprocessing.scale(y)
# lambda变化200次,从10**-2到10**-10
n_alphas = 50
alphas = np.logspace(-10,4,n_alphas)
lasso =linear_model.Lasso(fit_intercept=True)
# 加权系数
coefs_lasso = []
for a in alphas:
lasso.set_params(alpha = a)
lasso.fit(x,y)
coefs_lasso.append(lasso.coef_)
#------------------------------------
ridge =linear_model.Ridge(fit_intercept=True)
# 加权系数
coefs_ridge = []
for a in alphas:
ridge.set_params(alpha = a)
ridge.fit(x,y)
coefs_ridge.append(ridge.coef_)
figure=plt.figure('数据集可视化',figsize=(10,4))
ax_lasso=figure.add_axes([0.1,0.1,0.4,0.8],xlabel='X',ylabel='Y')
# plot自动遍历每列,按照不同的颜色绘制曲线
ax_lasso.plot(alphas,coefs_lasso)
ax_lasso.set_xscale('log') # 不按照等分模式计算x轴刻度,按照对数的指数来计算刻度
ax_lasso.set_xlim(ax_lasso.get_xlim()[::-1]) #坐标轴换一个方向
ax_lasso.grid(True)
ax_ridge=figure.add_axes([0.6,0.1,0.4,0.8],xlabel='X',ylabel='Y')
# plot自动遍历每列,按照不同的颜色绘制曲线
ax_ridge.plot(alphas,coefs_ridge)
ax_ridge.set_xscale('log') # 不按照等分模式计算x轴刻度,按照对数的指数来计算刻度
ax_ridge.set_xlim(ax_ridge.get_xlim()[::-1]) #坐标轴换一个方向
# 有网格线,更加容易观察
plt.grid(True)
plt.show()
鸢尾花数据下,参数的变化对权重系数影响的比较,LASSO分布更容易产生权重系数为0的情况(前一个LASSO回归,后一个Ridge回归)
Ridge回归与LASSO回归的权重系数的变化,主要后验概率分布受条件概率的影响。Ridge的条件概率是正态分布,LASSO的条件概率是Laplace分布。两个曲线的特征明显可以感知他们的方差参数对权重系数的影响(正如我们最后一张图所示的一样)。
本主题缺LASSO分布的Numpy原生实现,有时间的时候我迟早会补上。










网友评论