文章目录
- 机器学习的sklearn库
- 一、回归分析
- <1.1>线性回归
- 1.1.1、Python实现线性回归
- <1.2>最小二乘法
- 1.2.1、MATLAB实现最小二乘法
- 1.2.2、MATLAB实现最小二乘法(矩阵变换)
- 二、岭回归与Lasso回归
- <2.1>岭回归 ——(权值衰减)
- 2.1.1、岭回归原理
- 2.1.2、Python实现岭回归
- 2.1.3、MATLAB实现岭回归
- <2.2>Lasso回归 ——(特征选择)
- 2.2.1、Lasso回归原理
- 2.1.2、Python实现Lasso回归
- 2.2.2、MATLAB实现Lasso回归
- <2.3>岭回归与Lasso回归的差异
机器学习的sklearn库
官网:scikit-learn Machine Learning in Python sklearn (全称 scikit-learn ) 是基于 Python 语言的机器学习工具。它建立在 NumPy,SciPy,Pandas 和 Matplotlib 之上,里面的 API 设计非常好,所有对象的接口简单,很适合新手上路。sklearn有六个任务模块和一个数据引入模块。
(1)六个任务模块:分类 (Classification)、回归 (Regression)、聚类 (Clustering)、降维 (Dimensionality Reduction)、模型选择 (Model Selection)和预处理 (Preprocessing)。
(2)数据引入模块:数据集 (datasets)。
- 引入数据集的方法:生成随机数据:datasets.make_dataname;获取小数据:datasets.load_dataname;获取大数据:datasets.fetch_dataname;
生成随机数据包括:回归(make_regression)、分类(make_classification)、聚类(make_blobs)、正态分布 (make_gaussian_quantiles)
一、回归分析
一般来说,回归问题是一个函数拟合的过程。线性回归比较简单,可以直接推导出解析解,且许多非线性问题也可以转化为线性问题来解决,所以得到了广泛的应用。线性回归模型详解
回归分析的主要算法包括:
- 线性回归(Linear Regression)
- 逻辑回归(Logistic regressions)
- 多项式回归(Polynomial Regression)
- 逐步回归(Step Regression)
- 岭回归(Ridge Regression)
- 套索回归(Lasso Regression)
- 弹性网回归(ElasticNet)
<1.1>线性回归
1.1.1、Python实现线性回归
# 基于sklearn实现线性回归
######################################################
# 线性回归:sklearn.linear_model.LinearRegression(fit_intercept=True, normalize=False, copy_X=True, n_jobs=None)
# (1)fit_intercept:是否使用截距(默认True)。True表示使用,False表示不使用。
# (2)Normalize:是否归一化处理(默认False)。True表示使用,False表示不使用。
# (3)copy_X:True表示复制输入数据X; 否则可能被覆盖。
# (4)n_jobs: 用于计算作业的数量(默认None)。None意味着为1;当大于1或计算量足够大时开启加速;-1表示使用所有的处理器。
######################################################
import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets, linear_model
from sklearn.metrics import mean_squared_error, r2_score
#
# plt不能显示中文的解决方法
# import matplotlib.pyplot as plt
# plt.rcParams['font.sans-serif'] = ['SimHei'] # 显示中文
# plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
######################################################
# (1)加载数据集与数据分配
diabetes_X, diabetes_y = datasets.load_diabetes(return_X_y=True) # 导入datasets自带的数据集
# diabetes_X 数据集大小:442*10。diabetes_y 数据集大小:442*1。
diabetes_X = diabetes_X[:, np.newaxis, 2] # (只)取第二列数据:442*1
diabetes_X_train = diabetes_X[:-20] # 训练数据集X:422*1
diabetes_X_test = diabetes_X[-20:] # 测试数据集X:422*1
diabetes_y_train = diabetes_y[:-20] # 训练数据集y:20*1
diabetes_y_test = diabetes_y[-20:] # 测试数据集y:20*1
######################################################
# (2)模型训练与结果预测
regr = linear_model.LinearRegression() # 线性回归:对象实例化
regr.fit(diabetes_X_train, diabetes_y_train) # 模型训练
diabetes_y_pred = regr.predict(diabetes_X_test) # 模型预测
######################################################
# (3)打印结果与图形化显示
print('Coefficients: \n', regr.coef_)
print('Mean squared error(MSE): %.2f' % mean_squared_error(diabetes_y_test, diabetes_y_pred))
print('r2_score: %.2f' % r2_score(diabetes_y_test, diabetes_y_pred)) # r2_score计算确定系数R^2
plt.scatter(diabetes_X_test, diabetes_y_test, color="black")
plt.plot(diabetes_X_test, diabetes_y_pred, color="blue", linewidth=3)
plt.xlabel('x'), plt.ylabel('y')
plt.title('Linear Fitting')
plt.show()
<1.2>最小二乘法
最小二乘法(Least Squares): 又叫最小平方法,最常见于线性模型。用最小二乘法得到的估计,叫做最小二乘估计。
最小二乘法求回归直线方程的推导过程(公式推导 - 超详细)一文让你彻底搞懂最小二乘法(几何意义 - 图形化理解)
背景:1794年,德国数学家高斯在解决行星轨道预测问题时,首先提出最小二乘法。而高斯-马尔科夫定理从统计学的角度肯定了最小二乘法的合法性。
本质:估计线性模型中的未知参数,以最小化误差的平方和为准则,找到回归系数,得到最佳匹配函数。(1)常用于曲线拟合;
(2)常用来计算超定系统的近似解。
超定系统一般是无解的,只能求近似解。
- 超定系统(Overdetermined System): 是数学中的一种概念。如:现有M个方程,其包含N个未知数。如果M > N,则该系统是一个超定系统(又叫超定方程组)。
1.2.1、MATLAB实现最小二乘法
% 在matlab中,polyfit曲线拟合函数是基于最小二乘法原理实现的。
clear;clc;close all;
x = [2,4,5,6,6.8,7.5,9,12,13.3,15];
y = [-10,-6.9,-4.2,-2,0,2.1,3,5.2,6.4,4.5];
[~, k] = size(x);
for n = 1:9
p = polyfit(x,y,n); % 多项式拟合曲线
f = polyval(p, x); % 多项式计算
subplot(3, 3, n)
plot(x, y, '*')
hold on
plot(x, f)
title(n)
grid on
end
suptitle('1到9阶方程的曲线拟合结果')
1.2.2、MATLAB实现最小二乘法(矩阵变换)
clear;clc;close all;
x = [2,4,5,6,6.8,7.5,9,12,13.3,15];
y = [-10,-6.9,-4.2,-2,0,2.1,3,5.2,6.4,4.5];
[~, k] = size(x);
for n = 1:9
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (1)构造矩阵, 并计算系数向量A。
X = zeros(n+1, k); % 当前为n阶方程,则构建对应的(n+1)阶构造矩阵X。
for ii = 1:k
for jj = 1:(n+1)
X(jj, ii)=x(ii)^((n+1)-jj);
end
end
XT = X'; % 矩阵转置
Y = y';
ANSS = (XT'*XT)\(XT'*Y); % 待求解项的系数向量
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (2)根据求得的系数向量,计算n阶多项式方程的结果
x0 = 0:0.01:17; % 自定义范围
y0 = ANSS(1) * x0.^n; % n阶多项式方程的常数项
for num = 2:n+1
y0 = y0 + ANSS(num)*x0.^(n+1-num); % n阶多项式方程的系数项
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (3)绘图
subplot(3, 3, n)
plot(x, y, '*') % 原始数据
hold on
plot(x0, y0) % 拟合曲线
title(n)
grid on % 打开网格
end
suptitle('1到9阶方程的曲线拟合结果')
% 结论:(1)当阶数过小时,拟合曲线并不能很好地反映出样本点的分布情况;
% (2)当阶数过高时,拟合曲线会出现过拟合现象。
二、岭回归与Lasso回归
为了避免模型过拟合,通常需在损失函数后面加入正则化项。而不同的正则化项产生了不同的回归方法,其中以岭回归和Lasso回归最为经典。前者加入了L2正则化项(L2范数),后者加入的是L1正则化项(L1范数)。岭回归与Lasso回归的公式详细推导过程
<2.1>岭回归 ——(权值衰减)
2.1.1、岭回归原理
岭回归是一种多重共线性数据分析的有偏估计回归方法,实质上是一种改良的最小二乘估计法。
- 多重共线性:指自变量之间存在线性相关关系,即一个自变量可以是其他一个或几个自变量的线性组合。多重共线性详解
特点: (1)放弃了最小二乘法的无偏性,而通过有偏估计将回归系数无限收缩于0(但不等于0),进而可以极大缓解多重共线性问题以及过拟合问题。 (2)对离群点数据(病态数据)的拟合效果强于最小二乘法。 (3)岭回归是解决多重共线性问题最有效办法,但由于回归系数并没有收缩到0,并不能从根本上解决多重共线问题。岭回归原理
岭回归与最小二乘法的区别:(1)根据高斯-马尔科夫定理(最小二乘法),多重相关性并不影响最小二乘估计量的无偏性和最小方差性。
(2)但是,虽然
最小二乘估计量在所有线性无偏估计量中是方差最小的,可这个方差却不一定小。(3)而实际上可以找一个
有偏估计量,这个估计量
虽然有微小的偏差,但它的精度却能够大大高于无偏的估计量。
(4)岭回归分析就是依据这个原理,通过
在正规方程中引入有偏常数而求得回归估计量。
2.1.2、Python实现岭回归
# 基于sklearn实现岭回归
######################################################
# 交叉验证岭回归:sklearn.linear_model.RidgeCV(alphas=(0.1, 1.0, 10.0), fit_intercept=True, normalize=False, cv=None)
# (1)alpha:正则化强度(0~无穷大),默认为1.0。
# (2)fit_intercept:是否使用截距(默认True)。True表示使用,False表示不使用。
# (3)Normalize:是否归一化处理(默认False)。True表示使用,False表示不使用。
# (4)cv: 交叉验证的次数。如:cv=5表示五折交叉验证。
# 作用:通过设置多个alphas值,并使用交叉验证法,获取最优alphas值,即岭参数λ。
######################################################
# 岭回归:sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True, normalize=False)
# 作用:取岭参数(最优λ值)构建模型。
######################################################
import numpy as np
import matplotlib.pyplot as plt
import sklearn
from sklearn.datasets import make_regression
from sklearn.linear_model import Ridge, RidgeCV
######################################################
# (1)生成数据
X, y, w = make_regression(n_samples=50, n_features=100, coef=True, random_state=1, bias=3.5, noise=100)
###########################
# 生成回归样本数据:x, y = make_regression(n_sample=100, n_features=100, n_informative=10, n_targets=1, bias=0.1,
# effective_rank=None, tail_strength=0.5, noise=0.2, shuffle=True, coef=False, random_state=None)
# (1)n_sample:样本数
# (2)n_features:自变量个数(特征数)
# (3)n_informative:参与建模特征数
# (4)n_targets:因变量个数
# (5)bias:偏差(截距)
# (6)noise:噪音
# (7)coef:是否输出coef标识
# (8)random_state:随机状态。若为固定值,则每次产生的数据都一样。
######################################################
# (2)最优参数训练
ridge_cv = RidgeCV() # RidgeCV:对象实例化
ridge_cv.fit(X, y) # 模型训练
ridge_best_lambda = ridge_cv.alpha_ # 交叉验证得到岭参数(最优λ值)。
######################################################
# (3)构建最优模型
model_ridge = Ridge(alpha=ridge_best_lambda) # Ridge:对象实例化
model_ridge.fit(X, y) # 模型训练
y_pred = model_ridge.predict(X) # 模型预测
######################################################
# (4)打印结果与图形化显示
print('岭参数(最优λ):', ridge_best_lambda)
print('岭回归系数:', model_ridge.coef_)
print('MSE: %.2f' % sklearn.metrics.mean_squared_error(y, y_pred))
print('r2_score: %.2f' % sklearn.metrics.r2_score(y, y_pred)) # score():计算确定系数R^2
plt.subplot(221)
plt.plot(y, c='r', label='actual')
plt.plot(y_pred, c='g', label='prediction')
plt.legend(loc=4) # 图例位置调整:legend(loc=num) 其中,num=1~10, 不同数值对应不同位置。默认loc=1
plt.xlabel('x'), plt.ylabel('y')
plt.title('Predict Results (best_lambda: %.2f)' % ridge_best_lambda)
######################################################
# (5)在不同的岭参数下,获取对应的岭回归系数与误差。
clf = Ridge()
alphas = np.logspace(0, 6, 200) # 生成等份向量
coefs = []
errors = []
for a in alphas:
clf.set_params(alpha=a) # 更新岭参数
clf.fit(X, y) # 模型训练
coefs.append(clf.coef_)
errors.append(sklearn.metrics.mean_squared_error(clf.coef_, w))
###########################
# 岭迹图 —— 绘制不同岭参数对应的回归系数
plt.subplot(222)
ax = plt.gca()
ax.plot(alphas, coefs)
ax.set_xscale('log')
plt.xlabel('λ'), plt.ylabel('Ridge coefficients')
plt.title('Comparision Chart of Ridge Parameters and Regression Coefficients')
plt.axis('tight')
###########################
# 绘制不同岭参数对应的残差平方和
plt.subplot(223)
ax = plt.gca()
ax.plot(alphas, errors)
ax.set_xscale('log')
plt.xlabel('λ'), plt.ylabel('SSE')
plt.title('Comparision Chart of Ridge Parameters and Errors')
plt.axis('tight')
plt.show()
2.1.3、MATLAB实现岭回归
%% 读取EXCEL数据
% data = xlsread('C:\Users\pc\Desktop\data.xlsx');
%% (1)读取数据
clc;clear;close all;
x1=[0.455;0.35;0.53;0.44;0.33;0.425;0.53;0.545;0.475;0.55;0.525;0.43;0.49;0.535;0.47;0.5;0.355;0.44];
x2=[0.365;0.265;0.42;0.365;0.255;0.3;0.415;0.425;0.37;0.44;0.38;0.35;0.38;0.405;0.355;0.4;0.28;0.34];
x3=[0.095;0.09;0.135;0.125;0.08;0.095;0.15;0.125;0.125;0.15;0.14;0.11;0.135;0.145;0.1;0.13;0.085;0.1];
x4=[0.514;0.2255;0.677;0.516;0.205;0.3515;0.7775;0.768;0.5095;0.8945;0.6065;0.406;0.5415;0.6845;0.4755;0.6645;0.2905;0.451];
x5=[0.2245;0.0995;0.2565;0.2155;0.0895;0.141;0.237;0.294;0.2165;0.3145;0.194;0.1675;0.2175;0.2725;0.1675;0.258;0.095;0.188];
x6=[0.101;0.0485;0.1415;0.114;0.0395;0.0775;0.1415;0.1495;0.1125;0.151;0.1475;0.081;0.095;0.171;0.0805;0.133;0.0395;0.087];
x7=[0.15;0.07;0.21;0.155;0.055;0.12;0.33;0.26;0.165;0.32;0.21;0.135;0.19;0.205;0.185;0.24;0.115;0.13];
y=[15;7;9;10;7;8;20;16;9;19;14;10;1;10;10;12;7;10]; % 因变量(真实值:18个)
x=[x1,x2,x3,x4,x5,x6,x7]; % 自变量(7*18:7个属性,每个属性有18个特征值)
% 拟合方程:y = b1*x1 + b2*x2 + b3*x3 + b4*x4 + b5*x5 + b6*x6 + b7*x7;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% (2)岭回归:ridge()
k = 0:1e-2:10; % 岭参数(k);即正则化系数(λ)
b = ridge(y, x, k); % 岭回归系数(b)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 岭回归方程:y = β0 + β1*x1 + β2*x2 + ... + βn*xn
% 岭回归:b = ridge(y, x, k, s);
% (1)b: 岭回归模型中的系数向量:β = [β0, β1, β2, ..., βn]。其中,β0是常数项,β1到βn是自变量x1到xn对应的系数。
% (2)y: 因变量向量
% (3)x: 自变量矩阵:x = [x1, x2, ..., xn]。其中,每个x(i)都是列向量。
% (4)k: 岭参数。 岭参数不同,岭回归模型大不相同,顾要选取合适的岭参数。
% 备注:k=0时,即取消正则化L2,故此时的方程是最小二乘法。
% (5)s: 系数缩放标志符(默认为1)。用于确定 b 中的系数估计值是否缩放到与原始数据等比例。
% 当scaled为1时,不将向量 β 的系数缩放到与原始数据等比例。此时,每一个k值,b包含n个系数。
% 当scaled为0时,将向量 β 的系数缩放到与原始数据等比例。此时,每一个k值,b包含n+1个系数,其第一行是常数项β0。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% (3)岭迹图 ———— 绘制不同岭参数(k)对应的岭回归系数。
subplot(2, 2, 1);
plot(k,b); xlabel('岭参数(k)'); ylabel('β'); title('岭迹图');
legend('x1','x2','x3','x4','x5','x6','x7');
grid on
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% (4)绘制不同岭参数(k)对应的残差平方和。
% [row, col] = size(A):返回矩阵A的行数和列数。
% rows = size(A, 1):返回矩阵A的行数。
% cols = size(A, 2):返回矩阵A的列数。
k_num = size(b, 2); % k_num为岭参数(k)的个数
feature_num = size(x, 1); % feature_num为每个属性对应的特征数
y_ridge = x * b; % 多项式计算。计算不同岭参数下,每个样本的回归值。
for jj = 1:k_num
SSE_temp = 0; % 残差初始化
for ii = 1:feature_num
% 在当前岭参数下,累加每个样本(行)的残差值。
SSE_temp = SSE_temp + ( y_ridge(ii,jj) - y(ii) )^2;
end
SSE(jj) = SSE_temp; % 残差平方和
end
subplot(2, 2, 2);
plot(k, SSE)
xlabel('岭参数(k)')
ylabel('残差平方和(SSE)')
title('不同岭参数(k)对应的残差平方和的关系图')
grid on
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% (5)由上图可得,残差平方和最小对应的岭参数=2。
b1 = ridge(y, x, 2); % 岭回归系数(b1)
y_predict = x*b1; % 多项式计算。计算最优岭参数下,每个样本的回归值。
% for ii = 1:feature_num
% y_predict(ii, 1) = b1(1,1)*x1(ii) + b1(2,1)*x2(ii) + b1(3,1)*x3(ii) + b1(4,1)*x4(ii) + b1(5,1)*x5(ii) + b1(6,1)*x6(ii) + b1(7,1)*x7(ii);
% end
y_normalize = (y - min(y)) / (max(y) - min(y)); % 归一化(0~1)
y_predict_normalize = (y_predict - min(y_predict)) / (max(y_predict) - min(y_predict)); % 归一化(0~1)
subplot(2, 2, 3);
plot(1:feature_num, y_normalize , 'r');
hold on
plot(1:feature_num, y_predict_normalize , 'b');
legend('真实值y', '回归值y_ridge')
title('预测结果对比图')
grid on
<2.2>Lasso回归 ——(特征选择)
2.2.1、Lasso回归原理
最小绝对收缩和选择方法(Least absolute shrinkage and selection operator,Lasso)是一种压缩估计法。通过加入惩罚项L1正则化,对变量的系数进行压缩,并使某些不显著 / 不重要的回归系数变为0,进而达到特征选择的目的。
2.1.2、Python实现Lasso回归
# 基于sklearn实现Lasso回归
######################################################
# 交叉验证Lasso回归:sklearn.linear_model.LassoCV(alphas=(0.1, 1.0, 10.0), fit_intercept=True, normalize=False, cv=None)
# (1)alpha:正则化强度(0~无穷大),默认为1.0。
# (2)fit_intercept:是否使用截距(默认True)。True表示使用,False表示不使用。
# (3)Normalize:是否归一化处理(默认False)。True表示使用,False表示不使用。
# (4)cv: 交叉验证的次数。如:cv=5表示五折交叉验证。
# 作用:通过设置多个alphas值,并使用交叉验证法,获取最优alphas值,即岭参数λ。
######################################################
# 岭回归:sklearn.linear_model.Lasso(alpha=1.0, fit_intercept=True, normalize=False)
# 作用:取岭参数(最优λ值)构建模型。
######################################################
import numpy as np
import matplotlib.pyplot as plt
import sklearn
from sklearn.datasets import make_regression
from sklearn.linear_model import Lasso, LassoCV
######################################################
# (1)生成数据
X, y, w = make_regression(n_samples=50, n_features=100, coef=True, random_state=1, bias=3.5, noise=100)
###########################
# 生成回归样本数据:x, y = make_regression(n_sample=100, n_features=100, n_informative=10, n_targets=1, bias=0.1,
# effective_rank=None, tail_strength=0.5, noise=0.2, shuffle=True, coef=False, random_state=None)
# (1)n_sample:样本数
# (2)n_features:自变量个数(特征数)
# (3)n_informative:参与建模特征数
# (4)n_targets:因变量个数
# (5)bias:偏差(截距)
# (6)noise:噪音
# (7)coef:是否输出coef标识
# (8)random_state:随机状态。若为固定值,则每次产生的数据都一样。
######################################################
# (2)最优参数训练
lasso_cv = LassoCV() # LassoCV:对象实例化
lasso_cv.fit(X, y) # 模型训练
lasso_best_lambda = lasso_cv.alpha_ # 交叉验证得到岭参数(最优λ值)。
######################################################
# (3)构建最优模型
model_lasso = Lasso(alpha=lasso_best_lambda) # Lasso:对象实例化
model_lasso.fit(X, y) # 模型训练
y_pred = model_lasso.predict(X) # 模型预测
######################################################
# (4)打印结果与图形化显示
print('lasso参数(最优λ):', lasso_best_lambda)
print('lasso回归系数:', model_lasso.coef_)
print('MSE: %.2f' % sklearn.metrics.mean_squared_error(y, y_pred))
print('r2_score: %.2f' % sklearn.metrics.r2_score(y, y_pred)) # score():计算确定系数R^2
plt.subplot(221)
plt.plot(y, c='r', label='actual')
plt.plot(y_pred, c='g', label='prediction')
plt.legend(loc=4) # 图例位置调整:legend(loc=num) 其中,num=1~10, 不同数值对应不同位置。默认loc=1
plt.xlabel('x'), plt.ylabel('y')
plt.title('Predict Results (best_lambda: %.2f)' % lasso_best_lambda)
######################################################
# (5)在不同的lasso参数下,获取对应的lasso回归系数与误差。
clf = Lasso()
alphas = np.logspace(0, 6, 200) # 生成等份向量
coefs = []
errors = []
for a in alphas:
clf.set_params(alpha=a) # 更新lasso参数
clf.fit(X, y) # 模型训练
coefs.append(clf.coef_)
errors.append(sklearn.metrics.mean_squared_error(clf.coef_, w))
###########################
# 绘制不同lasso参数对应的回归系数
plt.subplot(222)
ax = plt.gca()
ax.plot(alphas, coefs)
ax.set_xscale('log')
plt.xlabel('λ'), plt.ylabel('Ridge coefficients')
plt.title('Comparision Chart of Lasso Parameters and Regression Coefficients')
plt.axis('tight')
###########################
# 绘制不同lasso参数对应的残差平方和
plt.subplot(223)
ax = plt.gca()
ax.plot(alphas, errors)
ax.set_xscale('log')
plt.xlabel('λ'), plt.ylabel('SSE')
plt.title('Comparision Chart of Lasso Parameters and Errors')
plt.axis('tight')
plt.show()
2.2.2、MATLAB实现Lasso回归
%% 读取EXCEL数据
% data = xlsread('C:\Users\pc\Desktop\data.xlsx');
%% (1)读取数据
clc;clear;close all;
x1=[0.455;0.35;0.53;0.44;0.33;0.425;0.53;0.545;0.475;0.55;0.525;0.43;0.49;0.535;0.47;0.5;0.355;0.44];
x2=[0.365;0.265;0.42;0.365;0.255;0.3;0.415;0.425;0.37;0.44;0.38;0.35;0.38;0.405;0.355;0.4;0.28;0.34];
x3=[0.095;0.09;0.135;0.125;0.08;0.095;0.15;0.125;0.125;0.15;0.14;0.11;0.135;0.145;0.1;0.13;0.085;0.1];
x4=[0.514;0.2255;0.677;0.516;0.205;0.3515;0.7775;0.768;0.5095;0.8945;0.6065;0.406;0.5415;0.6845;0.4755;0.6645;0.2905;0.451];
x5=[0.2245;0.0995;0.2565;0.2155;0.0895;0.141;0.237;0.294;0.2165;0.3145;0.194;0.1675;0.2175;0.2725;0.1675;0.258;0.095;0.188];
x6=[0.101;0.0485;0.1415;0.114;0.0395;0.0775;0.1415;0.1495;0.1125;0.151;0.1475;0.081;0.095;0.171;0.0805;0.133;0.0395;0.087];
x7=[0.15;0.07;0.21;0.155;0.055;0.12;0.33;0.26;0.165;0.32;0.21;0.135;0.19;0.205;0.185;0.24;0.115;0.13];
y=[15;7;9;10;7;8;20;16;9;19;14;10;1;10;10;12;7;10]; % 因变量(真实值:18个)
x=[x1,x2,x3,x4,x5,x6,x7]; % 自变量(7*18:7个属性,每个属性有18个特征值)
% 拟合方程:y = b1*x1 + b2*x2 + b3*x3 + b4*x4 + b5*x5 + b6*x6 + b7*x7;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% (2)Lasso回归:lasso()
[b, FitInfo] = lasso(x, y, 'CV', 10, 'Alpha', 1); % 使用十倍交叉验证、Alpha=1的Lasso回归,找到正则化线性回归模型的系数。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% lasso回归方程:y = β0 + β1*x1 + β2*x2 + ... + βn*xn
% lasso回归:[b, FitInfo] = lasso(x, y, 'CV', 10, 'Alpha', 1);
% (1)b:岭回归模型中的系数向量:β = [β0, β1, β2, ..., βn]。其中,β0是常数项,β1到βn是自变量x1到xn对应的系数。
% (2)y:因变量向量
% (3)x:自变量矩阵:x = [x1, x2, ..., xn]。其中,每个x(i)都是列向量。
% (4)CV:交叉验证(Cross-Validation)
% (5)Alpha:惩罚参数:0 <= α <= 1。
% 11、当α=1时,表示Lasso回归;
% 当α=0时,表示岭回归(Ridge regression);
% 当α=其他值时,表示弹性网络回归算法(Elastic net);
% 22、弹性网络回归算法的代价函数结合了Lasso回归和岭回归的正则化方法,通过两个参数 λ 和 β 来控制惩罚项的大小。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% (3)绘制交叉验证的训练轨迹图
axTrace = lassoPlot(b, FitInfo);
legend('show')
grid on
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% (4)绘制交叉验证的拟合曲线图
axCV = lassoPlot(b, FitInfo, 'PlotType', 'CV');
legend('show')
grid on
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% (5)取均方误差(MSE)最小,对应的λ(最优值)
idxLambdaMSE = FitInfo.IndexMinMSE; % MSE最小时,对应的 λ
coef = b(:, idxLambdaMSE); % λ 对应的稀疏系数向量
coef0 = FitInfo.Intercept(idxLambdaMSE); % λ 对应的常数项
y_predict = x*coef + coef0; % 矩阵乘法:(18*7)*(7*1)=(18*1)
feature_num = size(x, 1); % size(A, 1)返回矩阵A的行数。feature_num为每个属性对应的特征数。
plot(1:feature_num, y , 'r');
hold on
plot(1:feature_num, y_predict , 'b');
legend('真实值y', '回归值y_predict')
title('预测结果对比图')
grid on
<2.3>岭回归与Lasso回归的差异
以二维数据空间为例,说明Lasso和Ridge两种方法的差异。
- 两张图分别是两种方法的等高线与约束域。
(1)中心红色点:是极小值点(即线性回归的解)。
(2)同一颜色的椭圆:在同一椭圆上的函数值都相同,且越靠近红色点值越小。
(3)不同颜色的椭圆:即随着 λ 的变化所得到的残差平方和。- 等高线和约束域的切点就是目标函数的最优解。
(1)Ridge方法:对应的约束域是圆。其最优解在某条等值线与约束圆的切点上取到,但不会与坐标轴相切。
(2)Lasso方法:对应的约束域是正方形。其最优解通常在约束菱形的端点处取到(即坐标轴上)。
- 结论(岭回归与Lasso的差异)
(1)Lasso方法:将不显著的回归系数压缩为0,从而达到【特征选择】的效果。
(2)Ridge方法:将回归系数无限收缩于0(但不等于0),即最终模型会保留所有的变量,从而达到【权值衰减】的效果。
备注:Ridge regression的目标函数是处处可导的;而Lasso目标函数就没有那么好的性质了。实际上,我们可以给出前两个模型的解析解,而Lasso仅能给出迭代解法。
Python线性回归和岭回归代码详解及Demopython机器学习库sklearn——Lasso回归(L1正则化)