MATLAB中BADS优化时不同模型FVAL分数一致问题求助
问题诊断与修正方案
核心问题
你遇到的所有模型FVAL一致的现象,根源是模型函数的实现未做向量化处理,导致所有数据点的预测值被错误地广播为同一个值,最终目标函数输出不随参数变化(或恰好与null模型输出一致)。
具体错误分析
你的模型函数(如multiplicative)是按单个数据点设计的,但在目标函数中直接传入了234×2的参数索引矩阵。MATLAB的线性索引规则会导致x(1)取矩阵的第一个元素(而非第一列),x(2)取第二个元素(而非第二列),最终模型返回单个标量,被广播为234×1的向量。如果这个标量恰好等于mean(results),所有模型的目标函数值就会和null模型完全一致。
分步修正
1. 修正模型函数为向量化版本
将模型修改为支持批量处理所有数据点,返回与results同维度的预测值向量:
% Null模型(无需修改,标量会自动广播) null = @(params, x) mean(results); % 乘法模型:按列索引取参数,元素-wise相乘 multiplicative = @(params, x) params(x(:,1)) .* params(x(:,2)); % 最小值模型:按列索引取参数,逐元素取最小值 minimalism = @(params, x) min(params(x(:,1)), params(x(:,2)));
2. 移除手动惩罚项,使用BADS原生约束支持
原代码通过手动添加惩罚项实现约束,容易引入数值误差。BADS本身支持不等式约束,直接传递约束函数即可:
% 约束函数保持不变 constraint = @(params) [params(1)-params(2), params(2)-params(3), params(3)-params(4), ... params(5)-params(6), params(6)-params(7), params(7)-params(8)]; % 带约束模型的优化调用(无需构造penalized_objective) [mulConst_fit, mulConst_fval] = bads(objective_mul, x0, lb, ub, 'Constraints', constraint); [minConst_fit, minConst_fval] = bads(objective_min, x0, lb, ub, 'Constraints', constraint);
3. 优化null模型的计算效率
null模型不依赖任何参数,无需调用优化器,直接计算目标函数值即可:
null_fval = objective_null([]); % 任意传入params,模型会忽略它 null_fit = NaN(1,8); % null模型无自由参数,标记为NaN
4. 验证修正效果
在优化前手动验证模型预测值是否正确:
test_params = x0; pred_null = null(test_params, [tParamVal, sParamVal]); pred_mul = multiplicative(test_params, [tParamVal, sParamVal]); pred_min = minimalism(test_params, [tParamVal, sParamVal]); % 查看三个预测向量是否存在差异 disp('Null模型预测值均值:'); disp(mean(pred_null)); disp('乘法模型预测值均值:'); disp(mean(pred_mul)); disp('最小值模型预测值均值:'); disp(mean(pred_min));
若输出存在差异,说明模型函数修正正确,后续优化的FVAL会随模型不同而变化。
额外建议
- 替换
1e-10为MATLAB原生的eps,更适配数值计算场景,避免手动设置的精度误差。 - 计算AIC/BIC时注意自由参数数量:
- null模型:k=0(无自由参数)
- 无约束模型:k=8
- 带约束模型:k=8(不等式约束不减少自由参数数量,仅限制参数取值范围)
内容的提问来源于stack exchange,提问作者Model Builder
相关产品推荐
相关产品推荐

