使用scipy.optimize.minimize优化参数未收敛问题求助
问题分析与解决
你的代码核心问题是目标函数完全没有使用优化器传入的参数进行计算,所有误差相关的计算都在函数外使用初始参数完成,导致优化器认为目标函数值不会随参数变化,直接返回初始值。
具体问题点
- 所有依赖优化参数(LOGGMIN、C1E_O等)的计算(如
K、Predicted logG*、Predicted Error)都在objective函数外执行,且仅使用初始参数值,后续优化过程中完全没有更新这些值。 objective函数只是简单返回预先计算好的df['Predicted Error'].sum(),和传入的SE参数毫无关联,优化器无法找到参数调整的方向。Predicted logG*的表达式末尾缺少一个右括号,会导致语法错误。- 使用相对误差平方
((Test-Pred)/Test)**2,若Test LogG接近0会引发数值爆炸,导致误差和异常大。
修正后的代码
import numpy as np import pandas as pd import scipy.optimize as spo # 初始参数猜测 x0 = [120, 104, 0, 50, -504, 2012] ReferenceTemperatureE_O = 21 # 导入数据(只做一次,无需重复导入) df = pd.read_excel(r'C:\Users\Mahmoud Khadijeh\Desktop\MasterCurve.xlsx', header=None) # 预处理固定不变的列 df['log f'] = np.log10(df[1]) df['Test LogG'] = np.log10(df[2]) # 定义目标函数:计算平方误差和(这里改为绝对平方误差,避免分母为0的问题) def objective(params): LOGGMIN, LOGGMAX, BETA, GAMMA, C1E_O, C2E_O = params # 根据当前参数计算WLF移位因子 temp_diff = df[0] - ReferenceTemperatureE_O K = (-C1E_O * temp_diff) / (C2E_O + temp_diff) reduced_freq = df['log f'] + K # 计算预测的logG* predicted_logG = LOGGMIN + (LOGGMAX - LOGGMIN) / (1 + np.exp(BETA + GAMMA * reduced_freq)) # 计算平方误差和(改用绝对误差平方,若需相对误差可根据数据调整) error_sq = (df['Test LogG'] - predicted_logG) ** 2 sum_error = error_sq.sum() return sum_error # 执行优化 sol = spo.minimize(objective, x0, method='SLSQP', options={'disp': True}) # 输出结果 print("优化后的参数:", sol.x) print("最小平方误差和:", sol.fun)
额外优化建议
- 参数边界:可以给参数设置合理的边界,比如
LOGGMIN和LOGGMAX应该符合物理意义(通常模量的对数有合理范围),避免优化器跑出无意义的值。使用bounds参数:bounds = [(80, 150), (80, 150), (-10, 10), (10, 100), (-1000, 0), (1000, 3000)] sol = spo.minimize(objective, x0, method='SLSQP', bounds=bounds, options={'disp': True}) - 优化方法选择:如果问题是非线性的,也可以尝试
L-BFGS-B方法,它在处理无约束/有约束优化时表现稳定。 - 初始值合理性:确保初始参数在合理范围内,若初始值离最优值太远,可能导致优化陷入局部最优。
内容的提问来源于stack exchange,提问作者Mhmoud Khadija
相关产品推荐
相关产品推荐

