首页 > 解决方案 > 如何强制零拦截和日志拟合时间序列?

问题描述

我想在时间序列上拟合对数曲线,从 2015 年 7 月 0 日,y:30 日到 2024 年 7 月 30 日结束。(超出数据范围)

可重现的例子。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
y = [0.9166269898414612, 2.306040048599243, 8.813980102539062, 11.875900268554688, 10.998200416564941, 10.727499961853027, 79.02120208740234, 203.87100219726562, 305.8789978027344, 1118.31005859375, 669.9240112304688, 433.86700439453125, 197.38099670410156, 107.0610122680664, 162.16603088378906, 218.65414428710938, 183.9669189453125, 180.16017150878906, 207.60205078125, 345.5546569824219, 386.59033203125, 1314.9862060546875, 2107.88720703125, 2105.572509765625]
x = pd.date_range(start="2015-08-01",end="2021-04-06", periods=len(y))

x = mdates.date2num(x)
p4 = np.poly1d(np.polyfit(x, np.log(y), 1))
xx = np.linspace(x.min(), x.max(), 100)
dd = mdates.num2date(xx)


fig = plt.figure()
fig.set_size_inches((20, 16))
ax1 = fig.add_axes((0, 0.72, 1, 0.32))
ax1.plot(x, y, '-r', label='data')
ax1.plot(dd, p4(xx), '-b', label='logfit')

ax1.set_yscale('log')
plt.grid(True, which="both", ls="-", alpha = 0.3)
plt.legend(loc='upper left')
plt.show()

拦截是错误的

上例中的 x-intercept 不在应有的位置,我希望它位于 (0, 2015-07-30) 并且不太适合数据

标签: pythonnumpymatplotlibtime-series

解决方案


您可以使用 sklearn 的线性回归:

from sklearn.linear_model import LinearRegression

lg = LinearRegression(fit_intercept=False)

lg.fit(x.reshape(-1,1),np.log(y))

xx = np.linspace(x.min(), x.max(), 100)
yy_ = s.predict(xx.reshape(-1,1))

推荐阅读