Python线性回归预测日期。

33

我想使用简单线性回归预测未来某个日期的值,但由于日期格式的问题,我无法实现。

这是我手头拥有的数据框:

data_df = 
date          value
2016-01-15    1555
2016-01-16    1678
2016-01-17    1789
...  

y = np.asarray(data_df['value'])
X = data_df[['date']]
X_train, X_test, y_train, y_test = train_test_split             
(X,y,train_size=.7,random_state=42)

model = LinearRegression() #create linear regression object
model.fit(X_train, y_train) #train model on train data
model.score(X_train, y_train) #check score

print (‘Coefficient: \n’, model.coef_)
print (‘Intercept: \n’, model.intercept_) 
coefs = zip(model.coef_, X.columns)
model.__dict__
print "sl = %.1f + " % model.intercept_ + \
     " + ".join("%.1f %s" % coef for coef in coefs) #linear model

我试图转换日期,但未成功

data_df['conv_date'] = data_df.date.apply(lambda x: x.toordinal())

data_df['conv_date'] = pd.to_datetime(data_df.date, format="%Y-%M-%D")

你可能想要研究ARMA或ARIMA模型来处理时间序列数据。 - Sam
6个回答

41

线性回归在日期数据上不起作用。因此,我们需要将其转换为数值。以下代码将把日期转换为数值:

线性回归不能处理日期数据,需要将其转换为数字值。下面的代码将日期转换为数字值:

import datetime as dt
data_df['Date'] = pd.to_datetime(data_df['Date'])
data_df['Date']=data_df['Date'].map(dt.datetime.toordinal)

很不幸,这个无法工作 - 我收到了这个错误信息 TypeError: descriptor 'toordinal' requires a 'datetime.date' object but received a 'str' - jeangelj
我能这样做吗?data_df['date'] = pd.to_datetime(data_df['date'],format='%Y-%m-%d') - jeangelj
2
嗨jeangelj,请添加以下代码行:import datetime as dt data_df['Date'] = pd.to_datetime(data_df['Date']) data_df['Date']=data_df['Date'].map(dt.datetime.toordinal) - Chandan
2
请分享代码片段以将其转换回原始值,这是因为一旦我将日期转换为数字并预测了数字日期值,我希望将其转换回原始格式。 - SDE

6

转换:

1)日期转为数据框索引

df = df.set_index('date', append=False)

2) 将日期时间对象转换为float64对象

df = df.index.to_julian_date()

使用日期作为自变量运行回归分析。


2

线性回归适用于数值数据。日期时间类型不适合此情况。在将其分成三个单独的列(年、月和日)后,您应该删除该列。


1

在使用时

dt.datetime.toordinal

请注意,它仅转换日期值,不考虑分钟、秒等。要完整地从完整的日期时间对象生成序数,您可以使用以下方法:

df['Datetime column'].apply(lambda x: time.mktime(x.timetuple()))

0

我正在深入研究这里提供的不同选项,我只想对它们进行总结。写一篇完整的答案需要时间,但这就是我所研究的内容。

示例参考

我按照每种方法的要求使用了不同的数据类型来取相同的日期。也许我错过了其他选项。

t = pd.Timestamp('2021-09-03 00:00:00')    
   # Timestamp('2021-09-03 00:00:00')   pandas._libs.tslibs.timestamps.Timestamp
t2 = dtt.date(2021, 9, 3)          
   #  datetime.date(2021, 9, 3)     datetime.date

Pandas方法

pandas.to_numeric(arg, errors='raise', downcast=None)
# argscalar, list, tuple, 1-d array, or Series
例子
st3 = pd.to_numeric(df_example.index, downcast='integer')
st3[0]  
1630627200000000000

使用Python/Pandas获得相同的结果

  • pandas.Timestamp.toordinal
  • Python-date.toordinal
    注意:普罗利普提克格里高利序数给出了从公元前1年1月1日到现在的天数。这里的序数被称为普罗利普提克,因为自1582年10月起就采用了格里高利历。2021年8月23日。
# I checked it out and I found a 215 days difference
hoy = dtt.date.today()   # datetime.date(2022, 8, 3)
hoy.toordinal()  # 738370   - (365 * 2022)  =  340
hoy.timetuple()  # tm_yday=215  ---> 340 - 215 = 125
例子
t2.toordinal()
    738036
pd.Timestamp.toordinal(a) 
    738036  

Python方法

例子
time.mktime(t2.timetuple())     
1630638000.0

0

在回归/分类中,区分要使用的数据类型非常重要。

当您使用时间序列时,情况会有所不同,但如果您想将时间数据作为输入的数字数据类型,则应将数据类型从日期时间转换为浮点数(如果您的data_df['conv_date']是一个日期时间对象,如果不是,则应首先使用以下方法进行转换:data_df['conv_date'] = pd.to_datetime(data_df.date, format="%Y-%M-%D")

我同意Thomas Vetterli的答案。小心使用什么类型的时间数据很有用。

如果您只使用年份和月份数据,则dt.datetime.toordinal就足够使用了;

>>import datetime
>>data_df['conv_date'] = pd.to_datetime(data_df.date, format="%Y-%M-%D")
>>data_df['conv_date'] = data_df['conv_date'].map(datetime.datetime.toordinal)
737577

但如果您还想使用小时、分钟和秒钟的信息,那么time.mktime()更适合;
>>import time
>>data_df['conv_date'] = pd.to_datetime(data_df.date, format="%Y-%M-%D")
>>data_df['conv_date'] = data_df['conv_date'].apply(lambda  var: time.mktime(var.timetuple()))
1591016041.0 

另外,1591016044.0是我的数据的另一个典型输出,它随着秒数的变化而变化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接