Почему мои прогнозируемые значения все почти идентичны (и похожи на среднее значение)? - PullRequest
0 голосов
/ 29 января 2020

Я удалил тренд и сезонность из набора данных, содержащего 911 пожарных вызовов для определенного города, записанных ежечасно, в течение 17 лет. Затем я снабдил его линейным регрессором и попытался предсказать значения на предстоящий 24-часовой период. Тем не менее, мое значение R ^ 2 обычно близко к 0 (часто отрицательное), и все мои прогнозируемые значения находятся в пределах одной 10000-й (или менее) друг от друга, поэтому при построении графика она выглядит как горизонтальная линия, приблизительно отражающая среднее значение ,

Что я делаю не так?

Вот мой код:

from datetime import timedelta
def run_regression(df, dependent, label):
    cut_datetime = df[dependent].max()-timedelta(hours=26) #24 hour lag plus 4 hours to predict

    train = df[df[dependent] < cut_datetime][['julian_datetime', label]].dropna(how='any') #train == data before cut_datetime
    test = df[df[dependent] >= cut_datetime][['julian_datetime', label]].dropna(how='any') #test == data after cut_datetime

    regress = sklearn.linear_model.LinearRegression().fit(
                                              X = train[['julian_datetime']],
                                              y = train[label])

    test['predicted_value'] = regress.predict(
                                              X = test[['julian_datetime']])

    #Plots
    (test[label] - test['predicted_value']).plot()
    test[[label, 'predicted_value']].plot()

    #Metrics
    print('MSE: ', sklearn.metrics.mean_squared_error(test[label], test['predicted_value']))
    print('R^2: ', sklearn.metrics.r2_score(test[label], test['predicted_value']))
    print('Sample of predicted values: ', '\n', test['predicted_value'][:10])

run_regression(exp_model_df, 'incident_hour', 'label')

incident_hour -> формат даты и времени julian_date, указанный в начале function

Вот пример набора данных:

incident_hour   julian_datetime     label
0   2003-11-07 09:00:00     2452950.87500000    6.696136
1   2003-11-07 10:00:00     2452950.91666667    -5.293884
2   2003-11-07 11:00:00     2452950.95833333    5.679681
3   2003-11-07 12:00:00     2452951.00000000    4.411278
4   2003-11-07 13:00:00     2452951.04166667    5.837476
5   2003-11-07 14:00:00     2452951.08333333    6.469543
6   2003-11-07 15:00:00     2452951.12500000    2.191286
7   2003-11-07 16:00:00     2452951.16666667    0.347877
8   2003-11-07 17:00:00     2452951.20833333    0.151539
9   2003-11-07 18:00:00     2452951.25000000    5.925230
10  2003-11-07 19:00:00     2452951.29166667    8.563340
11  2003-11-07 20:00:00     2452951.33333333    3.151843
12  2003-11-07 21:00:00     2452951.37500000    3.751080
13  2003-11-07 22:00:00     2452951.41666667    5.476664
14  2003-11-07 23:00:00     2452951.45833333    0.146253
15  2003-11-08 00:00:00     2452951.50000000    2.879449
16  2003-11-08 01:00:00     2452951.54166667    0.712886
17  2003-11-08 02:00:00     2452951.58333333    6.118765
18  2003-11-08 03:00:00     2452951.62500000    6.052857
19  2003-11-08 04:00:00     2452951.66666667    0.892937
20  2003-11-08 05:00:00     2452951.70833333    -3.009876
21  2003-11-08 06:00:00     2452951.75000000    -3.525916
22  2003-11-08 07:00:00     2452951.79166667    -0.076345
23  2003-11-08 08:00:00     2452951.83333333    -3.236072
24  2003-11-08 09:00:00     2452951.87500000    -2.855910
25  2003-11-08 10:00:00     2452951.91666667    3.599330
26  2003-11-08 11:00:00     2452951.95833333    6.845144
27  2003-11-08 12:00:00     2452952.00000000    6.764351
28  2003-11-08 13:00:00     2452952.04166667    -1.896929
29  2003-11-08 14:00:00     2452952.08333333    0.370614
30  2003-11-08 15:00:00     2452952.12500000    4.899800
31  2003-11-08 16:00:00     2452952.16666667    7.245627
32  2003-11-08 17:00:00     2452952.20833333    1.559531
33  2003-11-08 18:00:00     2452952.25000000    8.437391
34  2003-11-08 19:00:00     2452952.29166667    4.957201
35  2003-11-08 20:00:00     2452952.33333333    1.349833
36  2003-11-08 21:00:00     2452952.37500000    6.257467
37  2003-11-08 22:00:00     2452952.41666667    -1.221531
38  2003-11-08 23:00:00     2452952.45833333    0.552749
39  2003-11-09 00:00:00     2452952.50000000    -0.917920
40  2003-11-09 01:00:00     2452952.54166667    -4.394944
41  2003-11-09 02:00:00     2452952.58333333    -2.238189
42  2003-11-09 03:00:00     2452952.62500000    -1.062656
43  2003-11-09 04:00:00     2452952.66666667    3.813087
44  2003-11-09 05:00:00     2452952.70833333    -4.540094
45  2003-11-09 06:00:00     2452952.75000000    2.680210
46  2003-11-09 07:00:00     2452952.79166667    4.581881
47  2003-11-09 08:00:00     2452952.83333333    3.803750
48  2003-11-09 09:00:00     2452952.87500000    6.590574
49  2003-11-09 10:00:00     2452952.91666667    8.227202

Вот график результатов:

enter image description here

Ответы [ 2 ]

0 голосов
/ 29 января 2020

Вы используете совершенно неправильный подход для временных рядов.

Давайте посмотрим, что делает линейная регрессия:

julian_datetime     label
0   2.452951e+06    6.696136
1   2.452951e+06    -5.293884
2   2.452951e+06    5.679681
3   2.452951e+06    4.411278
4   2.452951e+06    5.837476

Так что в основном он найдет функцию до f(x) = a*x +b и ваши x= julian_datetime и f(x)= label. И он минимизирует потери от label-prediction, поэтому проблема заключается в том, что для всех чисел 2.45,...,2.45 он найдет другое число. Но во временных сериях вы должны работать с потоком данных! В настоящее время время вообще не включается.

Один из примеров, чтобы сделать это для временных рядов (что не является лучшим подходом), - добавить все предыдущие 2 значения в качестве функции, чтобы он выглядел например:

julian_datetime     julian_datetime-1 julian_datetime-2 label
0   2.452951e+06                                         6.696136
1   2.452951e+06    2.452951e+06                         -5.293884
2   2.452951e+06    2.452951e+06     2.452951e+06       5.679681
3   2.452951e+06    2.452951e+06     2.452951e+06       4.411278

кстати, почему юлианское время и дата всегда имеют одно и то же значение? Ах, это еще хуже! Вы должны использовать столбец метки в качестве предыдущего значения, чтобы он выглядел следующим образом:

   y          y-1        y-2
0 6.696136
1 -5.293884  6.696136
2 5.679681   -5.293884           6.696136
3

, тогда ваше трианирование будет y-1, y-2, а ваш прогноз y

0 голосов
/ 29 января 2020

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

Основываясь на коде, вы подбираете модель с одной независимой переменной julian_datetime для прогнозирования вашей зависимой переменная label. Исходя из ваших данных выборки, переменная julian_datetime имеет очень большое количество повторяющихся значений. Я не удивлюсь, если у вас будет одинаковое значение julian_datetime для каждого наблюдения в вашем тестовом наборе. Это может привести к одному и тому же прогнозу, так как все входные данные одинаковы.

Если это так, и вы все еще не уверены, попробуйте перенести несколько наблюдений из тренировочного набора в набор тестов с разными julian_datetime значений, чтобы увидеть, если вы получаете разные прогнозы. Скорее всего, вы заметите разные прогнозы для этих новых наблюдений. В результате вы увидите изменения в своей строке.

Обновление

Я полагаю, что есть несколько причин, по которым строка не изменилась:

  1. Я полагаю, что ваш тренировочный набор включает в общей сложности около 140000 наблюдений, а ваш набор испытаний включает 25-100 наблюдений. Кроме того, ваш график содержит только данные о тестовом наборе. Следовательно, ваши прогнозы будут казаться неизменными, поскольку вы строите линию линейной регрессии в очень маленьком окне.

  2. Ваша линия линейной регрессии снова будет довольно плоской, если время не будет иметь эффекта на ваш ответ вообще.

Если вы все еще хотите go перейти к построению модели линейной регрессии, я бы рекомендовал сделать следующее:

  • Убедитесь, что ваш набор тестов достаточно большой, чтобы заметить изменения в прогнозах, или вы столкнетесь с этой же проблемой.
  • Попробуйте включить функции sin и cos в вашу модель, чтобы учесть возможную сезонность
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...