openlang

Matlab 里加权 rms 算错,只有权重不为 1 时才出问题

Fortran 和电子表格算出来都是 0.0300。Matlab 给出的数更大,而且会随权重变化。全是 1 的时候没问题。cfg.weights 看起来也对。为什么?

% config.m
cfg.weights = [1 1 2 2 4 4];

% run_calibration.m
data = load_readings(cfg.data_file);
pred = model_predict(data.t, cfg);
score = weighted_rms(data.v, pred, cfg.weights);

% weighted_rms.m
function s = weighted_rms(obs, pred, w)
res = (obs - pred) .* w;
wss = sum(res.^2);
% mean() in case we pass several channels later
s = sqrt(mean(wss) / sum(w));
end

obs 和 pred 分别检查过,都和参考值一致。没有报错,也没有警告。在 Fortran 里这就是一个循环。

从英语翻译查看原文

后续讨论 2

顺着彼此的依据读下去
  1. 固定链接

    权重被平方了。看这一行。

    res = (obs - pred) .* w;

    然后你对 res 取平方,分子里就有 w^2,但分母是 sum(w)。全是 1 的时候看不出来,所以你看不到差别。

    加权 rms 的规则是 sqrt(sum(w .* r.^2) / sum(w))。权重只算一次。

    r = obs(:) - pred(:);
    w = w(:);
    s = sqrt(sum(w .* r.^2) / sum(w));

    第二点。你的 cfg.weights 是一行。如果 obs 是一列,.* 不会报错,而是扩展成矩阵 (n x 6)。然后 sum 和 mean 把它掩盖了,全是 1 的时候照样没问题。像上面那样用 (:) 把所有东西都强制成列。查一次 size(res)。

    会不会 mean() 只是为了处理多个通道?那就显式按列算,不要对求和结果取 mean。

    关于扩展的规则看这里 https://www.mathworks.com/help/matlab/matlab_prog/compatible-array-sizes-for-basic-operations.html

    从英语翻译查看原文

同一个问题的其他角度

  1. 把一小段 MATLAB 脚本移植到 R,结果有一个变成了矩阵

    大家好,第一次把东西从 MATLAB 移植过来(我几乎没碰过 MATLAB),所以请手下留情。我在把同事分析里的一小段脚本搬到 R,因为我们其余的流程都是 R。它能从头跑到尾,没有错误,也没有警告,但数字和他保存的日志对不上。 原始 .m 里相关的两…

    回复 2最近活动 rmatlab
  2. 冷柜读数为零却报告状态 "ok",我漏了什么

    我的夜间审计脚本(Rscript,base R)会标出峰值温度超过上限的冰柜。昨晚 U-03 的记录仪被拔掉了,所以导出文件里它的 temp_c 全是字符串 ERR。报告里 U-03 仍然显示 ok。没有人收到告警。打印出来的表里,这台设备的 n_v…

    回复 2最近活动 r
  3. 一个每次分配一列的循环

    Julia 里切片是会复制的,这我知道,结果在循环里又忘了。有个函数遍历矩阵的各列,对各列做 s += sum(A[:, j]),每个 j 一次。每个 A[:, j] 都会新建一个向量,求完和就扔掉。@time 显示分配量随列数增长,而性能提示里说,…

    回复 2最近活动 julia