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

使用Scipy minimize进行幂律拟合参数优化的报错求助

解决scipy minimize优化幂律拟合参数的报错问题

报错原因分析

  1. TypeError:调用minimize时错误执行了chi_square_ols()(加了括号),且目标函数参数格式不符合minimize要求——它要求目标函数的第一个参数是待优化的参数数组,而非分开的A和p。
  2. NameError:参数传递逻辑错误,未通过args正确传递数据变量,导致函数内部无法识别x、y_av等变量。

核心修改步骤

  • 重构目标函数:将A和p合并为一个参数数组params作为函数第一个参数,固定数据x、y_av、unc通过args传入。
  • 修正minimize调用:直接传递函数名(不要加括号),用args传入非优化的固定变量。
  • 对齐卡方计算逻辑:加入误差加权,和curve_fit的计算规则保持一致,确保优化结果匹配。

修正后的完整代码

import matplotlib.pyplot as plt
import math
import scipy.optimize as scp
from scipy.optimize import curve_fit
import numpy as np

x = []
y1 = []
y2 = []
y3 = []
y4 = []
y5 = []
y6 = []
y7 = []
y8 = []
y9 = []
y10 = []
y_av = []
unc = []
logx = []
logy = []


with open('data1.txt', 'r') as data_file:
    for line in data_file:
        lines = [i for i in line.split()]
        x.append(float(lines[0]))
        y1.append(float(lines[1]))
        y2.append(float(lines[2]))
        y3.append(float(lines[3]))
        y4.append(float(lines[4]))
        y5.append(float(lines[5]))
        y6.append(float(lines[6]))
        y7.append(float(lines[7]))
        y8.append(float(lines[8]))
        y9.append(float(lines[9]))
        y10.append(float(lines[10]))

length = len(x)
dof = length-2

for i in range(length):
    y_av.append((y1[i]+y2[i]+y3[i]+y4[i]+y5[i]+y6[i]+y7[i]+y8[i]+y9[i]+y10[i])/10)
    
plt.title("Test")
plt.xlabel('xdata')
plt.ylabel('ydata')
plt.plot(x, y_av, marker='o', c='g')
plt.show()

for i in range(length):
    squared_diff = sum((y - y_av[i])**2 for y in [y1[i], y2[i], y3[i], y4[i], y5[i], y6[i], y7[i], y8[i], y9[i], y10[i]])
    unc.append(math.sqrt(squared_diff/10))

def power_fit(x, A, p):
    return A * x**p

plt.errorbar(x, y_av, yerr=unc, fmt='ko', label='data')

(params, cov) = scp.curve_fit(power_fit, x, y_av, sigma=unc)

param_err = np.sqrt(np.diagonal(cov))
A1 = params[0]
p1 = params[1]

plt.plot(x, power_fit(x, *params), 'r--')

chi_sq = np.sum(((y_av - A1*x**p1)/unc)**2)
chi_sq_red = chi_sq/dof

# 重构卡方函数:第一个参数是待优化的参数数组,后续为固定数据
def chi_square_ols(params, x, y_av, unc):
    A, p = params  # 从数组中拆分出A和p
    model = A * np.power(x, p)
    # 加入误差加权,和curve_fit逻辑对齐
    return np.sum(np.power((y_av - model)/unc, 2))

x0 = [1.00, 1.00]
# 修正minimize调用:传函数名,args以元组传入固定变量
min_chi = scp.minimize(chi_square_ols, x0=x0, args=(x, y_av, unc))

print("优化结果:")
print(min_chi)
# 提取优化后的参数
opt_A, opt_p = min_chi.x
print(f"优化得到的A: {opt_A}, p: {opt_p}")

关键修改说明

  1. 目标函数重构:将A和p整合为参数数组,避免全局变量依赖,通过args传递固定数据。
  2. minimize调用修正:直接传递函数对象而非执行函数,args用元组形式传入非优化变量。
  3. 加权卡方:加入unc权重,确保优化逻辑和curve_fit一致,结果更具参考性。

内容的提问来源于stack exchange,提问作者eird19

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 02:57:59