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

标准化测试数据集时如何不使用scale函数提升计算精度

问题本质

你遇到的量级10^-2的误差并非计算精度导致,而是自定义标准化代码存在广播逻辑错误:R的矩阵向量化运算默认按列优先顺序循环匹配向量元素,直接写a - colMeans(a)并不会实现「每列减去对应列均值」的效果,而是将长度为列数的均值向量,按顺序循环匹配矩阵的所有元素,完全不符合中心化的逻辑要求。

正确的自定义标准化实现

你可以用以下两种写法实现和内置scale函数完全一致的精度,同时可自行存储训练集的均值、标准差参数用于测试集处理:

set.seed(5)
a = matrix(rnorm(30000,  mean=10, sd=5), 10000, 3)  

# 提前计算训练集的均值和标准差,可单独存储用于后续测试集标准化
train_mean = colMeans(a)
train_sd = apply(a, 2, sd)

# 正确写法1:用sweep函数指定按列操作
a_scale_custom1 = sweep(a, 2, train_mean, FUN = "-")
a_scale_custom1 = sweep(a_scale_custom1, 2, train_sd, FUN = "/")

# 正确写法2:转置矩阵后运算再转回,利用转置后维度匹配逻辑
a_scale_custom2 = t((t(a) - train_mean) / train_sd)

# 验证和scale函数结果一致
all.equal(a_scale_custom1, scale(a), check.attributes = FALSE)
# 输出为 TRUE
colMeans(a_scale_custom1)
# 输出和scale结果一致,为1e-16量级的正常浮点误差
训练/测试集标准化复用参数的实践

如果你需要用训练集的统计量标准化测试集,除了上述自定义写法,也可以直接提取scale函数返回结果的属性值复用,逻辑更简洁:

# 训练集标准化
train_scaled = scale(train_data)
# 提取训练集的均值、标准差,单独存储
train_center = attr(train_scaled, "scaled:center")
train_scale_param = attr(train_scaled, "scaled:scale")

# 测试集用训练集参数直接标准化
test_scaled = scale(test_data, center = train_center, scale = train_scale_param)

内容的提问来源于stack exchange,提问作者Álvaro Méndez Civieta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:45:04