1. 先把 RSQ 放上台面:它到底在算什么
Excel 里有一个常年被低估、也常年被滥用的函数:RSQ。名字看着像"RSQ = R Square",实际上它算的是两组数值之间皮尔逊相关系数的平方,也就是决定系数 R²。很多人第一次用它是在做销售预测、投放效果评估、设备参数与良品率的关系分析,写下一行=RSQ(B2:B101,A2:A101),看到一个 0.87,然后在汇报里写下"相关性很强,模型可用"。这一步跳得太快了,中间漏掉的信息量,比这个函数本身的语法要多得多。
我把 RSQ 定位成一个"诊断工具"而不是"结论工具"。它能告诉你一件事:一组配对数据里,线性成分占了多少比例。它不能告诉你因果,不能告诉你模型对不对,也不能告诉你新样本能不能预测准。这篇内容面向三类人:日常用 Excel 做数据核对的运营和财务同学、需要快速判断两组指标关系的工程与质量人员、以及正在从 Excel 过渡到脚本分析、想把统计概念重新夯实一遍的开发者。函数语法十分钟就能学会,真正难的是把它算出来的那个数字放回正确的位置上。
1.1 一句话定义与三个等价形式
RSQ(known_y's, known_x's)返回的是CORREL(y,x)的平方,也就是PEARSON(y,x)的平方。三个函数在数学上同源:CORREL和PEARSON给的是 r,RSQ给的是 r²。所以有一个非常实用的自查手段——你在同一个区域上同时写=RSQ(B2:B11,A2:A11)和=CORREL(A2:A11,B2:B11)^2,两个结果必须一致到小数点后十几位,如果不一致,说明你引用的区域范围不一样,或者中间某一列存在脏数据被隐式剔除了。
决定系数还有第二个等价定义,来自回归的平方和分解:R² = SSR/SST = 1 − SSE/SST。其中 SST 是总平方和(每个 y 减去 y 均值再平方求和),SSR 是回归平方和,SSE 是残差平方和。这个定义比"相关系数平方"更本质,因为它能推广到多元回归,而RSQ函数只能吃两组一维数据。理解这一点很关键:Excel 的 RSQ 只在简单线性回归(一个自变量)的场景下等于模型的 R²,一旦你做了多元回归,就得换成LINEST的输出或者别的口径。
第三个形式是相关系数的协方差表达:r = Sxy / √(Sxx·Syy),其中 Sxy 是离差乘积和,Sxx 和 Syy 是各自的离差平方和。这个形式看着最笨,但它是最适合手工验算的形式,也是排查异常值时最好用的形式——你能一眼看出到底是分子被拉大了,还是分母被撑爆了。
1.2 参数顺序不是装饰:known_y's 与 known_x's 的语义
这里有一个很多人不知道的细节:CORREL(array1, array2)两个参数是对称的,交换位置结果不变;但RSQ(known_y's, known_x's)的命名带着明确的语义方向——y 是被解释变量,x 是解释变量。数值上 RSQ 交换参数也不变(因为平方了),但语义上变了。为什么这件事重要?因为当你把 RSQ 和SLOPE、INTERCEPT、LINEST、TREND组合使用的时候,参数顺序必须保持一致,否则你算出来的斜率和 R² 描述的是两条不同的回归线,指标之间互相矛盾,而 Excel 不会给你任何提示。
我见过一个典型的翻车案例:某团队做设备温度(A 列)与产品尺寸偏差(B 列)的关系分析,先用=RSQ(A2:A61,B2:B61)得 0.72,再用=SLOPE(A2:A61,B2:B61)算斜率,然后拿斜率去反推"温度每升高 1 度,偏差变化多少"。方向反了,结论整个反了——实际算出的是"偏差每变化 1 单位,温度变化多少"。这种错误在数字上看不出任何异常,斜率是个正常的小数,R² 也正常,但业务解释彻底错了。
提示:把参数顺序写死成习惯——第一参数永远放"结果/被解释量",第二参数永远放"原因/解释量"。团队协作时,在表格的字段说明里标注清楚,比事后解释省事得多。
1.3 RSQ 在 Excel 函数家族里的位置
把相关函数排一下,会看得更清楚:CORREL/PEARSON给 r,RSQ给 r²,COVARIANCE.P/COVARIANCE.S给协方差(注意总体和样本两个版本),SLOPE给回归斜率,INTERCEPT给截距,LINEST给完整回归统计量数组,TREND和FORECAST.LINEAR给预测值,STEYX给回归标准误。这套函数构成了 Excel 里最完整的单变量线性回归工具链,RSQ是其中的"体检指标",不是"诊断报告"。
另外要注意新旧函数的差异。COVAR、FORECAST、PEARSON这些是兼容版本,新版本对应COVARIANCE.P、FORECAST.LINEAR、PEARSON本身没变。RSQ恰好没有新旧两版的问题,一直叫这个名字,所以兼容性上基本不用操心。但如果你的表格要在多个版本之间流转,还是建议在关键单元格旁边标注函数名和参数含义,避免接手的人改错。
2. 手工推导:把 R² 拆成三个平方和
我不太赞成"函数会用就行"这种态度来做统计分析。原因是这类函数出错的时候不报错,只给你一个看起来挺像回事的数字,你不手工推一遍,就没有能力判断这个数字是不是被某一行数据带偏了。下面拿一组十期的虚构数据走一遍完整流程,数据量小,方便你拿计算器复核。
2.1 一组十期数据的完整计算过程
设 x 为投放强度(1 到 10 的整数档位),y 为对应的到店人次(百人):
| 期次 | x | y |
|---|---|---|
| 1 | 1 | 2.3 |
| 2 | 2 | 3.6 |
| 3 | 3 | 6.5 |
| 4 | 4 | 7.8 |
| 5 | 5 | 10.4 |
| 6 | 6 | 11.9 |
| 7 | 7 | 14.6 |
| 8 | 8 | 15.8 |
| 9 | 9 | 18.6 |
| 10 | 10 | 19.4 |
第一步算均值:x̄ = 5.5,ȳ = 11.09。第二步算离差:dx 是 −4.5 到 4.5,dy 是 −8.79 到 8.31。第三步算三个平方和:Sxx = 82.5,Syy ≈ 326.35,Sxy ≈ 163.65。
于是 r = 163.65 / √(82.5 × 326.35) ≈ 163.65 / 164.08 ≈ 0.99738,R² ≈ 0.99477。
在 Excel 里,=RSQ(B2:B11,A2:A11)会直接给到 0.9948 左右(保留四位)。如果你算出来差得比较多,八成是均值算错了,或者把某一行的 y 和 x 对齐错了——后者是最常见的问题,尤其当数据是从别的系统导出的、中间删过行的时候。
回归系数也能顺手算出来:斜率 b = Sxy/Sxx = 163.65/82.5 ≈ 1.9836,截距 a = ȳ − b·x̄ = 11.09 − 1.9836×5.5 ≈ 0.1802。也就是大致上 y ≈ 0.18 + 1.98x。这个斜率能不能用?先别急着用,看下一步。
2.2 从 R² 反推显著性:t 值与 p 值
R² 高不高是一回事,这个关系是不是"真实存在"是另一回事。判断显著性用 t 检验,公式是:
t = r × √(n − 2) / √(1 − r²)
代入 r = 0.99738、n = 10:t ≈ 0.99738 × 2.8284 / 0.0723 ≈ 39.0,自由度 8。这个 t 值对应的双侧 p 值极小,远小于 0.001。在 Excel 里可以直接写=T.DIST.2T(39.0,8)验证。
反过来说,如果你只有 5 个数据点、R² = 0.6,r ≈ 0.775,t = 0.775 × √3 / √0.4 ≈ 0.775 × 1.732 / 0.632 ≈ 2.12,自由度 3,双侧 p 约 0.12,不显著。同一句"R² 有 0.6"在样本量 5 和样本量 500 的场景下,含义天差地别。这是我在做报告时一定会加的一列:R²、样本量、p 值,三个数一起出现,缺一个都容易被误读。
在 Excel 里搭一个小的显著性计算区,公式大致是这样(假设 B1 放 R²,B2 放样本量):
=B1 // R² =SQRT(B1/(1-B1)) // r 的绝对值,等价于 |r| =B3*SQRT(B2-2) // t 统计量,如果单独写在一个格子里 =T.DIST.2T(ABS(B4),B2-2) // 双侧 p 值如果追求一步到位,=T.DIST.2T(ABS(SQRT(B1/(1-B1))*SQRT(B2-2)),B2-2)也能算,但可读性差,不建议放在长期维护的表格里。
2.3 调整 R²:小样本的必要修正
R² 有一个众所周知的"作弊"倾向:增加自变量数量,它几乎不会下降,哪怕新加的变量纯属噪声。RSQ只能处理单变量,所以这个问题在单变量场景下稍微轻一些,但样本量小时仍然严重。修正办法是调整 R²:
调整 R² = 1 − (1 − R²) × (n − 1) / (n − k − 1)
其中 n 是样本量,k 是自变量个数。单变量回归时 k = 1。代入前面的例子:1 − 0.00523 × 9/8 ≈ 0.99412,几乎没变,因为样本量相对充足、R² 已经很高。
但如果 n = 5、R² = 0.90、k = 1:调整 R² = 1 − 0.10 × 4/3 ≈ 0.8667,掉了 3 个多点。如果 n = 3:调整 R² = 1 − 0.10 × 2/1 = 0.80,掉了 10 个点。样本越小,惩罚越重,这个惩罚力度是合理的——三个点拟合一条直线,中间那个点的自由度几乎被吃光。
注意:n = 2 的时候 R² 恒等于 1,因为两点必然连成一条直线、残差为零。所以拿两个数据点算 RSQ 然后说"完全线性相关",在统计上没有任何意义。我在审表格时看到只有两三行的 RSQ,一律打回去要求补数据。
3. 落地实操:RSQ 的五种写法与组合拳
语法层面的事情很快能讲完,真正的功夫在于"怎么写才不出错"。下面这几种写法,覆盖了从简单核对到日常报表的大部分场景,可以直接照抄。
3.1 最基础写法与动态区域的处理
最朴素的写法就是框选区域:=RSQ(B2:B101,A2:A101)。缺点是区域是死的,加一行数据就得手动改。改进方式有三种,按维护成本从低到高排:
第一种是命名区域 + 整列引用。把 A 列和 B 列定义为"投放强度""到店人次",公式写成=RSQ(到店人次,投放强度)。可读性最好,但整列引用在旧版本里会把标题行也算进去(标题是文本,会被忽略,问题不大,但会影响计算性能)。
第二种是表格结构化引用。把数据区转成 SuperTable(Ctrl+T),公式写成=RSQ(表1[到店人次],表1[投放强度]),新增行自动扩展。这是我最推荐的方案,维护成本几乎为零,而且不会误把下面不相干的数据卷进来。
第三种是用INDEX构造动态终点,避免整列引用:
=RSQ(B2:INDEX(B:B,COUNTA(B:B)),A2:INDEX(A:A,COUNTA(A:A)))这个写法有个隐患:它假设 B 列和 A 列的非空行数完全一致。如果其中一列中间有空行,两边的终点会错位,虽然最终因为长度不同会报#N/A(这算是好事,至少暴露了问题),但排查起来很费劲。更稳妥的做法是只用一列的计数来控制两边的范围:
=RSQ(B2:INDEX(B:B,COUNTA(A:A)),A2:INDEX(A:A,COUNTA(A:A)))3.2 与 LINEST 交叉验证:两套算法对不上就是有问题
LINEST返回的是回归统计量数组,第 1 行第 1 列是斜率,第 1 行第 2 列是截距,第 3 行第 1 列是 R²,第 3 行第 2 列是回归标准误。用INDEX取出来验证:
=INDEX(LINEST(B2:B11,A2:A11),1) // 斜率 =INDEX(LINEST(B2:B11,A2:A11),2) // 截距 =INDEX(LINEST(B2:B11,A2:A11),3,1) // R²前文那组数据的LINESTR² 应当与RSQ完全一致。如果对不上,可能的原因有:LINEST的const参数被设成了FALSE(强制截距过原点,R² 会变)、两边的区域范围不一致、或者数据中存在被隐式忽略的文本/空值。这个交叉验证我建议做成表格里的固定检查项,尤其是涉及对外发布的报表,两道算法互相校验,成本很低。
顺带说一句STEYX:它给的是回归标准误,单位与 y 相同。R² = 0.99 听起来很高,但如果 y 的量级是几万、标准误是几千,那这个模型在实际预测上的可用性就要打问号。R² 是相对指标,标准误是绝对指标,两个都要看。
3.3 残差诊断:R² 高不代表模型对
这一步是分水岭。绝大多数人算完 R² 就收工,实际上花五分钟做残差检查,能挡掉大部分"看着很美"的误判。做法很简单:先算出每个点的预测值,再算残差,然后看残差的结构。
=INDEX(LINEST(B2:B11,A2:A11),1) // 斜率 b =INDEX(LINEST(B2:B11,A2:A11),2) // 截距 a =a + b * A2 // 预测值 =B2 - 预测值 // 残差残差该看什么?三个地方。一是残差是否随 x 系统性变化——如果残差在 x 较小的时候全是正、较大的时候全是负,说明关系是弯的,直线拟合不合适,这时候 R² 再高也不能用直线推断。二是残差的离散程度是否随 x 增大而扩张(喇叭口形状),这叫异方差,会破坏显著性检验的前提。三是有没有一两个残差特别大的点,这些点往往是数据录入错误,或者是真正的异常事件,值得单独追查。
我个人的经验是:R² 超过 0.95 的时候,反而要更警惕。自然界和业务场景里,能到 0.95 以上的线性关系通常意味着三种情况之一——数据本身是同源推导的(比如用公式算出来的两列)、时间趋势造成的伪相关、或者样本太少。真正干净的业务数据,0.6 到 0.8 是很常见的区间。
3.4 用 FILTER 做配对清洗
新版 Excel 里FILTER让配对清洗简单了很多。假设 A 列是 x、B 列是 y,中间可能有空值或文本,你希望只保留两边都是数字的行:
=RSQ(FILTER(B2:B100,(ISNUMBER(A2:A100))*(ISNUMBER(B2:B100))), FILTER(A2:A100,(ISNUMBER(A2:A100))*(ISNUMBER(B2:B100))))这个写法看起来啰嗦,但它把"配对过滤"这件事显式化了。老版本 Excel 没有FILTER,可以用辅助列:C 列写=IF(AND(ISNUMBER(A2),ISNUMBER(B2)),B2,NA()),D 列写=IF(AND(ISNUMBER(A2),ISNUMBER(B2)),A2,NA()),然后=RSQ(C2:C100,D2:D100)。NA()会被 RSQ 忽略,而且这样处理的配对是对齐的,不会错位。
注意:Excel 的
RSQ、CORREL在遇到文本、逻辑值、空白单元格时,会成对忽略这些数据点。这个隐式行为不报错,很容易让人以为"100 行数据全用上了",实际上可能只用了 87 行。所以务必在报表里显式加一个计数单元格,比如=SUMPRODUCT((ISNUMBER(A2:A100))*(ISNUMBER(B2:B100))),把实际参与计算的行数亮出来。
3.5 一张参数速查表
把上面这些整理成一张表,贴在表格旁边当备忘:
| 函数/参数 | 作用 | 关键注意点 |
|---|---|---|
RSQ(y,x) | 返回 r² | 参数顺序影响语义,不影响数值 |
CORREL(a,b) | 返回 r | 与 RSQ 开方同值,可互相验证 |
SLOPE(y,x) | 回归斜率 | 必须与 RSQ 参数顺序一致 |
INTERCEPT(y,x) | 回归截距 | 与 SLOPE 配对使用 |
LINEST(y,x) | 完整统计量 | 第 3 行第 1 列是 R² |
STEYX(y,x) | 回归标准误 | 绝对量纲,比 R² 更能反映预测精度 |
const参数 | 是否强制过原点 | 设 FALSE 会改变 R² 含义 |
4. 误用警示:六个最常见的翻车现场
这部分是我最想写的。前面那些语法和推导,网上都能找到,但下面这些坑,基本都是从实际项目里摔出来的。
4.1 把 R² 当因果证据
R² 只描述"两组数一起变化的程度",它对因果一无所知。有一个流传很广的经典现象:某段时间内某类商品的销量和另一个完全无关的指标走势高度同步,R² 能到 0.9,但两者之间没有任何机制上的联系,只是都被同一条时间趋势带着走。这类"伪相关"在时间序列数据里极常见,尤其是两个都在增长的量放在一起比较的时候。
规避方法有两个。第一,做差分:把每一期减去上一期,用变化量代替原始值算 R²,能消掉大部分趋势造成的共振。第二,引入第三变量做控制,或者至少在报告里注明"未控制时间趋势"。我在写分析结论时,会把 R² 描述成"共同变动的比例",绝不用"导致""影响"这类词,除非背后有实验设计或者明确的业务机制支撑。
4.2 非线性关系下的双向失真
这是一个双向的坑,两边都会出事。
一边是虚高:如果真实关系是单调但非线性的(比如指数增长、对数衰减),R² 依然可能很高,因为它确实在"单调"这个意义上相关,但用直线去预测会在两端产生严重偏差。判断方法是看残差图,如果残差呈现明显的曲线形状,就不能用线性模型。
另一边是虚低,这个更隐蔽。举一组数据:x 取 −3 到 3,y 取 x 的平方,即 9、4、1、0、1、4、9。这组数据之间存在完美的确定性关系,但算出来的 r = 0,R² = 0。为什么?因为关系是 U 型的,x 增大时 y 先减后增,正负离差互相抵消,线性相关系数恰好为零。
所以有一个必须记住的结论:R² = 0 只说明没有线性相关,不说明没有关系。反过来同样成立:R² 高只说明线性成分多,不说明关系就是线性的。做任何 RSQ 之前,先画一张散点图,这个动作能挡掉一半的误判。
4.3 单点杠杆:一个异常值改写全局
R² 对异常值极其敏感,因为它用的是平方和,误差被平方放大。更麻烦的是"杠杆点"——在 x 方向上远离均值的点,它对回归线的拉扯力远超普通点。一个典型的场景是:9 个点散乱无章、R² 只有 0.05,加上 1 个在 x 轴远端、y 值也很高的点,R² 瞬间跳到 0.7,而且看起来"数据量还挺多"。这种点在设计实验时是有效信息,在自然观测数据里就很可能是录入错误、特殊事件或者口径变更。
处理上我一般分三步走:先用条件格式把离均值超过 3 个标准差的点标出来;再逐个判断它是"错误"还是"真实极端事件",前者修正、后者保留但要单列说明;最后做一次"剔除该点后重算"的敏感性检验,把两个 R² 都写进报告。如果两个数差得很多,说明结论不稳定,这时候不该给单一结论。
提示:敏感性检验不用做得很复杂,加一个辅助列标记,然后
=RSQ(FILTER(B2:B100,标记列="保留"), FILTER(A2:A100,标记列="保留"))就够了。花两分钟,能避免后面被人质疑时无法自证。
4.4 样本量陷阱与过拟合
样本量的问题有两个层面。第一个层面是前面提过的:样本太小,R² 天然偏高。n = 3 的时候 R² 的期望值本来就很高,n = 2 的时候恒为 1。第二个层面是"数据窥探"——你先看了数据,发现某两列很相关,然后才去算 R²,这时候 R² 已经不是一个无偏的评估指标了,因为你是从大量候选中挑出最好看的那个。如果手上有 50 个指标、两两组合算 R²,纯随机数据里也会出现几个 0.4 以上的组合,这是多重比较的必然结果。
实际操作中的对策:把数据分成探索集和验证集,探索集里挑关系,验证集里复核 R²。样本量实在太少的时候(比如季度数据只有 8 期),就别硬做回归,改成描述性对比加业务解释,比硬塞一个 R² 更诚实。
4.5 自相关与伪相关
时间序列数据里,相邻两期的值往往高度相关(今天的数据和昨天差不多),这叫自相关。自相关会让 R² 虚高,而且会让显著性检验的 p 值偏小——表面上 p < 0.001,实际上有效样本量远小于名义样本量。常见表现是:把两个都在缓慢增长的量做相关,R² 常年 0.9 以上,做差分以后掉到 0.1 以下。
另外一类是"共同原因"导致的伪相关:两个指标都受第三个因素驱动,比如都受季节影响。处理方法还是那两条——差分、分层。按季节分层以后再算,R² 通常能回到一个更真实的水平。
4.6 把 R² 当预测精度
这是最容易出现在汇报材料里的错误。R² = 0.85 的含义是"y 的变异中有 85% 能被 x 的线性关系解释",它不是"预测准确率 85%",也不是"误差在 15% 以内"。R² 是相对指标,它跟 y 本身的离散程度有关;同样的 R²,y 波动大的场景下绝对误差也大。
要评估预测精度,应该看回归标准误STEYX,或者直接看残差的分布——比如 90% 的残差落在什么区间内。在做预测区间的时候,还要考虑样本量和外推距离:外推到 x 的取值范围之外,误差会急剧放大,这时候 R² 完全不能作为可靠性依据。
5. 排查速查:报错、异常值与结果解释
5.1 报错类型与定位顺序
RSQ 的报错类型不多,但每种都对应不同的排查路径,按下面这个顺序走基本能定位:
| 报错 | 最常见原因 | 定位动作 |
|---|---|---|
#N/A | 两组数据点数不一致 | 用COUNTA分别数两列,看差多少 |
#DIV/0! | 某一列方差为 0,或有效点少于 2 个 | 检查是否有整列常数、是否几乎全是空值 |
#VALUE! | 参数里混入了无法解析的引用 | 检查参数是不是文本串、区域是不是写错了 |
| 结果明显偏低 | 存在未清理的文本/空值导致配对剔除 | 加计数单元格,比对实际参与行数 |
| 结果明显偏高 | 存在杠杆点或重复值 | 做残差检查、条件格式标记离群点 |
其中#DIV/0!有个隐蔽分支:如果一列里有一堆相同数值(比如某段时间全部是默认值 0),方差接近零,分母趋零,也会报这个错。这种情况不是数据"没有",而是数据"没有变化",需要回到业务侧确认这批记录是否有效。
5.2 结果异常自检清单
养成习惯,每次算出 R² 后过一遍这几条:
- 样本量够不够:少于 8 个点,R² 参考价值有限;少于 3 个点,直接别算。
- 散点图看没看:形状是不是直线、有没有拐点、有没有分组聚集。
- 异常值处理没处理:剔除前后各算一次,差异大不大。
- 参数顺序对不对:RSQ、SLOPE、LINEST 三处的 y/x 是否一致。
- 实际参与行数是多少:和名义行数比一比。
- p 值算没算:样本量小的时候这一步不能省。
- 调整 R² 是多少:尤其是样本量小于 30 的时候。
- 残差有没有结构:曲线、喇叭口、孤立大残差,三种都要看。
这八条做下来大概五分钟,但它能把结论的可靠性提升一个档次。我在给团队做培训时说,这五分钟不是"额外工作",而是"工作本身"——不做这五分钟,前面算的那些数字可能全是白算。
5.3 几条我的实操心得
第一个心得是关于公式布局的。我习惯把 RSQ 的结果放在一个独立的"诊断区",和业务数据表分开,诊断区里从上到下依次是:有效样本量、r、R²、调整 R²、t 值、p 值、斜率、截距、标准误。这九个数放在一起看,任何一项异常都会立刻暴露。只放一个 R² 的表格,等于自废武功。
第二个心得是关于版本兼容的。如果表格要给不熟悉统计的同事用,我会在 R² 单元格旁边写一句固定文案,比如"当前关系解释了约 XX% 的波动,样本 N 个",用TEXT和&拼接自动生成。这样导出成 PDF 或者截图发出去的时候,数字始终带着上下文,不会被人单独摘出来误用。
第三个心得是关于扩展方向的。Excel 这套函数只适合单变量的快速诊断,一旦涉及两个以上自变量、交互项、非线性变换,就该换工具了。LINEST支持多元,但输出数组的解读成本高,而且不提供 p 值矩阵。再往上走,就得用统计软件或者脚本了。这里提醒一句:脚本里的r2_score类函数对任意模型都能算,包括树模型、神经网络,它算的是"模型预测值与真实值的拟合优度",和 Excel 里 RSQ 的含义已经不同了,不能直接横向比较。这个差别,是我见过最容易在迁移工具时踩的坑。
第四个心得是关于表述的。写完一个 R²,逼自己用一句话把它翻译成业务语言,且不能出现"相关""决定系数"这些词。比如"十期投放数据里,到店人次的波动有约 99% 能跟投放强度同步变化解释,但只有十个样本,而且数据是单调递增的,需要排除季节因素后再确认"。这句话虽然长,但它把结论、局限、待验证项都装进去了,比一个光秃秃的 0.99 有用得多。说到底,RSQ 是个起点,不是一个句号。