使用特征奇异值分解进行线性回归



我有一个过度确定的2D数据系统。我正在使用特征库来计算线性回归线。数据以A x = b的形式表示,其中A是nx1矩阵,b是n大小的向量。

当我运行SVD时,我计算斜率,并且直线通过原点(即,没有y轴截距)。对于没有经过原点的趋势线的数据,这不会导致我正在寻找的线。

下面是一个例子:

//Eigen
#include <Eigen/Dense>
//std
#include <cstdlib>
#include <iostream>
int main() {

Eigen::MatrixXd A(15,1);
Eigen::VectorXd b(15);
A << -4, -4, -4, -3, -3, -2, -2, -1, -1, -1, 0, 1, 1, 2, 2;
b << 11.8, 10.9, 11.5, 9.6, 8.4, 7.4, 6.2, 4.8, 5.4, 4.5, 3.5, 1.5, 0.1, -0.5, -2;

//Calculate the SVD and solve for the regression line
Eigen::MatrixXd x = A.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(b);
Eigen::MatrixXd b_reg = A*x;
std::cout << x << std::endl;
std::cout << b_reg << std::endl;
return EXIT_SUCCESS;
}

我预计趋势线是y = -2.079x + 2.907。我上面的程序报告x为-2.714,经过原点的行

是否有一种简单的方法来使用SVD来恢复"偏移量"?回归线吗?还是应该使用SVD以外的工具?在这种情况下,什么?

今天我遇到了同样的问题,并让它与Eigen库一起工作。

Eigen假设与你的问题相关的所有数据都编码在你传递的矩阵中。在您的例子中,您告诉特征,所有函数的形式是:

y = m*x

因为A矩阵是一维的。当然,您需要的是:

y = m*x + b

你怎么能让艾根考虑这个?我们用另一种形式重写一下因为你已经使用了b在传统线性代数格式的代码中:

b = p *A + p

,其中p1和p2是要求解的参数。如果你有一个a和b值的列表(你有,这些是前两个方程中的x和y值),你可以把它写成向量表示法:

据美联社>b =

,p= {p1, p2}和b= {b1, b2, b3,…}(有多少项就有多少项)

现在想想这个:如果p为2x1矩阵,且b是Nx1矩阵(N =您拥有的数据点数),a的维度是多少?需要吗?它必须是Nx2

"那么A的另一列是什么呢?吗?"你问?看一个例子:

A11 * p1 + A12 * p2 = b1

啊,等等,p2是常数,是你要解的y轴截距。因此:

A12 * p2 = p2

A22 * p2 = p2

A32 * p2 = p2

这是怎么回事?如果第二列中的所有值A1。

所以…在您的代码中,使A为2列矩阵,并将第二列填满1。结果将为您提供您正在寻找的两个参数。你可以通过文档中的示例输出这些值:JacobiSVD

最新更新