R语言NLS模型数据拟合验证问题求助(支持Python方案)
问题描述
需验证给定NLS模型能否拟合样本数据,使用R语言nls函数时反复报错:step factor 0.000488281 reduced below 'minFactor' of 0.000976562,调整初始值、迭代次数均无效。Excel求解器可得到初步拟合结果但无法满足需求,需解决报错并获得更优拟合,接受R或Python代码方案。
模型与初始值
原模型公式:
$$y = a2 + (a1 - a2) \times \frac{(\frac{Lc}{K})^n \times H}{(1 + \frac{Lc}{K})^n \times H}$$
注:公式中分子分母的H可完全约去,简化后为:
$$y = a2 + (a1 - a2) \times \frac{(\frac{Lc}{K})^n}{(1 + \frac{Lc}{K})^n}$$
初始值:
- $a1 = 0.01$(固定值)
- $n_{init} = 0.6$
- $K_{init} = 0.4$
- $a2_{init} = 0.75$
样本数据
Lc <- c(0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.01,0.05,0.08,0.1,0.049554,0.099109,0.1486635,0.1783962,0.198218,0.24479923,0.29534482,0.3468815,0.396436,0.43409742,0.495545,0.5450995,0.594654,0.6442085,0.693763,0.7433175,0.792871,0.941534313,0.99108875,1.486634,1.982178667,2.477723333,2.477723333,2.973267327,4.45990099,5.946534653,7.928712871,9.415346535,12.88415842,16.3529703,19.32623762,19.32623762,22.7950495,22.7950495,27.33423762,27.33423762,27.33423762,27.33423762,29.23712871,29.23712871,32.70594059,35.67920792,35.67920792,37.66138614,37.66138614,39.1480198,39.1480198,39.1480198,59.46534653,59.46534653,79.26750804,79.26750804) y <- c(0.7336301,0.7300885,0.7302002,0.7265662,0.7217741,0.7223443,0.7238027,0.71864,0.7094976,0.6989751,0.6764343,0.6598028,0.410136,0.3917024,0.3777954,0.3685038,0.3590556,0.3537131,0.3488757,0.343905,0.3402811,0.3378536,0.3371936,0.3337051,0.3308202,0.3284294,0.328673,0.3269062,0.3233758,0.3233758,0.3210403,0.3189582,0.3163805,0.3135109,0.3126578,0.3114899,0.3090119,0.3056575,0.3040519,0.301711,0.3005168,0.2975471,0.2903744,0.2960987,0.2874757,0.2914471,0.2900818,0.2900818,0.2841886,0.2841886,0.2807069,0.2861011,0.2829085,0.2770104,0.2824439,0.2748469,0.2797121,0.2669634,0.2723519,0.2768586,0.2676962,0.2730733,0.2656272,0.2706228)
解决方案
核心思路
- 移除冗余参数
H,简化模型以降低拟合复杂度 - 使用更稳健的非线性拟合算法(Levenberg-Marquardt)替代R默认的Gauss-Newton算法
R语言方案
使用minpack.lm包的nlsLM函数,该函数专门解决非线性拟合的收敛问题:
# 安装并加载依赖包 install.packages("minpack.lm") library(minpack.lm) # 样本数据 Lc <- c(0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.01,0.05,0.08,0.1,0.049554,0.099109,0.1486635,0.1783962,0.198218,0.24479923,0.29534482,0.3468815,0.396436,0.43409742,0.495545,0.5450995,0.594654,0.6442085,0.693763,0.7433175,0.792871,0.941534313,0.99108875,1.486634,1.982178667,2.477723333,2.477723333,2.973267327,4.45990099,5.946534653,7.928712871,9.415346535,12.88415842,16.3529703,19.32623762,19.32623762,22.7950495,22.7950495,27.33423762,27.33423762,27.33423762,27.33423762,29.23712871,29.23712871,32.70594059,35.67920792,35.67920792,37.66138614,37.66138614,39.1480198,39.1480198,39.1480198,59.46534653,59.46534653,79.26750804,79.26750804) y <- c(0.7336301,0.7300885,0.7302002,0.7265662,0.7217741,0.7223443,0.7238027,0.71864,0.7094976,0.6989751,0.6764343,0.6598028,0.410136,0.3917024,0.3777954,0.3685038,0.3590556,0.3537131,0.3488757,0.343905,0.3402811,0.3378536,0.3371936,0.3337051,0.3308202,0.3284294,0.328673,0.3269062,0.3233758,0.3233758,0.3210403,0.3189582,0.3163805,0.3135109,0.3126578,0.3114899,0.3090119,0.3056575,0.3040519,0.301711,0.3005168,0.2975471,0.2903744,0.2960987,0.2874757,0.2914471,0.2900818,0.2900818,0.2841886,0.2841886,0.2807069,0.2861011,0.2829085,0.2770104,0.2824439,0.2748469,0.2797121,0.2669634,0.2723519,0.2768586,0.2676962,0.2730733,0.2656272,0.2706228) # 初始值 n.init <- 0.6 K.init <- 0.4 a1 <- 0.01 a2.init <- 0.75 # 简化后的模型公式 model_formula <- y ~ a2 + (a1 - a2) * ((Lc/K)^n / (1 + (Lc/K))^n) # 执行拟合 fit <- nlsLM(model_formula, start = list(n = n.init, K = K.init, a2 = a2.init), control = nls.lm.control(maxiter = 1000)) # 查看拟合结果 summary(fit) # 可视化拟合效果 plot(Lc, y, pch = 16, col = "steelblue", main = "NLS模型拟合结果") lines(sort(Lc), predict(fit, newdata = list(Lc = sort(Lc))), col = "red", lwd = 2) legend("topright", legend = c("原始数据", "拟合曲线"), col = c("steelblue", "red"), pch = c(16, NA), lty = c(NA, 1))
Python语言方案
使用scipy.optimize.curve_fit函数,默认采用Levenberg-Marquardt算法:
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit # 样本数据 Lc = np.array([0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.01,0.05,0.08,0.1,0.049554,0.099109,0.1486635,0.1783962,0.198218,0.24479923,0.29534482,0.3468815,0.396436,0.43409742,0.495545,0.5450995,0.594654,0.6442085,0.693763,0.7433175,0.792871,0.941534313,0.99108875,1.486634,1.982178667,2.477723333,2.477723333,2.973267327,4.45990099,5.946534653,7.928712871,9.415346535,12.88415842,16.3529703,19.32623762,19.32623762,22.7950495,22.7950495,27.33423762,27.33423762,27.33423762,27.33423762,29.23712871,29.23712871,32.70594059,35.67920792,35.67920792,37.66138614,37.66138614,39.1480198,39.1480198,39.1480198,59.46534653,59.46534653,79.26750804,79.26750804]) y = np.array([0.7336301,0.7300885,0.7302002,0.7265662,0.7217741,0.7223443,0.7238027,0.71864,0.7094976,0.6989751,0.6764343,0.6598028,0.4101
相关产品推荐
相关产品推荐

