为什么 curve_fit 函数无法拟合数据?

问题描述 投票:0回答:1

我正在尝试拟合一些有关钟摆的数据,以找到钟摆衰减的时间常数。 curve_fit 函数似乎无法正确拟合数据。

这是我使用的数据和我的代码:

数据链接

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.stats import chi2

filepath1 = '1.txt'


t1, x1, y1 = np.genfromtxt(filepath1, dtype=float, delimiter = ' ', skip_header = 2, unpack=True)



rad1 = np.arctan(x1/y1)


#t1, rad1 = t1[:1500], rad1[:1500]

error = 0.05*np.ones(len(t1))

def angle (t, theta_0, tau, T , phi):
    return theta_0 * np.exp(-t/tau) * np.cos(((2*np.pi)/T) * t + phi)

popt1, pcov1 = curve_fit(angle, t1, rad1,sigma = error, p0=(0.45,50,1.3,0.05), absolute_sigma=True, method='lm')


theta_0, tau, T , phi = popt1

print(tau,T)
plt.plot(t1,rad1)
plt.plot(t1,angle(t1,theta_0, tau, T , phi))

当我减少需要拟合的数据数量时,cruve fit 函数以某种方式很好地拟合了数据。

python numpy matplotlib scipy
1个回答
0
投票

TL;博士

您用于拟合的方程是小角度的近似值 (<5°) where we can accept

sin(x) = x
)。只需选择角度遵守此约束的数据即可返回有效拟合。

MCVE

import numpy as np
import pandas as pd
from scipy import optimize
from sklearn.metrics import r2_score

我们加载并转换您的数据:

data = pd.read_csv("https://pastebin.com/raw/Yszin3Zy", header=1, sep=" ")
data = data.drop("Unnamed: 3", axis=1)
data = data.set_index("t")
data["x"] *= np.pi / 180.

我们选择近似值成立的数据:

data = data.loc[100:,:]

我们用简化模型进行回归:

def model(t, theta_0, tau, T , phi):
    return theta_0 * np.exp(- t / tau) * np.sin(((2 * np.pi) / T) * t + phi)

popt, pcov = optimize.curve_fit(
    model, data.index, data.x, p0=(0.45, 30, 1.3, 0.05)
)

我们推断回归曲线:

yhat = model(data.index, *popt)
r2_score(data.x, yhat)  # 0.9915901662189318

看起来像:

© www.soinside.com 2019 - 2024. All rights reserved.