将非线性单变量回归拟合到 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 中的时间序列数据的主要内容,如果未能解决你的问题,请参考以下文章