将非线性单变量回归拟合到 Python 中的时间序列数据

Posted

技术标签:

【中文标题】将非线性单变量回归拟合到 Python 中的时间序列数据【英文标题】:Fitting a non-linear univariate regression to time-series data in Python 【发布时间】:2018-12-09 18:13:58 【问题描述】:

我最近开始使用 python 进行机器学习。下面是我选择的一个数据集作为示例,以及我到目前为止所使用的代码。选择 [2000....2015] 作为测试数据和训练数据 [2016, 2017]。

Dataset  
      Years        Values
    0    2000      23.0
    1    2001      27.5
    2    2002      46.0
    3    2003      56.0
    4    2004      64.8
    5    2005      71.2
    6    2006      80.2
    7    2007      98.0
    8    2008     113.0
    9    2009     155.8
    10   2010     414.0
    11   2011    2297.8
    12   2012    3628.4
    13   2013   16187.8
    14   2014   25197.8
    15   2015   42987.8
    16   2016   77555.5
    17   2017  130631.9

import pandas as pd
import numpy as np

import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

from sklearn.ensemble import RandomForestClassifier

df = pd.DataFrame([[i for i in range(2000,2018)], 
[23.0,27.5,46.0,56.0,64.8,71.2,80.2,98.0,113.0,155.8,414.0,2297.8,3628.4,16187.8,25197.8,42987.8,77555.5,130631.9]])


df = df.T
df.columns = ['Years', 'Values']

上面的代码创建了DataFrame。要记住的另一件重要事情是我的Years 列是一个时间序列,而不仅仅是一个连续值。我没有进行任何更改来适应这一点。

我想拟合可能有帮助的非线性模型,并像我为线性模型示例所做的那样打印绘图。这是我尝试使用线性模型的方法。此外,在我自己的示例中,我似乎没有考虑到我的 Years 列是时间序列而不是连续的这一事实。

一旦我们有了模型,就想用它来预测至少未来几年的值。

X = df.iloc[:, :-1].values
y = df.iloc[:, 1].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.1, random_state = 0, shuffle = False)
lm = LinearRegression()
lm.fit(X_train, y_train)
y_pred = lm.predict(X_test)
plt.scatter(X_train, y_train, color = 'red')
plt.plot(X_train, lm.predict(X_train), color = 'blue')
plt.title('Years vs Values (training set)')
plt.xlabel('Years')
plt.ylabel('Values')
plt.show()

【问题讨论】:

不明白你想要什么!你想要非线性回归吗?或者您想知道如何将您的输出发送到fit my output to the X_train and Y_train data,因为您似乎已经这样做了! 嗨 Abhishek,我需要一个非线性回归。我已经尝试过SVM(kernel = 'poly'),但没有奏效。你能帮忙吗? 好的,你也可以DataFramename.dtypes,告诉我你得到了什么? 年份:int64,值:float64 好吧,想办法 【参考方案1】:

试试这个。您也可以打印预测值。 预计 5 年。

import numpy.polynomial.polynomial as poly
import pandas as pd
import numpy as np

import matplotlib.pyplot as plt

df = pd.DataFrame([[i for i in range(2000,2018)],
[23.0,27.5,46.0,56.0,64.8,71.2,80.2,98.0,113.0,155.8,414.0,2297.8,3628.4,16187.8,25197.8,42987.8,77555.5,130631.9]])
df = df.T
df.columns = ['Year', 'Values']
df['Year'] = df['Year'].astype(int)
df['Values'] = df['Values'].astype(int)
no_of_predictions = 5


X = np.array(df.Year, dtype = float)
y = np.array(df.Values, dtype = float)
Z = [2019,2020,2021,2022]
coefs = poly.polyfit(X, y, 4)
X_new = np.linspace(X[0], X[-1]+no_of_predictions, num=len(X)+no_of_predictions)
ffit = poly.polyval(X_new, coefs)
pred = poly.polyval(Z, coefs)
predictions = pd.DataFrame(Z,pred)
print predictions
plt.plot(X, y, 'ro', label="Original data")
plt.plot(X_new, ffit, label = "Fitted data")
plt.legend(loc='upper left')
plt.show()

【讨论】:

这是目前最好的解决方案。有没有办法让我们也可以控制预测值?我的意思是,我们能否以某种方式降低一年的预测值。假设在这种情况下,我们将 2019 年的预测值设为 271917.56,我们能否以某种方式将所有年份的预测值降低到一个较小的数字?我希望你明白?我昨天也在数据集上尝试了 ARIMA 模型,但由于数据中没有季节性,即使在第一次差异、第二次差异、季节性第一差异之后,我也无法将其更改为“固定”数据集。没有任何效果 很高兴听到我的回答对您有所帮助。既然它是问题陈述,我认为如果你接受我的回答并提出一个新问题会更好。一定会帮助你的。【参考方案2】:

编辑:我的回答是错误的,我习惯使用分类器而不是回归器;不删除它,因为我害怕被禁止发布更多答案。不要使用这个答案。

试试这个

import pandas as pd
import numpy as np

import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

from sklearn.ensemble import RandomForestClassifier

df = pd.DataFrame([[i for i in range(2000,2018)], 
[23.0,27.5,46.0,56.0,64.8,71.2,80.2,98.0,113.0,155.8,414.0,2297.8,3628.4,16187.8,25197.8,42987.8,77555.5,130631.9]])


df = df.T
df.columns = ['Year', 'Values']
df['Year'] = df['Year'].astype(int)
df['Values'] = df['Values'].astype(int)

你的数据框

X = df[['Year']]
y = df[['Values']]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.1, random_state = 0, shuffle = False)
print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)

clf = RandomForestClassifier(n_estimators=10)
clf.fit(X_train, y_train)


y_pred = clf.predict(X_test)

plt.scatter(X_train, y_train, color = 'red')
plt.plot(X_train, clf.predict(X_train), color = 'blue')
plt.title('Years vs Values (training set)')
plt.xlabel('Years')

plt.xticks(rotation=90)
plt.ylabel('Values')
plt.show()

【讨论】:

删除你的答案没有被封号的危险,既然是错的,你就应该这样做……【参考方案3】:

同时,我也试过了

import numpy.polynomial.polynomial as poly
X = np.array(df.Years, dtype = float)
y = np.array(df.Values, dtype = float)
coefs = poly.polyfit(X, y, 4)
X_new = np.linspace(X[0], X[-1], num=17)
ffit = poly.polyval(X_new, coefs)
plt.plot(X, y, 'ro', label="Original data")
plt.plot(X_new, ffit, label = "Fitted data")
plt.legend(loc='upper left')
plt.show()

它确实提供了几乎完美的契合度。但现在我不清楚如何使用这些来预测未来五年的价值。

【讨论】:

以上是关于将非线性单变量回归拟合到 Python 中的时间序列数据的主要内容,如果未能解决你的问题,请参考以下文章

使用tensorflow实现机器学习中的线性拟合

拟合线性回归模型中的值误差

python曲线拟合结果总结

单变量线性回归模型

MLlib--保序回归

利用python进行回归分析