我正在尝试拟合一些有关钟摆的数据,以找到钟摆衰减的时间常数。 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))
您用于拟合的方程是小角度的近似值 (<5°) where we can accept
sin(x) = x
)。只需选择角度遵守此约束的数据即可返回有效拟合。
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
看起来像: