基于遗传算法的局部函数拟合:平方误差和函数报错排查与解决
解决遗传算法拟合幂律模型时的
sumOfSquaredError函数变量问题 最近我在折腾用遗传算法(借助SciPy的differential_evolution工具)拟合不同实验的幂律模型,卡在sumOfSquaredError(parameterTuple)这个误差计算函数上好一会儿,各种报错找上门,好在最后解决了,跟大家唠唠整个过程:
遇到的坑
第一次尝试:变量未定义报错
我先写了主函数,从pandas DataFrame里提取单实验的xData和yData,然后直接调用differential_evolution来优化sumOfSquaredError函数。结果直接炸了:NameError: xData is not defined,偶尔还伴随RuntimeError。后来才反应过来——differential_evolution调用目标函数时,只会自动传入参数元组parameterTuple,函数内部根本访问不到主函数里定义的xData和yData。第二次尝试:参数传递困境
我想着把xData、yData作为额外参数传给sumOfSquaredError,但又犯了难:parameterTuple是differential_evolution自动生成的,我不知道怎么把自己的数据集参数塞进去,完全卡壳了。
最终解决办法
折腾半天后,我用两个关键操作搞定了问题:
- 声明全局变量
把xData和yData声明为全局变量,这样sumOfSquaredError函数就能直接访问到这两个数据集,不用纠结参数传递的问题。 - 调整数组维度
用reshape把提取的数据调整成合适的维度,避免因维度不匹配引发RuntimeError。
示例代码
import pandas as pd from scipy.optimize import differential_evolution import numpy as np # 全局变量存储实验数据 xData = None yData = None def sumOfSquaredError(parameterTuple): # 引用全局变量 global xData, yData # 幂律模型:y = a * x^b a, b = parameterTuple yPred = a * np.power(xData, b) # 计算平方误差和 return np.sum((yData - yPred) ** 2) def fit_single_experiment_power_law(df): global xData, yData # 从DataFrame提取单实验的x、y数据,同时调整维度 xData = df['x_column'].values.reshape(-1, 1) yData = df['y_column'].values.reshape(-1, 1) # 设置幂律模型参数的边界范围 parameter_bounds = [(0, 20), (-3, 3)] # 示例边界,可根据实际调整 # 调用差分进化算法进行拟合 fitting_result = differential_evolution(sumOfSquaredError, parameter_bounds) return fitting_result.x # 返回拟合得到的参数a和b
要是不想用全局变量,其实也可以用functools.partial把数据绑定到误差函数上,不过我当时赶进度,用全局变量最快解决了问题。
内容的提问来源于stack exchange,提问作者Nankin
相关产品推荐
相关产品推荐

