我正在尝试绘制 S&P 500 指数的 curve_fit。
我(我认为)成功地执行了线性拟合/绘图。当我尝试让指数 curve_fit 工作时,我收到此错误:
Optimal parameters not found: Number of calls to function has reached maxfev = 800.
import numpy as np
import matplotlib.pyplot as plt
import yfinance as yf
from scipy.optimize import curve_fit
# get data
df = yf.download("SPY", interval = '1mo')
df = df.reset_index()
def func(x, a, b):
return a * x + b
# ?? return a * np.exp(-b * x) + c
# ?? return a*(x**b)+c
# ?? return a*np.exp(b*x)
# create data arrays
# convert Date to numeric for curve_fit ??
xdata = df['Date'].to_numpy().astype(np.int64)//10**9
ydata = df['Close'].to_numpy()
# p0 = (?, ?, ?) use guesses?
popt, pcov = curve_fit(func, xdata, ydata)
print(popt)
y_pred = func(xdata, *popt)
plt.plot(xdata, ydata)
plt.plot(xdata, y_pred, '-')
plt.show()
我正确处理日期吗?
我应该进行 p0 初始猜测吗?
这个问题/解决方案可能会提供一些线索。
如果 x 轴以日期格式标记就好了(但现在不重要)。
除了标准化数据之外,实际选择一个好的函数也很重要。在你的例子中你有:
def func(x, a, b):
return a * x + b
# ?? return a * np.exp(-b * x) + c
# ?? return a*(x**b)+c
# ?? return a*np.exp(b*x)
当你说你想要拟合指数时,正确的应该是这个,IMO:
# define the exponential growth function, before you had exponential decay because of -b
def ExponentialGrowth(x, a, b, c):
return a * np.exp(b * x) + c # + c due to account for offset
电源功能可能也可以,我没有检查。无论如何,这是代码:
# define the exponential growth function, before you had exponential decay because of -b
def ExponentialGrowth(x, a, b, c):
return a * np.exp(b * x) + c # + c due to account for offset
# get data
x = df['Date'].to_numpy().astype(np.int64)//10**9
y = df['Close'].to_numpy()
# apply z normalization
xNorm = (x - x.mean()) / x.std()
yNorm = (y - y.mean()) / y.std()
# get the optimal parameters
popt, pcov = curve_fit(ExponentialGrowth, xNorm, yNorm)
# get the predicted but in the normalized range
yPredNorm = ExponentialGrowth(xNorm, *popt)
# reverse normalize the predicted values
yPred = yPredNorm * (y.std()) + y.mean()
plt.figure()
plt.scatter(df['Date'], y, 1)
plt.plot(df['Date'], yPred, 'r-')
plt.grid()
plt.legend(["Raw", "Fitted"])
plt.xlabel("Year")
plt.ylabel("Close")
结果:
如果您最终需要获得初始猜测,您可以在线搜索如何获得任何函数的初始猜测。例如,如果我正在拟合指数增长函数并且我知道数据的偏移量为 100,我可以将
c
的初始猜测设置为 100...
希望这对您有帮助。