无法使用指数 curve_fit 来处理日期

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

我正在尝试绘制 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()

enter image description here

我正确处理日期吗?

我应该进行 p0 初始猜测吗?

这个问题/解决方案可能会提供一些线索。

如果 x 轴以日期格式标记就好了(但现在不重要)。

python date matplotlib curve-fitting yfinance
1个回答
0
投票

除了标准化数据之外,实际选择一个好的函数也很重要。在你的例子中你有:

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")

结果:

results

如果您最终需要获得初始猜测,您可以在线搜索如何获得任何函数的初始猜测。例如,如果我正在拟合指数增长函数并且我知道数据的偏移量为 100,我可以将

c
的初始猜测设置为 100...

希望这对您有帮助。

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