Как спрогнозировать значения на n дней? out-of-sample
Обучил модель предсказывать данные на тестовом наборе данных. Теперь нужно сделать прогноз на n-дней от последней даты в датасете. Как это сделать?
Обучал модель так:
- Сгенерил новые признаки
def make_features(data, max_lag, rolling_mean_size):
data['day'] = data.index.day
data['weekday'] = data.index.weekday
data['dayofyear'] = data.index.dayofyear
for lag in range(1, max_lag+1):
data['lag_{}'.format(lag)]= data['events'].shift(lag)
data['rolling_mean'] = data['events'].shift().rolling(rolling_mean_size).mean()
data['rolling_std'] = data['events'].rolling(2).std()
return data
- Разбил на тестовые и тренировочные данные
def timeseries_train_test_split(X, y, test_size):
# Получаем индекс, с которого начинаются тестовые данные
test_index = int(len(X)*(1-test_size))
X_train = X.iloc[:test_index]
y_train = y.iloc[:test_index]
X_test = X.iloc[test_index:]
y_test = y.iloc[test_index:]
return X_train, X_test, y_train, y_test
y = data_new.dropna().events
X = data_new.dropna().drop(['events'], axis=1)
X_train, X_test, y_train, y_test = timeseries_train_test_split(X, y, test_size=0.1)
- Обучил XGboost-ом
reg = xgb.XGBRegressor(n_estimators=1000,
nthread=4,
min_child_weight=6,
learning_rate=0.1,
subsample=0.7,
max_depth=11,
colsample_bytree=0.7,
)
reg.fit(X_train, y_train,
eval_set=[(X_train, y_train), (X_test, y_test)],
early_stopping_rounds=50,
verbose=False)
X_test_pred = reg.predict(X_test)
В результате получил 2-недельное предсказание по тестовому набору данных https://skr.sh/sBimjbd3ITY?a
Ответы (1 шт):
Если это задача на временные ряды, то предсказывать нужно пошагово:
- делаете фичи из имеющихся у вас данных
- предсказываете на день вперёд за край имеющихся данных
- добавляете полученное предсказание в ваши данные
- если ещё не все
nдней предсказали, то переходите к п.1
Конечно, при таком методе предсказания степень неопределённости сильно растёт с каждым шагом. Если сначала вы опирались на реальные данные, то с каждым последующим шагом вы всё больше начинаете опираться на ваши же предсказания. Поэтому предсказание временных рядов без чёткой периодичности и без дополнительных каких-то данных - дело довольно рисковое.
Update: Как собственно предсказывать.
- делаете новый датафрейм с индексом - следующей датой за максимальной, имеющейся в X, добавляете его через
concatк собственноXв конец - запускаете
make_featuresна этом обновлённомX, таким образом заполняете фичи везде, включая последнюю строку датафрейма - берёте последнюю строку с уже заполненными теперь фичами
X_pred = X.iloc[[-1]] - получаете предсказание
y_pred = reg.predict(X_pred) - дальше можете заполнить
X['events'] = y_pred[0] - и перейти к предсказанию следующей даты