我有两个变量,我正try 在Scipy Optimize中使用curve_fit来拟合数据.它看起来不错,但左侧的红线与数据(绿点)不太匹配.我如何在curve_fit()上加一些重物才能把左边的红线移到蓝线上呢?

enter image description here

以下是代码:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt 
from scipy.optimize import curve_fit
from pandas import DataFrame

x = [  57,   83,  124,  141,  196,  223,  275,  302,  341,  714,  895,
   1034, 1117, 1207, 1248, 1416, 1494, 1563, 1708, 1785, 1863, 2015,
   2139, 2238, 2312, 2412, 2442, 2520, 2596, 2658, 2706, 2777, 2846,
   2966, 3106, 3241, 3276, 3424, 3568, 3647, 3831, 3961, 4091, 4248,
   4430, 4478, 4644, 4833, 5052, 6041 ]

y = [ 70,  81,  87,  91,  96, 106, 109, 114, 120, 129, 144, 162, 168,
   175, 181, 184, 190, 195, 205, 213, 216, 219, 224, 226, 231, 236,
   239, 247, 255, 260, 264, 269, 282, 292, 297, 304, 308, 313, 319,
   322, 327, 333, 338, 341, 345, 354, 362, 364, 374, 391  ]
       

plt.scatter(x,y,color='green')

def func(x, a, b):
    return a * np.power(x,b) 

popt, pcov = curve_fit(func, x, y)

plt.plot(x, func(x, *popt), 'b-', label='fit: a=%5.3f, b=%5.3f' % tuple(popt))

popt2 = [12.6, 0.386]
plt.plot(x, func(x, *popt2), 'r-', label='fit: a=%5.3f, b=%5.3f' % tuple(popt2))

plt.semilogx()

推荐答案

似乎没有必要增加权重,但可以通过增加更多自由度来改进模型:

import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit, Bounds

x = np.array([
     57,   83,  124,  141,  196,  223,  275,  302,  341,  714,  895,
   1034, 1117, 1207, 1248, 1416, 1494, 1563, 1708, 1785, 1863, 2015,
   2139, 2238, 2312, 2412, 2442, 2520, 2596, 2658, 2706, 2777, 2846,
   2966, 3106, 3241, 3276, 3424, 3568, 3647, 3831, 3961, 4091, 4248,
   4430, 4478, 4644, 4833, 5052, 6041,
])

y = np.array([
    70,  81,  87,  91,  96, 106, 109, 114, 120, 129, 144, 162, 168,
   175, 181, 184, 190, 195, 205, 213, 216, 219, 224, 226, 231, 236,
   239, 247, 255, 260, 264, 269, 282, 292, 297, 304, 308, 313, 319,
   322, 327, 333, 338, 341, 345, 354, 362, 364, 374, 391,
])

def model(x: np.ndarray, a: float, b: float, c: float, d: float) -> np.ndarray:
    return a * (x - b)**c + d

popt, *_ = curve_fit(
    f=model, xdata=x, ydata=y,
    p0=(1, 0, 2, 0),
    bounds=Bounds(
        lb=(0,  -1e4,  0, -1e3),
        ub=(1e4, 1e4, 50,  1e3),
    ),
)
print(popt)

fig, ax = plt.subplots()
ax.semilogx(x, y, label='experiment')
ax.semilogx(x, model(x, *popt), label='fit')
ax.legend()
plt.show()
[ 1.75236837e+02 -2.67170725e+03  2.30138464e-01 -9.99999670e+02]

fit

Python相关问答推荐

如果索引不存在,pandas系列将通过索引获取值,并填充值

如何使用SubProcess/Shell从Python脚本中调用具有几个带有html标签的参数的Perl脚本?

根据给定日期的状态过滤查询集

分组数据并删除重复数据

如何在Deliveryter笔记本中从同步上下文正确地安排和等待Delivercio代码中的结果?

Select 用a和i标签包裹的复选框?

SQLGory-file包FilField不允许提供自定义文件名,自动将文件保存为未命名

Python上的Instagram API:缺少client_id参数"

Vectorize多个头寸的止盈/止盈回溯测试pythonpandas

优化器的运行顺序影响PyTorch中的预测

利用Selenium和Beautiful Soup实现Web抓取JavaScript表

将输入聚合到统一词典中

什么是合并两个embrame的最佳方法,其中一个有日期范围,另一个有日期没有任何共享列?

Pandas Data Wrangling/Dataframe Assignment

基于行条件计算(pandas)

Matplotlib中的字体权重

Python 3试图访问在线程调用中实例化的类的对象

在极点中读取、扫描和接收有什么不同?

如何在PythonPandas 中对同一个浮动列进行逐行划分?

如何将一个文件的多列导入到Python中的同一数组中?