sciklearn线性回归(最终优势始终为0)

时间:2018-06-27 13:38:24

标签: python pandas scikit-learn regression linear-regression

我正在尝试使用这种小型 Dataset (Screenshot)进行简单的线性回归。

数据集是记录,每个记录分为四个小时间段(2016-2018年的第二个到最后一个时间段除外)。

我想做的是尝试预测2019-2022年时间段的记录输出。为此,我放置了一个2019-2022时间块,其中所有行的值都为0(因为在将来这段时间内没有做任何事情)。我这样做是为了适应sklearn的train_test_split的语法,并使用了以下代码:

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split 
from sklearn.linear_model import LinearRegression

df = pd.read_csv("TCO.csv")
df = df[['2000-2003', '2004-2007', '2008-2011','2012-2015','2016-2018','2019-2022']]
linreg = LinearRegression()
X1_train, X1_test, y1_train, y1_test = train_test_split(df[['2000-2003','2004-2007','2008-2011',
'2012-2015','2016-2018']],df['2019-2022'],test_size=0.4,random_state = 42)

linreg.fit(X1_train, y1_train)
linreg.intercept_
list( zip( ['2000-2003','2004-2007','2008-2011','2012-2015','2016-2018'],list(linreg.coef_)))

y1_pred = linreg.predict(X1_test)
print(y1_pred)

test_pred_df = pd.DataFrame({'actual': y1_test,
                          'predicted': np.round(y1_pred, 2),
                          'residuals': y1_test - y1_pred})

print(test_pred_df[0:10].to_string())

由于某种原因,该算法对于所有残差为0的行将始终返回0作为最终预测(这是由于2019-2022年的时间段所有行均为零)。

我认为我做错了什么,但我不知道是什么。 (我是这个主题的初学者。)有人可以指出出了什么问题以及如何解决?

编辑:我添加了数据的可复制版本:

      df = pd.DataFrame( {'Country:':['Brunei','Cambodia','Indonesia','Laos',
                             'Malaysia','Myanmar','Philippines','Singaore',
                             'Thailand','Vietnam'],
                 '2000-2003': [0,0,14,1,6,0,25,8,26,8],
                 '2004-2007': [0,3,15,6,21,0,37,11,44,36],
                 '2008-2011': [0,5,31,9,75,0,58,27,96,61],
                 '2012-2015': [5,11,129,35,238,3,99,65,170,96],
                 '2016-2018': [6,22,136,17,211,10,66,89,119,88]})

1 个答案:

答案 0 :(得分:0)

根据您的数据,我认为这就是您要的[编辑:请参见下面的更新版本]:

import pandas as pd
from sklearn.linear_model import LinearRegression

df = pd.DataFrame( {'Country:':['Brunei','Cambodia','Indonesia','Laos',
                             'Malaysia','Myanmar','Philippines','Singaore',
                             'Thailand','Vietnam'],
                 '2000-2003': [0,0,14,1,6,0,25,8,26,8],
                 '2004-2007': [0,3,15,6,21,0,37,11,44,36],
                 '2008-2011': [0,5,31,9,75,0,58,27,96,61],
                 '2012-2015': [5,11,129,35,238,3,99,65,170,96],
                 '2016-2018': [6,22,136,17,211,10,66,89,119,88]})

# create a transposed version with country in header
df_T = df.T
df_T.columns = df_T.iloc[-1]
df_T = df_T.drop("Country:")

# create a new columns for target
df["2019-2022"] = np.NaN

# now fit a model per country and add the prediction
for country in df_T:
    y = df_T[country].values
    X = np.arange(0,len(y))
    m = LinearRegression()
    m.fit(X.reshape(-1, 1), y)
    df.loc[df["Country:"] == country, "2019-2022"] = m.predict(5)[0]

此打印:

Country:        2000-2003   2004-2007   2008-2011   2012-2015   2016-2018   2019-2022
Brunei  0   0   0   5   6   7.3
Cambodia    0   3   5   11  22  23.8
Indonesia   14  15  31  129 136 172.4
Laos    1   6   9   35  17  31.9
Malaysia    6   21  75  238 211 298.3
Myanmar 0   0   0   3   10  9.5
Philippines 25  37  58  99  66  100.2
Singaore    8   11  27  65  89  104.8
Thailand    26  44  96  170 119 184.6
Vietnam 8   36  61  96  88  123.8

忘记我对shift()的评论。我考虑过,但对于这么少量的数据,这是没有意义的。但是考虑时间序列方法并将每个国家的时间序列视为一个时间序列可能仍然对您有价值。

编辑:

不好意思。上面的代码是不必要的复杂操作,但这只是我逐步进行操作的结果。当然,它可以像tihs一样逐行完成:

import pandas as pd
from sklearn.linear_model import LinearRegression

df = pd.DataFrame( {'Country:':['Brunei','Cambodia','Indonesia','Laos',
                             'Malaysia','Myanmar','Philippines','Singaore',
                             'Thailand','Vietnam'],
                 '2000-2003': [0,0,14,1,6,0,25,8,26,8],
                 '2004-2007': [0,3,15,6,21,0,37,11,44,36],
                 '2008-2011': [0,5,31,9,75,0,58,27,96,61],
                 '2012-2015': [5,11,129,35,238,3,99,65,170,96],
                 '2016-2018': [6,22,136,17,211,10,66,89,119,88]})

# create a new columns for target
df["2019-2022"] = np.NaN

for idx, row in df.iterrows():
    y = row.drop(["Country:", "2019-2022"]).values
    X = np.arange(0,len(y))
    m = LinearRegression()
    m.fit(X.reshape(-1, 1), y)
    df.loc[idx, "2019-2022"] = m.predict(len(y)+1)[0]

1500行应该没问题。