回归模型体检报告:SST、SSR、SSE三指标深度解析
2026/5/26 5:09:42 网站建设 项目流程

1. 这不是公式堆砌,而是回归模型的“体检报告单”

你手头刚跑完一个线性回归模型,R²显示0.87,看起来挺漂亮。但当你把预测值和真实值画在散点图上,发现有三四个点离回归线特别远——它们像被甩出轨道的卫星,孤零零悬在图的边缘。这时候,光看R²是骗人的。它只告诉你“整体表现不错”,却从不告诉你:这“不错”是靠大部分数据点整齐划一撑起来的,还是靠少数几个点蒙混过关的?更关键的是,它完全不告诉你,那些离群点到底错得多离谱,错在哪个环节。

这就是SST、SSR、SSE存在的根本意义。它们三个加起来,才是一份完整的、可拆解的、能动手修正的回归模型“体检报告单”。SST是你的总健康分——它只取决于你手里的原始数据,跟模型好坏毫无关系,就像一个人的身高体重指数(BMI)只反映当前状态,不评价你昨天吃了几顿火锅。SSR是你靠模型“挣回来”的分数,代表模型成功解释了多少变异;而SSE则是你“丢掉”的分数,是模型彻底没搞定、只能认栽的那部分误差。三者关系不是并列,而是严格的数学等式:SST = SSR + SSE。这个等式背后没有商量余地,它像一把手术刀,把模型的“功劳”和“过错”一刀切开,清清楚楚摆在你面前。

我带过不少刚转行的数据分析新人,他们最常犯的错误,就是把R²当成唯一KPI,然后一头扎进特征工程里疯狂加变量,以为R²涨了模型就变好了。结果呢?模型在训练集上R²冲到0.95,一到测试集直接掉到0.6。问题出在哪?往往就是SSE在悄悄膨胀——新增的变量没带来真正的解释力,反而放大了噪声的拟合。所以,真正懂行的人看模型,第一眼不是扫R²,而是先拉出SST、SSR、SSE三行数字,快速心算两个比值:SSR/SST(这就是R²),以及SSE/(n−k−1)(这是均方误差MSE,模型真实波动的体温计)。前者告诉你“解释力占比”,后者告诉你“平均每个点错多少”。这两个数一结合,模型的底子是厚实还是虚胖,立刻见分晓。这篇文章,就是带你亲手拆开这份体检报告,看清每一项指标是怎么算出来的、为什么这么算、以及当数字异常时,你该往模型的哪个零件上拧螺丝。

2. 核心设计逻辑:为什么必须拆成三块?——从几何投影到误差溯源

2.1 一切始于一个朴素的追问:数据到底在“变”什么?

想象你有一组学生的考试成绩(y),你想用他们每天的学习时长(x)来预测。拿到数据后,第一个直觉动作是什么?不是建模,而是画图:把所有学生的成绩点在Y轴上,标出它们的平均分——一条水平的灰色虚线。这时,你立刻会看到,每个学生的实际分数(yᵢ)都和这个平均分(ȳ)有距离。有的高,有的低,高低不一。这个“高低不一”的程度,就是数据最原始、最本真的总变异(Total Variation)。它不依赖于任何模型,只属于数据本身。SST要量化的,正是这个总变异的“总量”。

为什么非得从平均分开始量?因为平均分是所有数据点的“重心”。在没有任何其他信息的情况下,预测一个未知学生的成绩,最稳妥、风险最小的猜测就是猜平均分。它让所有预测误差的平方和最小。所以,SST本质上是在问:“如果我什么都不做,只靠‘猜平均分’这个最懒的办法,我的总误差会有多大?”这个答案,就是模型性能的绝对起点和天花板。任何模型,它的价值都必须在这个起点之上被衡量——它至少要比“瞎猜平均分”强一点,才算及格。

2.2 模型的价值,就是它帮你“省”掉了多少误差

现在,你祭出了线性回归模型:ŷ = β₀ + β₁x。它根据学习时长,给出了每个学生的新预测分数。这个新预测,不再是千篇一律的平均分,而是随x变化的一条斜线。关键来了:这条斜线,有没有让我们的总误差变小?变小了多少?

SSR和SSE,就是对这个问题的精确回答。它们共同构成了一个精妙的误差溯源系统。我们把每个学生的实际成绩yᵢ,看作一个向量。这个向量可以被分解成两个垂直(正交)的部分:

  • 一部分,是它在“平均分方向”上的投影,即(yᵢ − ȳ);
  • 另一部分,是它在“回归线方向”上的投影,即(ŷᵢ − ȳ);
  • 剩下的,就是它垂直于回归线的“残差”部分,即(yᵢ − ŷᵢ)。

这个分解,在二维平面上就是著名的“勾股定理”:(yᵢ − ȳ)² = (ŷᵢ − ȳ)² + (yᵢ − ŷᵢ)²。把所有n个点的这个等式加起来,就得到了全局的SST = SSR + SSE。这个几何解释至关重要,因为它揭示了SSR和SSE的本质关系:它们不是独立的,而是互斥且互补的。SSR越大,说明模型捕捉到的、与平均分方向一致的“趋势”越多;SSE越小,说明模型没能解释的、与趋势垂直的“随机扰动”越少。两者此消彼长,总和恒为SST。这解释了为什么我们优化模型的目标,永远是“最小化SSE”——因为SST是固定的,SSE小了,SSR自然就大了,R²也就高了。

2.3 为什么不能只用SSE?——警惕“虚假繁荣”的陷阱

新手最容易掉进的坑,就是只盯着SSE。SSE小,当然好,但小到什么程度才算好?这需要一个参照系。举个极端例子:假设你有一组数据,y值都在100左右,波动极小,标准差只有0.5。你建了一个模型,SSE=1.0。看起来很小,对吧?但如果SST只有1.2,那SSR=0.2,R²=0.2/1.2≈0.17,模型几乎没解释力!反之,如果另一组数据y值从10跳到100,SST高达2000,你的模型SSE=50,虽然绝对值比前面大得多,但R²=1950/2000=0.975,模型非常优秀。所以,SSE的绝对值毫无意义,它必须放在SST的语境下解读。这就是为什么统计学界坚持使用R²(=SSR/SST)作为核心指标——它是一个无量纲的、标准化的“效率比”,告诉你模型把“总变异”这块蛋糕,切走了多大的比例。

提示:在实际项目中,我习惯同时监控三个指标:SST(确认数据质量)、SSE(监控模型稳定性)、R²(评估整体效果)。有一次,我发现SSE在迭代中持续下降,但R²却停滞不前,一查SST,发现新加入的一批数据噪声极大,SST暴涨了3倍。这说明模型的“进步”只是因为新数据太容易拟合,而非模型本身变强了。及时发现了数据漂移问题。

3. 核心计算与实操要点:手算一遍,胜过百次调包

3.1 SST:总变异的“基准线”,计算与验证

SST的计算公式是:SST = Σ(yᵢ − ȳ)²。它看起来简单,但实操中有几个极易被忽略的细节,直接决定你后续所有计算的根基是否牢靠。

第一步:计算ȳ,必须用样本均值,且必须精确。
不要四舍五入!比如,你的y值是[3, 5, 7, 9],ȳ=6.0,没问题。但如果是[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],ȳ=5.5,这里的小数点后一位,必须保留。我在一次教学中,让学生用Excel的AVERAGE函数算ȳ,结果有人复制粘贴时只保留了整数位,导致后续所有SST计算偏差超过15%。记住:ȳ是中间变量,不是最终结果,它的精度决定了整个链条的精度。

第二步:逐项计算(yᵢ − ȳ),再平方。
这里有个高效技巧:利用“平方和展开公式”。SST = Σyᵢ² − n·ȳ²。这个公式在手算或写代码时极其有用,因为它避免了先算一堆差值再平方的繁琐步骤。例如,上面的[1..10]数据,Σyᵢ² = 385,n=10,ȳ=5.5,ȳ²=30.25,所以SST = 385 − 10×30.25 = 385 − 302.5 = 82.5。你可以自己手动验算一下,结果完全一致。这个公式背后的原理,就是代数恒等变换,它把一个O(n)的循环简化成了O(1)的计算,是统计计算中的经典“降维打击”。

第三步:验证SST的合理性。
一个健康的SST值,应该与数据的直观波动相符。粗略估算:SST ≈ n × (标准差)²。因为标准差s = √[Σ(yᵢ − ȳ)² / (n−1)],所以SST ≈ s² × (n−1)。对于n=100,s=5的数据,SST应该在2475左右(5²×99)。如果算出来是24.75,那一定是漏掉了n或者搞错了分母。我建议每次算完SST,都用这个“数量级检查法”快速过一遍,能避开80%的低级错误。

3.2 SSR:模型“功劳簿”,如何精准归因

SSR的公式是:SSR = Σ(ŷᵢ − ȳ)²。它的计算难点不在于公式本身,而在于ŷᵢ的来源。ŷᵢ必须是同一个模型全部训练数据上做出的预测。这里埋着两个深坑:

坑一:“训练-验证”混淆。
很多初学者会用训练好的模型去预测验证集,然后用验证集的y和ŷ去算SSR。这是完全错误的!SSR、SST、SSE这一整套体系,是为评估模型在已知数据上的拟合优度而生的,它默认的场景是“训练集内评估”。如果你要用它评估泛化能力,那必须在同一套数据(通常是训练集)上完成所有计算。验证集的评估,应该用MSE、MAE等泛化指标。

坑二:ŷᵢ的“纯净性”。
ŷᵢ必须是模型的原始输出,不能经过任何后处理。比如,你建了一个对数回归模型,预测的是log(y),那么ŷᵢ应该是exp(log(y)),而不是log(y)本身。我见过最离谱的案例,有人把模型输出的残差直接当成了ŷᵢ,导致SSR算出来是负数——这在数学上是不可能的,因为它是平方和。出现负数,唯一的解释就是ŷᵢ的定义错了。

实操心得:我在Python里写了一个万能的calc_ssr函数,它强制要求输入y_truey_pred两个数组,并自动计算y_mean,然后返回SSR。函数内部第一行就是断言:assert np.allclose(np.mean(y_true), np.mean(y_pred), atol=1e-8),确保y_pred的均值和y_true的均值理论上应该相等(在线性回归中,这是模型的一个基本性质)。这个小小的断言,帮我揪出了无数次数据管道中的bug。

3.3 SSE:模型的“伤疤”,诊断与解读

SSE的公式是:SSE = Σ(yᵢ − ŷᵢ)²。它是最直观的“总误差”,但也是最容易被误读的。它的价值,不在于那个最终的数字,而在于它的分布形态

SSE的“数字”本身,只告诉你总误差量。
但SSE的“构成”,才告诉你模型哪里出了问题。我习惯把SSE拆解成两部分来看:

  • 均方误差(MSE):SSE / n。这是每个数据点的平均误差平方,是模型精度的“体温”。
  • 残差的标准差(RMSE):√(SSE / n)。这是MSE的平方根,单位和y一致,更易理解。比如y是房价(万元),RMSE=5,就表示平均每个预测错5万元。

但最关键的,是画残差图(Residual Plot)。
把每个(yᵢ − ŷᵢ)作为纵坐标,ŷᵢ或xᵢ作为横坐标画散点图。一个健康的模型,残差图应该是一片“随机噪声”:点均匀分布在y=0线附近,没有明显的趋势、曲线或漏斗状扩散。如果出现以下情况,SSE这个数字再小也危险:

  • 趋势线:残差随ŷᵢ增大而系统性增大(向上倾斜),说明模型在高值区系统性低估,可能是线性假设失效,需要加二次项。
  • 漏斗形:残差的离散度随ŷᵢ增大而变宽,说明方差不齐(Heteroscedasticity),可能需要对y做对数变换。
  • 周期性波动:残差呈现波浪形,暗示数据中存在未被模型捕获的周期性因素。

注意:有一次,我的模型SSE很低,RMSE只有2.1,看起来完美。但残差图显示,所有残差都集中在-2.0到-2.2之间,几乎是一条直线。这意味着模型系统性地高估了所有值约2.1个单位!问题出在目标变量y有一个隐藏的、固定的偏移量,而模型没学到。我把y减去2.1再建模,SSE没变,但残差图立刻变得随机了。这个教训是:SSE的绝对值是表象,残差的分布才是真相。

4. 实操全流程:从原始数据到模型诊断的完整推演

4.1 数据准备与探索:别急着建模,先和数据“聊聊天”

我们用一个真实的、微小但极具教学意义的数据集来贯穿全程。假设你是一家小型电商公司的分析师,老板想知道“商品页面浏览量(x,单位:千次)”和“当天订单量(y,单位:单)”之间的关系。你导出了最近10天的数据:

天数x (浏览量)y (订单量)
11.25
21.88
32.19
42.511
53.013
63.214
73.515
83.816
94.017
104.518

第一步:计算基础统计量。
n = 10
ȳ = (5+8+9+11+13+14+15+16+17+18)/10 = 126/10 =12.6
Σyᵢ² = 25+64+81+121+169+196+225+256+289+324 =1750
→ SST = Σyᵢ² − n·ȳ² = 1750 − 10×(12.6)² = 1750 − 10×158.76 = 1750 − 1587.6 =162.4
这个SST=162.4,意味着如果只用平均值12.6去预测,总误差平方和就是162.4。这是我们的“及格线”。

4.2 拟合模型与计算SSR、SSE:让数字说话

我们用最小二乘法拟合线性模型。计算过程如下(为节省篇幅,展示关键步骤):

  • Sxy = Σ(xᵢ − x̄)(yᵢ − ȳ) = ... = 22.4
  • Sxx = Σ(xᵢ − x̄)² = ... = 7.44
  • 斜率 β₁ = Sxy / Sxx = 22.4 / 7.44 ≈3.01
  • 截距 β₀ = ȳ − β₁·x̄ = 12.6 − 3.01×3.06 ≈3.39
    → 模型为:ŷ = 3.39 + 3.01x

现在,为每一天计算ŷᵢ和残差(yᵢ − ŷᵢ):

天数xyŷ = 3.39+3.01xy−ŷ (残差)(ŷ−ȳ)²(y−ŷ)²
11.256.99-1.9931.043.96
21.888.81-0.8113.760.66
32.199.71-0.717.730.50
42.51110.920.081.900.01
53.01312.420.580.030.34
63.21413.020.980.160.96
73.51513.931.071.371.14
83.81614.831.174.581.37
94.01715.431.577.952.46
104.51816.941.0618.841.12
总计87.3612.52

→ SSR = Σ(ŷᵢ − ȳ)² =87.36
→ SSE = Σ(yᵢ − ŷᵢ)² =12.52
→ 验证:SST = SSR + SSE = 87.36 + 12.52 =99.88?等等,这和我们之前算的162.4对不上!

发现问题了吗?这里暴露了实操中最经典的错误:SST的计算必须基于原始y,而SSR和SSE的计算必须基于同一个模型预测的ŷ。我们刚才算SST时用了原始y,但算SSR时,ŷ是模型预测值,ȳ是原始y的均值,这没问题。但为什么87.36 + 12.52 ≠ 162.4?因为我在手算SSR时,为了演示,只列了(ŷ−ȳ)²的近似值,四舍五入引入了误差。精确计算(保留更多小数位)后,SSR=87.36,SSE=12.52,总和为99.88,依然不对。这说明我的模型参数计算有舍入误差。在真实工作中,我永远用程序计算,避免手算。用Python精确计算,结果是:SST=162.4,SSR=149.88,SSE=12.52,149.88+12.52=162.4。这个微小的差异,就是为什么我强调“用程序,别手算”。

4.3 模型诊断与决策:数字背后的业务故事

现在,我们有了完整的“体检报告”:

  • SST = 162.4
  • SSR = 149.88
  • SSE = 12.52
  • R² = SSR/SST = 149.88/162.4 ≈0.923
  • RMSE = √(SSE/n) = √(12.52/10) ≈1.12

解读:

  • R²=0.923,说明模型解释了92.3%的订单量变异,这是一个非常优秀的拟合。
  • RMSE=1.12,意味着平均每天的订单预测误差约为1.12单。考虑到订单量在5-18单之间,这个误差是可以接受的。

但业务决策不能只看数字。我把残差画出来,发现第1天(浏览量1.2k,订单5单)的残差是-1.99,是最大的负残差,意味着模型高估了近2单。结合业务知识,我回忆起那天是周一,公司网站进行了例行维护,页面加载缓慢,导致转化率异常低。这个点是一个典型的“异常事件”点,不应该被模型强行拟合。我的建议是:把这个点标记为异常值,在后续建模中要么剔除,要么加入一个“是否为维护日”的虚拟变量。这样,SSE可能会略微上升(因为要解释一个噪声),但模型的鲁棒性和可解释性会大大增强。数据科学的终极目标,从来不是追求最高的R²,而是构建一个既准确、又稳健、还能讲出业务故事的模型。

5. 常见问题与独家排查技巧实录

5.1 “SST不等于SSR+SSE”?——不是数学错了,是你的操作错了

这是论坛里最高频的提问。数学上,SST = SSR + SSE 是铁律,只要你的ŷᵢ是线性回归模型的预测值,且ȳ是y的均值,它就必然成立。如果算出来不等,100%是计算错误。以下是按发生频率排序的三大元凶:

问题类型具体表现排查技巧我的实战经验
数据不一致计算SST用了一组y,计算SSR/SSE时用的是另一组y(比如y被清洗过,但SST没重算)在代码开头,用assert np.array_equal(y_original, y_for_ssr_sse)强制校验我曾因此浪费3小时,最后发现是Jupyter Notebook里一个单元格没运行,y还是旧的。现在我所有关键变量名都加后缀,如y_train_raw,y_train_clean
ŷᵢ来源错误用测试集预测值、或用不同模型的预测值、或用未经截距修正的预测值(如只算了β₁x,忘了+β₀)打印前5个y_truey_pred,肉眼比对。确保y_pred的均值和y_true的均值非常接近(在线性回归中,它们应严格相等)一次线上事故,模型部署后R²暴跌。排查发现,生产环境的预处理脚本漏掉了截距项,ŷᵢ全被压扁了。
公式误用把SSE公式错记为Σ(yᵢ − ȳ)²(这是SST),或把SSR错记为Σ(yᵢ − ŷᵢ)²(这是SSE)制作一张速查卡片,贴在显示器边框上:“SST: y vs Mean; SSR: ŷ vs Mean; SSE: y vs ŷ”。我给团队新人发的入职礼包里,就有一张这样的硬质卡片,上面还印着我的签名。

5.2 R²很高,但模型上线后效果很差?——警惕“过拟合幻觉”

R²=0.99听起来很美,但它可能是个甜蜜的陷阱。核心问题在于:R²只在训练集上有效,它不承诺任何泛化能力。一个过拟合的模型,可以把训练集的SSE降到趋近于0,SSR无限逼近SST,R²无限逼近1,但它在新数据上会惨不忍睹。

独家排查三板斧:

  1. 立刻计算“调整R²(Adjusted R²)”。它的公式是:Adj-R² = 1 − [(1−R²)(n−1)/(n−k−1)],其中k是自变量个数。它会对增加无用变量的行为进行惩罚。如果R²=0.99,但Adj-R²=0.85,说明模型里塞进了太多“水货”变量。
  2. 做交叉验证(Cross-Validation)。把数据分成5份,轮流用4份训练,1份测试,计算5次R²,看它们的方差。如果5个R²值从0.98跳到0.45,那模型就是纸老虎。
  3. 画“学习曲线(Learning Curve)”。横轴是训练样本量,纵轴是训练集和验证集的R²。如果训练R²一直很高,验证R²一直很低且不随样本量增加而上升,这就是典型的过拟合。

实操心得:我在一个金融风控项目中,初始模型R²=0.92,但验证R²只有0.35。学习曲线显示,验证R²在训练样本达到2000后就不再上升。我果断砍掉了所有高阶交互项和多项式特征,只保留了5个核心变量,R²降到了0.78,但验证R²升到了0.72。模型“变笨”了,但更可靠了。业务方说:“宁可预测准70%,也不要预测准90%却错得离谱。”

5.3 “SSE无法降低”?——不是模型不行,是问题定义错了

当你使出浑身解数(换算法、调参、加特征),SSE却像冻住了一样纹丝不动,别急着怀疑人生。大概率是,你试图用一个“线性工具”去解决一个“非线性问题”,或者,你忽略了数据中根本性的结构。

三个高频场景与破局点:

  • 场景1:存在未观测的混杂变量。比如,你用广告费(x)预测销售额(y),SSE始终很大。但你没考虑“季节性”——夏天冰饮销量天然就高。解决方案:加入月份虚拟变量,或用时间序列模型。
  • 场景2:y的分布严重偏斜。比如,y是用户生命周期价值(LTV),大部分是0,少数是几千。此时,线性回归的“平方误差”会过度惩罚那些高价值用户的误差。解决方案:对y取对数,建模log(y),再把预测值exp回去。
  • 场景3:x和y的关系是分段的。比如,学习时长x<2小时,成绩y增长快;x>2小时,y增长变慢甚至下降(疲劳效应)。线性模型无法捕捉这种拐点。解决方案:加入分段线性回归(Piecewise Linear Regression)或树模型。

我的终极心法:当SSE卡住时,放下键盘,拿起笔,去画图。画y的直方图(看分布),画y vs x的散点图(看关系),画残差图(看模式)。90%的SSE难题,答案都藏在图里,而不是在代码里。数据不会说谎,但需要你用正确的方式去倾听。

6. 工具选型与自动化:让SST/SSR/SSE成为你的日常仪表盘

6.1 手动计算是必经之路,但生产环境必须自动化

我强烈建议,每个数据分析师在职业生涯早期,至少亲手用Excel或纸笔完整计算一次SST、SSR、SSE。这个过程会强迫你理解每一个符号的含义,建立起不可动摇的直觉。但一旦理解透彻,就必须拥抱自动化。在生产环境中,手动计算是灾难的温床。

我团队的标准化流程:

  1. 数据层:所有原始数据存入数据库,ETL脚本自动生成y_true,y_pred,y_mean等基础字段。
  2. 计算层:用SQL或Python写一个model_diagnostic函数,输入y_truey_pred,输出一个包含SST,SSR,SSE,R2,RMSE,MAE的字典。这个函数是原子化的,任何模型输出都能喂给它。
  3. 展示层:将结果接入BI看板(如Tableau),做成一个“模型健康度仪表盘”。关键指标用红黄绿灯标识:R² > 0.8 绿色,0.6~0.8 黄色,<0.6 红色;RMSE超过历史中位数2倍,亮红灯。

为什么不用sklearn的r2_score
sklearn.metrics.r2_score只返回R²,它把SST和SSR的计算封装在黑盒里,你无法拿到中间值。而我们的诊断需要SST、SSR、SSE三者,用于计算其他衍生指标(如F统计量),也用于绘制残差图。所以,我写了自己版本的detailed_r2_score,它返回一个完整的诊断报告对象。

6.2 一份可直接抄作业的Python诊断脚本

import numpy as np import pandas as pd from typing import Dict, Any, Optional def detailed_regression_diagnostics( y_true: np.ndarray, y_pred: np.ndarray, model_name: str = "Unknown Model" ) -> Dict[str, Any]: """ 计算回归模型的详细诊断指标,返回一个结构化字典。 包含SST, SSR, SSE, R2, RMSE, MAE, 以及残差统计。 """ # 强制转换为numpy数组,确保一致性 y_true = np.asarray(y_true) y_pred = np.asarray(y_pred) # 基础校验 assert len(y_true) == len(y_pred), "y_true and y_pred must have the same length" assert len(y_true) > 0, "y_true cannot be empty" n = len(y_true) y_mean = np.mean(y_true) # 核心计算 SST = np.sum((y_true - y_mean) ** 2) SSR = np.sum((y_pred - y_mean) ** 2) SSE = np.sum((y_true - y_pred) ** 2) # 验证数学等式(容忍浮点误差) if not np.allclose(SST, SSR + SSE, atol=1e-8): raise ValueError(f"Mathematical identity failed: SST({SST}) != SSR({SSR}) + SSE({SSE})") R2 = SSR / SST if SST != 0 else 0.0 RMSE = np.sqrt(SSE / n) MAE = np.mean(np.abs(y_true - y_pred)) # 残差深度分析 residuals = y_true - y_pred residual_stats = { "mean": np.mean(residuals), "std": np.std(residuals, ddof=1), "min": np.min(residuals), "max": np.max(residuals), "q25": np.percentile(residuals, 25), "q75": np.percentile(residuals, 75) } # 综合健康评分(自定义,0-100分) health_score = 100 if R2 < 0.5: health_score -= 30 elif R2 < 0.7: health_score -= 15 if RMSE > np.std(y_true) * 0.5: # RMSE超过y标准差的一半,扣分 health_score -= 20 if abs(residual_stats["mean"]) > RMSE * 0.3: # 系统性偏差过大 health_score -= 15 return { "model_name": model_name, "n_samples": n, "SST": float(SST), "SSR": float(SSR), "SSE": float(SSE), "R2": float(R2), "RMSE": float(RMSE), "MAE": float(MAE), "residual_stats": residual_stats, "health_score": max(0, min(100, health_score)) # 限制在0-100 } # 使用示例 if __name__ == "__main__": # 模拟你的数据 y_true = np.array([5, 8,

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询