линейная регрессия sciklearn (окончательный прогноз всегда 0) - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь сделать простую линейную регрессию, используя этот маленький набор данных (снимок экрана) .

Набор данных - это записи, разделенные на небольшие временные блоки по 4 года каждый (за исключением 2-го и последнего временного блока 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 голосов
/ 28 июня 2018

На основании ваших данных, я думаю, это то, что вы просите [Редактировать: см. Обновленную версию ниже]:

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(). Я думал об этом, но это не имеет смысла для этого небольшого количества данных, я думаю. Но, учитывая методы временных рядов и рассматривая ряды каждой страны как временные ряды, все еще может стоить для вас.

Edit:

Простите. Вышеприведенный код неестественно сложен, но был просто результатом того, что я прошел его шаг за шагом. Конечно, это может быть просто сделано построчно, как 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 строк не должно быть проблем.

...