我有一些C++代码正在获取一堆 X,Y 值并执行 线性贴合
Eigen::Matrix<float, Eigen::Dynamic, 2> DX;
Eigen::Matrix<float, Eigen::Dynamic, 1> DY;
对于数据值的循环(编辑了一点,因为我的数据源 比简单的数组复杂一些(:
{
DX(i,0) = x[i];
DX(i,1) = 1;
DY(i,0) = y[i];
}
然后
Eigen::Vector2f Dsolution = DX.colPivHouseholderQr().solve(DY);
// linear solution is in Dsolution[0] and Dsolution[1]
我需要该计算的相关系数。 如何获取?
大多数本征的东西都在我头顶两层楼左右,所以你可能需要用基本的方式把它拼出来。
根本问题是我在多个数据集上运行此例程 我需要一些关于内部噪声和方差的数据质量的指示。
谢谢!
我假设您要计算最小二乘拟合的 R² 系数。
线性最小二乘法
首先,让我们回顾一下您正在做的事情。在你的Dsolution
向量中有两个系数(我们称它们为a
和b
,它们是你的x
s和y
s之间的仿射模型的估计参数(。这意味着对于每个x[i]
,模型对相应y[i]
的估计值estimated_y[i] = a * x[i] + b
。
a
和b
的计算方法是最小化观测y[i]
与其估计值a*x[i] + b
(也称为残差(之差的平方和。事实证明,你可以通过解决线性问题来简单地做到这一点,这就是为什么你使用本征solve()
来找到它们。
计算 R²
现在我们要计算 R²,这是您的拟合度"好"程度的指标。
如果我们遵循上面链接的维基百科的定义,要计算 R²,您需要:
- 计算观测值的平均值
y_avg
计算总平方和, - 即观测值与其平均值之间的平方差之和(这类似于方差,但您不除以样本数(
- 通过将每个
y
的预测值和观测值之间的差值平方和来计算残差平方和
那么R²就1 - (sum_residuals_squares / sum_squares)
特征码
让我们看看如何使用特征码做到这一点:
float r_squared(const MatrixX2f& DX, const VectorXf& DY, const Vector2f& model)
{
// Compute average
const float y_avg = DY.mean();
// Compute total sum of squares
const int N = DX.rows();
const float sum_squares = (DY - (y_avg * VectorXf::Ones(N))).squaredNorm();
// Compute predicted values
const VectorXf estimated_DY = DX * model;
// Compute sum of residual squared
const float sum_residuals_square = (DY - estimated_DY).squaredNorm();
return 1 - (sum_residuals_square / sum_squares);
}
两个平方和表达式中使用的技巧是使用平方范数函数,因为向量的平方范数是其分量的平方和。我们这样做两次,因为我们有两个平方和要计算。
在第一种情况下,我们创建了一个大小为N
的向量充满了我们乘以y_avg
的向量,以获得一个元素都是y_avg
的向量。然后DY的每个元素减去该向量将被y[i] - y_avg
,我们计算平方范数得到平方的总和。
在第二种情况下,我们首先使用线性模型计算预测y
,然后使用平方范数计算与观测值的差值,使用平方范数计算平方差的总和。