在Matlab中如何计算决定系数R^2和相关系数r
Problem
当你使用polyfit
函数进行多项式拟合之后,你希望计算决定系数或者相关系数看看拟合效果如何。聪明的你肯定觉得聪明的 Matlab 的polyfit
函数的返回值中会有\(R^2\)或者\(r\)吧。你尝试disp
了一下,发现有一个结构体\(S\)。再查一查帮助文档,发现误差估计结构体\(S\)中只有一个范德蒙德矩阵\(R\)、自由度\(df\)和残差的范数\(normr\),并没有你想要的\(R^2\)或者\(r\)。
Solution
很遗憾,我们还是需要手动计算这两个系数。
假设X
是原始数据自变量,Y
是原始数据因变量,我们先进行多项式拟合:
1 | p = polyfit(X, Y, n); % n是多项式次数 |
得到了Y_pre
为多项式拟合后的预测值。
决定系数R-squared的计算
我们使用如下公式计算\(R^2\): \[ \begin{align} RSS&=\sum (y_{pre}-y)^2\\ ESS&=\sum (y-\overline y)^2\\ R^2&=1-\frac{ESS}{TSS} \end{align} \] 代码如下:
1 | SSerr = sum((Y_pre - Y).^2); % 残差平方和 |
相关系数r的计算
计算相关系数\(r\),可以使用corrcoef
函数先计算相关系数矩阵,取其非对角线元素的值。
代码如下:
1 | r = corrcoef(Y_pre, Y); |
Others
\(r\)(相关系数)和 \(R^2\)(决定系数,也称为R-squared)是可以用于衡量数据的不同的方面的两个不同的统计量。
Calculation
\[ \begin{gather} R^2=1-\frac{RSS}{TSS}=1-\frac{\sum (y_{pre}-y)^2}{\sum (y-\overline y)^2}\\ r=\frac{n(\sum x y)-(\sum x)(\sum y)}{\sqrt{[n \sum x^2-(\sum x)^2][n \sum y^2-(\sum y)^2]}}\\ R^2=r^2 \end{gather} \]
Comparison
- 相关系数 \(r\in[-1,1]\):衡量两个变量之间线性关系的强度和方向。
- \(r = 1\) 表示完全正相关。
- \(r = -1\) 表示完全负相关。
- \(r = 0\) 表示没有线性相关。
- 决定系数 \(R^2\in[0,1]\):衡量模型对因变量变异的解释程度。
- R² = 1 表示模型完美地解释了数据的变异。
- R² = 0 表示模型没有解释数据的任何变异。
R² 衡量模型拟合优度的指标,告诉我们模型对数据变异的解释程度有多好。而相关系数 r 仅仅告诉我们两个变量之间线性关系的强度,它并不对模型拟合优度全面评估。
如果想要更全面的评估,通常会看 \(R^2\) 。
如果只关心两个变量之间是否有线性关系,看相关系数 \(r\)。
后续
补充于2024-7-31
但是有时候会出现 \(R^2<0\) 的情况。等等,为什么 \(R^2\) 会小于零?它不是 \(r\) 的平方吗?
当出现拟合效果特别差的时候,就有可能会出现(?)
今天我们在研读一篇论文的时候,遇到了“多元线性回归”。而由于题目背景,有些小组疑惑是否要规定常数项为 0。假如使用 Matlab 中的多元线性回归函数 regress
的话,当 X
不存在全为 1 的一列时,会出现报错:
警告: R 方和 F 统计量的定义不良,除非 X 有一列全部为 1。
键入 "help regress" 了解详细信息。
同时,如果硬要输出 regress
返回值中的 stat(1)
的话,会发现 \(R^2\) 可能是一个负数。(演示代码见附录)
实际上这是因为 \(R^2\) 的定义不同导致的。
范德蒙德矩阵
1
2[b,bint,r,rint,stats]=regress(Y,X,0.05);
fprintf("R^2=stats(1)=%f\n",stats(1));
输出 R^2=stats(1)=-0.381201
,为负数。
\(1-\frac{ESS}{TSS}\)
1
2
3
4Y_pre=X*b;
ESS=sum((Y_pre-Y).^2);
TSS=sum((Y-mean(Y)).^2);
fprintf("R^2=1-ESS/TSS=%f\n",1-ESS/TSS);输出
R^2=1-ESS/TSS=-0.381201
,结果与范德蒙德矩阵结果一致。\(\frac{RSS}{TSS}\)
1
2RSS=sum((Y_pre-mean(Y)).^2);
fprintf("R^2=RSS/TSS=%f\n",RSS/TSS);输出
R^2=RSS/TSS=3.746787
,为正数。\(r^2\)
1
2r = corrcoef(Y_pre, Y);
fprintf("r=corrcoef()(1,2)=%f=>r^2=%f\n",r(1,2),(r(1,2)).^2);输出
r=corrcoef()(1,2)=0.869397=>r^2=0.755851
,为正数。
以上。
References
polyfit and R^2 value - MATLAB Answers - MATLAB Central (mathworks.cn)
相关系数 - MATLAB corrcoef - MathWorks 中国
Code
1 | X_data=[120 73 180 80 125 125 81.1000000000000 90 |