You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用VBA的WorksheetFunction.LinEst正确计算R²?拟合差异解惑

多项式拟合中LinEst计算R²异常的问题与解决

问题背景

我编写了VBA代码,对基于公式 Y = 2*X^3 - 3*X^2 + 4*X - 5 的数据进行线性、二阶、三阶多项式拟合,X取值为1-10,对应Y值为-2,7,34,91,190,343,562,859,1246,1735。拟合系数与Excel图表趋势线一致,但R²结果差异极大:

  • 线性拟合:趋势线R²=0.8483,LinEst返回值=27.17940397
  • 二阶多项式拟合:趋势线R²=0.9962,LinEst返回值=1.828348201
  • 三阶多项式拟合:趋势线R²=1,LinEst返回值=1.43117E-15

疑问:为何出现这种差异?R²为何大于1?如何通过WorksheetFunction.LinEst正确计算R²?

原代码

Sub Data_regression()

Dim X() As Double   ' X values
Dim Y() As Double   ' Y values
Dim Z() As Variant  ' Regression statistics

Dim number_datapoints As Integer
Dim i, r As Integer

' Insert data in columns A and B
' Column A contains X values
' Column B contains Y values
' First value should start in row 1

With ActiveSheet

' Get number of datapoints
r = 1
While .Cells(r + 1, 1).Text <> ""
    r = r + 1
Wend
number_datapoints = r

' ********* LINEAR REGRESSION *********

' Define the ranges for X and Y data
ReDim X(number_datapoints - 1, 0)
ReDim Y(number_datapoints - 1, 0)
r = 1
For r = 1 To number_datapoints
    i = r - 1
    Y(i, 0) = .Cells(r, 2)
    X(i, 0) = .Cells(r, 1)
Next r

' Perform regression using LINEST function
Z = WorksheetFunction.LinEst(Y, X, True, True)

' Write the results back to the worksheet
r = 1
.Cells(r, 4).Value = "y = m.x + c"
.Cells(r + 1, 4).Value = "slope (m):"
.Cells(r + 1, 5).Value = Z(1, 1)
.Cells(r + 2, 4).Value = "Intercept (c):"
.Cells(r + 2, 5).Value = Z(1, 2)
.Cells(r + 3, 4).Value = "R-squared:"
.Cells(r + 3, 5).Value = Z(2, 1)  ' 错误:此处取错了R²的位置

' ********* QUADRATIC REGRESSION *********

ReDim Preserve X(number_datapoints - 1, 1)

For i = 0 To number_datapoints - 1
    X(i, 1) = X(i, 0) ^ 2
Next i

' Perform regression using LINEST function
Z = WorksheetFunction.LinEst(Y, X, True, True)

' Write the results back to the worksheet
r = 6
.Cells(r, 4).Value = "y = a.x^2 + b.x + c"
.Cells(r + 1, 4).Value = "a:"
.Cells(r + 1, 5).Value = Z(1, 1)
.Cells(r + 2, 4).Value = "b:"
.Cells(r + 2, 5).Value = Z(1, 2)
.Cells(r + 3, 4).Value = "c:"
.Cells(r + 3, 5).Value = Z(1, 3)
.Cells(r + 4, 4).Value = "R-squared:"
.Cells(r + 4, 5).Value = Z(2, 1)  ' 错误:此处取错了R²的位置

' ********* THIRD DEGREE POLINOMIAL REGRESSION *********

ReDim Preserve X(number_datapoints - 1, 2)

For i = 0 To number_datapoints - 1
    X(i, 2) = X(i, 0) ^ 3
Next i

' Perform regression using LINEST function
Z = WorksheetFunction.LinEst(Y, X, True, True)

' Write the results back to the worksheet
r = 12
.Cells(r, 4).Value = "y = a.x^3 + b.x^2 + c.x + d"
.Cells(r + 1, 4).Value = "a:"
.Cells(r + 1, 5).Value = Z(1, 1)
.Cells(r + 2, 4).Value = "b:"
.Cells(r + 2, 5).Value = Z(1, 2)
.Cells(r + 3, 4).Value = "c:"
.Cells(r + 3, 5).Value = Z(1, 3)
.Cells(r + 4, 4).Value = "d:"
.Cells(r + 4, 5).Value = Z(1, 4)
.Cells(r + 5, 4).Value = "R-squared:"
.Cells(r + 5, 5).Value = Z(2, 1)  ' 错误:此处取错了R²的位置

End With

End Sub

问题原因

你错误引用了LinEst返回数组中R²的位置:
当LinEst的第四个参数stats=True时,返回的是一个5行×(自变量列数+1)列的多维数组,其中R²(决定系数)位于第三行第一列(即Z(3,1))。而你之前取值的Z(2,1)是对应系数的标准误差,Z(5,1)是回归平方和(SSR),这些都不是R²,因此出现了大于1或极小值的异常结果。

修正方法

将所有获取R²的代码行,从Z(2,1)改为Z(3,1)即可。修正后的关键代码片段如下:

线性拟合部分

.Cells(r + 3, 4).Value = "R-squared:"
.Cells(r + 3, 5).Value = Z(3, 1)  ' 正确的R²位置

二阶多项式拟合部分

.Cells(r + 4, 4).Value = "R-squared:"
.Cells(r + 4, 5).Value = Z(3, 1)  ' 正确的R²位置

三阶多项式拟合部分

.Cells(r + 5, 4).Value = "R-squared:"
.Cells(r + 5, 5).Value = Z(3, 1)  ' 正确的R²位置

LinEst返回数组的统计量位置说明

为避免后续出错,明确stats=True时返回数组的核心统计量位置:

  • 第1行:回归系数(从最高次项到常数项,比如三阶多项式依次是X³、X²、X、常数项的系数)
  • 第2行:对应系数的标准误差
  • 第3行:第1列=R²,第2列=Y的标准误差
  • 第4行:第1列=F统计量,第2列=自由度
  • 第5行:第1列=回归平方和(SSR),第2列=残差平方和(SSE)

修正后,LinEst返回的R²将与Excel趋势线的结果完全一致。

内容的提问来源于stack exchange,提问作者Daniel Louw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:23:10