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

如何优化Python中Cross模型对我的数据的曲线拟合效果?

优化Cross模型曲线拟合效果的问题

我尝试用Cross模型拟合流变数据,但拟合效果很差。当前数据为剪切速率(x轴)和黏度(y轴),拟合曲线与实验数据偏差明显,实验数据(蓝色散点)和拟合曲线(红色线条)的对比显示模型无法贴合数据趋势。

当前代码

# Data used in model - from dataframe

x1M_5 = df_PEO_EXPT_080223["1M_5_wt%_Shear Rate"]
y1M_5 = df_PEO_EXPT_080223["1M_5_wt%_Viscosity"]

x1M_5 
y1M_5

#CurveFit Cross Model
from scipy.optimize import curve_fit

def Cross(x, Y0, Yinfinity, A, P):
    y = Yinfinity + ((Y0 - Yinfinity)/(1 - (A*x)**P))
    return(y)

guess = [2.14191448e+04, 5.22945442e+03, 2.24737143e-01, 4.63747120e+02]

popt, pcov = curve_fit(Cross, x1M_5, y1M_5, p0= guess,  maxfev = 100000)
popt
pcov

y_model = Cross(x1M_5, *popt) 

ax = fig.add_subplot(111)

plt.scatter(x1M_5, y1M_5)
plt.plot(x1M_5, y_model, color='r')
plt.xscale('log')
plt.yscale('log')

plt.show()
print(popt)

问题分析与解决方案

  • 修正模型公式:标准Cross模型的分母应为1 + (A*x)**P,你当前代码中用了减号,这会导致当A*x >=1时分母出现负数或零,引发数值异常,这是拟合失效的核心原因。
  • 重置初始猜测值:初始参数必须符合流变学物理意义:
    • Y0(零剪切黏度)取数据中黏度的最大值
    • Yinfinity(无穷剪切黏度)取数据中黏度的最小值
    • A 可按黏度开始下降的剪切速率的倒数估算
    • P(流动指数)通常在0~1之间,你之前的463完全超出合理范围,会误导拟合算法
  • 添加参数约束:用bounds限制参数范围,避免出现无物理意义的数值,示例:
    bounds=([0, 0, 0, 0], [1e5, 1e4, 1, 1])
    
  • 数据校验:确保数据中无零值、负值等异常点,必要时先做筛选。

修改后的代码

# 从数据框提取实验数据
x1M_5 = df_PEO_EXPT_080223["1M_5_wt%_Shear Rate"]
y1M_5 = df_PEO_EXPT_080223["1M_5_wt%_Viscosity"]

# 导入所需库
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

# 修正后的标准Cross模型
def Cross(x, Y0, Yinfinity, A, P):
    return Yinfinity + (Y0 - Yinfinity) / (1 + (A * x) ** P)

# 基于物理意义生成初始猜测值
eta0_guess = y1M_5.max()
etainf_guess = y1M_5.min()
# 找到黏度开始下降的剪切速率,取倒数作为A的初始值
shear_rate_drop = x1M_5[y1M_5 < 0.9 * eta0_guess].min()
A_guess = 1 / shear_rate_drop if shear_rate_drop > 0 else 0.1
P_guess = 0.5  # 流动指数初始值取0~1范围内的典型值

guess = [eta0_guess, etainf_guess, A_guess, P_guess]

# 添加参数约束,确保符合物理范围
popt, pcov = curve_fit(Cross, x1M_5, y1M_5, p0=guess, maxfev=100000,
                       bounds=([0, 0, 0, 0], [1e5, 1e4, 1, 1]))

# 生成拟合曲线数据
y_model = Cross(x1M_5, *popt) 

# 绘图对比
fig, ax = plt.subplots()
ax.scatter(x1M_5, y1M_5, label='实验数据')
ax.plot(x1M_5, y_model, color='r', label='拟合曲线')
ax.set_xscale('log')
ax.set_yscale('log')
ax.set_xlabel('剪切速率')
ax.set_ylabel('黏度')
ax.legend()
plt.show()

print("拟合得到的参数:", popt)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:50:30