【转】最小二乘法与岭回归的介绍与对比

本文介绍了线性回归的基本原理及最小二乘法的应用,探讨了在面对多重共线性和奇异矩阵等问题时,如何利用岭回归和LASSO回归进行模型优化,通过引入正则化项来提高模型的稳定性和预测准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:https://blog.youkuaiyun.com/dang_boy/article/details/78504258

一 线性回归(最小二乘法)

假设我们有n个样本数据,每个数据有p个特征值,然后p个特征值是线性关系。

即对应的线性模型

写成矩阵的形式即是Y=XA

由于样本与模型不一定百分百符合,存在一些噪声,即误差,用B表示,B也是一个向量

即B=Y-XA

Y为样本值,XA为模型的计算值,即期望值

误差的平方的计算公式

Xi为行向量,A为列向量。

最小二乘法的目标就是取得最小的e对应的A,由于方差的计算是一个二次函数,即抛物线,对应存在一个最小值,即导数为0对应的A。所以对e求A的偏导数,再使其等于0,求解方程即可以获得A。

误差的平方e写成矩阵形式即为

对矩阵E取迹(迹就是矩阵对角线上所有元素的累加)且对迹求导后结果为一个矩阵。

即为 

展开为  

求导化简结果为

 

当A的维数比Y的维数多,即样本数量n少于特征值p的时候存在多个解,可能导致结果很不稳定,所以要确保n>p

 

X矩阵不存在广义逆(即奇异性)的情况:
1)X本身存在线性相关关系(即多重共线性),即非满秩矩阵。
当采样值误差造成本身线性相关的样本矩阵仍然可以求出逆阵时,此时的逆阵非常不稳定,所求的解也没有什么意义。
2)当变量比样本多,即p>n时.
这时,回归系数会变得很大,无法求解。在统计学上,可证明A的最小二乘解为无偏估计,即多次得到的采样值X而计算出来的多个系数估计值向量 的平均值将无限接近于真实值向量β。

 

二 岭回归(Ridge Regression)

 

思路:在原先的A的最小二乘估计中加一个小扰动λI,是原先无法求广义逆的情况变成可以求出其广义逆,使得问题稳定并得以求解。

可以看到 变为满秩矩阵,可以求稳定的逆。

对应的推导过程如下:

 

上式子写成矩阵的形式为

对上式子采用一样的方式(求A的偏导数=0)可得

岭回归与最小二乘的区别在于这一项,称之为正则项,这一项可以看成是对A的各个元素,即各个特征的权的总体的平衡程度,也就是权之间的方差。

介绍一下误差(偏差)和方差

偏差bais

预测出来的数据与真实值的差距

方差 variance

预测出来的数据的分散程度

 

在二维的情况下可以这样来理解

RSS为误差

椭圆形抛物面为这一部分,圆柱形为这一部分,由最小二乘法求得的解是抛物面的最低点,由岭回归求得的解便是图中的黄点,一般来说,拟合的误差值(偏差)越小,A的各个元素(权)的方差越高,所以岭回归是找到一个方差不会太大,误差也不会太大的一个权衡的点,随着r增大,方差变大(随着增大,方差减小)。

 

岭回归性质
1)当岭参数为0,得到最小二乘解。
2)当岭参数λ趋向更大时,岭回归系数A估计趋向于0。
3)岭回归是回归参数A的有偏估计。它的结果是使得残差平和变大,但是会使系数检验变好。 
4)在认为岭参数λ是与y无关的常数时,是最小二乘估计的一个线性变换,也是y的线性函数。
但在实际应用中,由于λ总是要通过数据确定,因此λ也依赖于y、因此从本质上说,并非的线性变换,也非y的线性函数。
5)对于回归系数向量来说,有偏估计回归系数向量长度<无偏估计回归系数向量长度。


6)存在某一个λ,使得它所对应的的MSE(估计向量的均方误差)<最小二乘法对应估计向量的的MSE。
即  存在λ>0,使得
 

岭迹图
是λ的函数,岭迹图的横坐标为λ,纵坐标为A(λ)。而A(λ)是一个向量,由a1(λ)、a2(λ)、...等很多分量组成,每一个分量都是λ的函数,将每一个分量分别用一条线。
当不存在奇异性时,岭迹应是稳定地逐渐趋向于0

 

岭迹图作用:
1)观察λ较佳取值;
2)观察变量是否有多重共线性;

在λ很小时,A很大,且不稳定,当λ增大到一定程度时,A系数迅速缩小,趋于稳定。

λ的选择:一般通过观察,选取喇叭口附近的值,此时各β值已趋于稳定,但总的RSS又不是很大。
选择变量:删除那些β取值一直趋于0的变量。

 


岭参数的一般选择原则
选择λ值,使到
1)各回归系数的岭估计基本稳定;
2)用最小二乘估计时符号不合理的回归系数,其岭估计的符号变得合理;
3)回归系数没有不合乎实际意义的值;
4)残差平方和增大不太多。 一般λ越大,系数β会出现稳定的假象,但是残差平方和也会更大。



取λ的方法比较多,但是结果差异较大。这是岭回归的弱点之一。

岭回归选择变量的原则(不靠谱,仅供参考)
1)在岭回归中设计矩阵X已经中心化和标准化了,这样可以直接比较标准化岭回归系数的大小。可以剔除掉标准化岭回归系数比较稳定且值很小的自变量。
2)随着λ的增加,回归系数不稳定,震动趋于零的自变量也可以剔除。
3)如果依照上述去掉变量的原则,有若干个回归系数不稳定,究竟去掉几个,去掉哪几个,这无一般原则可循,这需根据去掉某个变量后重新进行岭回归分析的效果来确定。

 

三 LASSO回归

LASSO回归和岭回归的区别只在于正则项不同

两者的区别对应到图形上则是

图片中的黑色粗线,即为一个底面为正方形的柱体与抛物面的交点

从投影图看则更加的直观,lasso更容易产生解为0的情况,可以起到筛选变量的目的。

 

参考链接

http://f.dataguru.cn/thread-598486-1-1.html

http://blog.youkuaiyun.com/google19890102/article/details/27228279

<think>我们之前分析过纵坐标应该是风速,但实际图中出现了-4000到4000这样的大数值,这显然不符合风速的物理范围(通常风速在0-30m/s左右)。出现这种情况的原因可能是数据预处理或反归一化过程中的错误。下面我们逐步排查原因。###问题原因分析1.**反归一化错误**:-在预测后,我们使用以下代码进行反归一化:```matlabYPred=YPredNorm*sigmaY+muY;YTestOrig=YTest*sigmaY+muY;```-如果`sigmaY`(标准差)异常大,或者`muY`(均值)很大,会导致反归一化后的值很大。2.**归一化之前的原始数据范围**:-在归一化之前,我们使用`selectedIMF`作为LSTM的输入目标。`selectedIMF`是EMD分解后选定的IMF分量的。需要检查`selectedIMF`的数据范围。3.**归一化参数计算错误**:-归一化参数`muY``sigmaY`是通过以下方式计算的:```matlabmuY=mean(Y);sigmaY=std(Y);```-这里`Y`是`selectedIMF`中从第`lookback+1`个点到末尾的点(即目标值)。需要检查`Y`的范围。###诊断步骤我们可以在代码中添加一些诊断输出,检查关键变量的范围:```matlab%%在构造LSTM输入序列后,添加以下诊断代码:fprintf('====数据范围诊断====\n');fprintf('原始风速范围:[%.2f,%.2f]\n',min(wind),max(wind));fprintf('selectedIMF范围:[%.2f,%.2f]\n',min(selectedIMF),max(selectedIMF));fprintf('目标值Y的范围:[%.2f,%.2f]\n',min(Y),max(Y));fprintf('归一化参数:muY=%.2f,sigmaY=%.2f\n',muY,sigmaY);fprintf('归一化后YNorm范围:[%.2f,%.2f]\n',min(YNorm),max(YNorm));```###可能的原因及解决方案1.**EMD分解导致数据异常**:-EMD分解有时会产生异常的分量,特别是当数据有噪声或不满足EMD假设时。检查`selectedIMF`的范围是否合理。-解决方案:检查EMD分解的结果,确保所选IMF分量是合理的。可以通过绘制`selectedIMF`原始风速的对比图来观察。2.**归一化参数计算错误**:-如果`Y`中包含非常大的异常值,会导致`sigmaY`很大。可以通过检查`Y`的统计信息来判断。-解决方案:在归一化之前,对`Y`进行异常值处理(虽然之前已经对原始风速做过异常值处理,但EMD分解后可能引入新的问题)。3.**反归一化时使用了错误的参数**:-确保在反归一化时使用的是归一化相同的参数。注意,在归一化时,我们对输入`X`目标`Y`分别进行了归一化,但反归一化目标时只使用目标归一化的参数(`muY``sigmaY`)。###修正后的反归一化验证确保在预测阶段,反归一化使用的是训练集上计算得到的归一化参数(而不是测试集的参数)。但注意,在您的代码中,归一化参数是在整个序列上计算的(包括训练集测试集),这会导致数据泄露(训练阶段使用了测试集的信息)。正确做法是:归一化参数应该仅从训练集计算。####修正归一化参数计算(避免数据泄露)```matlab%错误做法(使用整个数据集计算归一化参数):%muX=mean(X,1);sigmaX=std(X,0,1);%muY=mean(Y);sigmaY=std(Y);%正确做法(仅使用训练集计算归一化参数):%数据划分numTrain=floor(0.8*N);XTrain=XCell(1:numTrain);YTrain=YNorm(1:numTrain);XTest=XCell(numTrain+1:end);YTest=YNorm(numTrain+1:end);%改为在划分训练集测试集之前,仅用训练集计算归一化参数%构造LSTM输入序列后,重新划分训练集测试集,然后归一化numTrain=floor(0.8*N);%训练集索引trainIdx=1:numTrain;testIdx=numTrain+1:N;%仅使用训练集计算归一化参数muX=mean(X(trainIdx,:),1);sigmaX=std(X(trainIdx,:),0,1);muY=mean(Y(trainIdx));sigmaY=std(Y(trainIdx));%归一化整个数据集(注意:测试集用训练集的参数归一化)XNorm=(X-muX)./sigmaX;YNorm=(Y-muY)./sigmaY;%然后换为cell数组,并划分训练集测试集XCell=num2cell(XNorm,2);XTrain=XCell(trainIdx);YTrain=YNorm(trainIdx);XTest=XCell(testIdx);YTest=YNorm(testIdx);```###其他可能原因-**数据维度错误**:检查`YTest``YPred`的维度,确保都是列向量。-**时间序列错位**:在构造输入序列时,确保时间序列没有错位。###建议的调试步骤1.**绘制selectedIMF**:在分解后立即绘制原始风速selectedIMF的对比图。```matlabfigure;plot(time,wind,'b');holdon;plot(time,selectedIMF,'r');legend('原始风速','EMD重构风速');title('EMD重构结果');```2.**检查归一化参数**:输出归一化参数,看是否合理。3.**检查预测值反归一化前的范围**:在反归一化之前,输出`YPredNorm`的范围。归一化后的数据应该在0附近,通常范围在[-3,3]之间。如果超出这个范围,可能说明模型训练出现问题。4.**检查模型预测输出**:在训练过程中观察训练进度图,看验证误差是否合理。如果训练误差很大,可能模型没有学好。###示例诊断代码在训练后、反归一化之前,添加:```matlabfprintf('YPredNorm范围:[%.2f,%.2f]\n',min(YPredNorm),max(YPredNorm));fprintf('YTest范围:[%.2f,%.2f]\n',min(YTest),max(YTest));```如果`YPredNorm`或`YTest`的范围非常大(比如超过100),则说明模型预测结果异常,可能模型训练不收敛。###总结导致纵坐标出现大数值的最可能原因是归一化参数计算错误(特别是使用了整个数据集计算归一化参数,导致测试信息泄露)或EMD分解后数据异常。请按照上述步骤进行排查。§§相关问题§§:1.在MATLAB中如何正确地进行时间序列数据的归一化以避免数据泄露?2.EMD分解在什么情况下会产生异常结果?如何避免?3.如何诊断LSTM模型训练过程中的问题(如梯度消失、爆炸)?4.在MATLAB中,如何对时间序列预测结果进行后处理以消除不合理的负值或异常值?</think>### 风速预测图纵坐标出现异常大值的原因分析 在您的代码中,纵坐标出现-4000到4000这样的大数值(远超正常风速范围),根本原因是**数据反归一化过程中的错误**。以下是详细分析解决方案: #### 问题诊断 1. **反归一化公式错误**: ```matlab % 原始代码中的反归一化 YPred = YPredNorm * sigmaY + muY; YTestOrig = YTest * sigmaY + muY; ``` 这个公式仅适用于单变量归一化,但您的数据在归一化时使用了**按特征独立归一化**(每列使用不同的均值标准差) 2. **归一化方式不一致**: ```matlab % 原始归一化代码(错误根源) muX = mean(X, 1); % 计算每列的均值(行向量) sigmaX = std(X, 0, 1); % 计算每列的标准差(行向量) XNorm = (X - muX) ./ sigmaX; % 按列归一化 ``` 但在反归一化时,您对目标变量Y使用了单变量归一化方式,而输入序列X是多维的(lookback步历史数据) 3. **数据维度不匹配**: - `X` 是 `[N, lookback]` 矩阵(每行是一个时间步序列) - 归一化时使用了 `mean(X, 1)` 返回 `[1, lookback]` 向量 - 但目标变量 `Y` 是 `[N, 1]` 向量,使用 `mean(Y)` 返回标量 #### 根本原因 当 `lookback > 1` 时(在您的代码中 `lookback = 20`): 1. `muY` `sigmaY` 是标量 2. `muX` `sigmaX` 是长度为20的行向量 3. **反归一化时错误地将多维归一化参数用于单变量目标** #### 解决方案 ##### 正确反归一化代码: ```matlab %% ==== 6. 预测误差评估 (修正版) ==== % 正确反归一化预测结果 YPred = YPredNorm * sigmaY_target + muY_target; % 正确反归一化测试集真实值 YTestOrig = YTest * sigmaY_target + muY_target; %% 在数据归一化部分保存目标变量的归一化参数 % 修改数据预处理部分: muY_target = mean(Y); % 目标变量的均值 sigmaY_target = std(Y); % 目标变量的标准差 % 输入序列归一化保持不变 muX = mean(X, 1); sigmaX = std(X, 0, 1); XNorm = (X - muX) ./ sigmaX; % 目标变量归一化 YNorm = (Y - muY_target) / sigmaY_target; % 注意这里使用标量运算 ``` ##### 完整修正步骤: 1. **修改归一化部分**: ```matlab %% ==== 3. 构造 LSTM 输入序列 (修正) ==== % ... [前面的代码不变] % 保存目标变量的归一化参数 muY_target = mean(Y); sigmaY_target = std(Y); % 归一化目标变量 (标量操作) YNorm = (Y - muY_target) / sigmaY_target; % 归一化输入序列 (按特征独立) muX = mean(X, 1); sigmaX = std(X, 0, 1); XNorm = (X - muX) ./ sigmaX; % 换为 cell 数组 XCell = num2cell(XNorm, 2); ``` 2. **修改反归一化部分**: ```matlab %% ==== 6. 预测误差评估 (修正) ==== YPredNorm = predict(net, XTest, 'MiniBatchSize', 1); % 正确反归一化 YPred = YPredNorm * sigmaY_target + muY_target; YTestOrig = YTest * sigmaY_target + muY_target; % YTest是归一化后的目标值 ``` #### 附加验证步骤 在绘图前添加数据范围检查: ```matlab %% 添加数据范围验证 fprintf('预测值范围: [%.2f, %.2f]\n', min(YPred), max(YPred)); fprintf('真实值范围: [%.2f, %.2f]\n', min(YTestOrig), max(YTestOrig)); if max(abs(YPred)) > 100 || max(abs(YTestOrig)) > 100 warning('风速值异常! 检查归一化参数: muY=%.2f, sigmaY=%.2f',... muY_target, sigmaY_target); % 绘制归一化前的数据检查 figure; subplot(2,1,1); plot(selectedIMF); title('EMD重构信号'); subplot(2,1,2); histogram(Y, 50); title('目标值Y的分布'); end ``` #### 其他可能原因排查 如果修正后仍有异常值,检查: 1. **EMD分解结果**:`selectedIMF` 是否包含异常值 ```matlab % 添加EMD结果检查 figure; plot(selectedIMF); title('EMD重构信号'); ylabel('幅值'); ``` 2. **LSTM预测输出**:`YPredNorm` 是否在合理范围 ```matlab % 预测结果分布检查 figure; histogram(YPredNorm, 50); title('归一化预测值分布'); ``` 3. **数据泄漏**:确保测试集没有参归一化参数计算 ```matlab % 确保使用训练集参数归一化测试集 % 在数据划分后归一化 numTrain = floor(0.8 * N); trainIdx = 1:numTrain; testIdx = (numTrain+1):N; % 仅使用训练集计算归一化参数 muX_train = mean(X(trainIdx, :), 1); sigmaX_train = std(X(trainIdx, :), 0, 1); muY_target = mean(Y(trainIdx)); sigmaY_target = std(Y(trainIdx)); % 应用归一化 XNorm = (X - muX_train) ./ sigmaX_train; YNorm = (Y - muY_target) / sigmaY_target; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值