Временной ряд представляет собой изменение объекта во времени. Например, вы, вероятно, слышали о прогнозировании погоды, когда мы пытаемся предсказать, какими будут погодные условия в будущем в определенное время, возможно, в день или в определенный час дня. Другими примерами временных рядов являются дневная цена закрытия акций компании, ежемесячные данные о количестве осадков, годовые показатели продаж и т. Д.

Я предоставляю ссылку на репозиторий GitHub кода, использованного в этом руководстве. Https://github.com/aryan109/Sunspot_Prediction

Компоненты временного ряда

Тренд

Тенденция показывает общую тенденцию данных к увеличению или уменьшению в течение длительного периода времени.

Периодические колебания

Во временном ряду есть некоторые компоненты, которые имеют тенденцию повторяться в течение определенного периода времени. Они действуют регулярно, скачкообразно. эти вариации бывают двух типов: -
a) Сезонные вариации: это ритмические силы, которые действуют регулярно и периодически в течение периода менее года.
б) Циклические вариации. Вариации временного ряда, которые действуют в течение более одного года, являются циклическими вариациями.

Случайные или нерегулярные движения (шум)

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

Обычно временные ряды в реальном времени могут иметь как тенденцию, так и сезонность, а также некоторый белый шум.

В этом уроке мы собираемся сделать прогноз солнечных пятен.

вы, вероятно, думаете: «Что! на солнце тоже есть пятна ??? "

Солнечные пятна - это участки, которые кажутся темными на поверхности Солнца. Они кажутся темными, потому что они холоднее других частей поверхности Солнца. Температура пятна все еще очень высока - около 6500 градусов по Фаренгейту!
Солнечные пятна используются для отслеживания солнечного цикла. Солнечный цикл - это цикл, который магнитное поле Солнца проходит примерно каждые 11 лет.

Давайте начнем

Во-первых, нам нужно загрузить данные наших временных рядов. вот код для загрузки данных в формате CSV.

!wget — no-check-certificate \
 https://storage.googleapis.com/laurencemoroney-blog.appspot.com/Sunspots.csv \
 -O /tmp/sunspots.csv

загруженный файл CSV будет выглядеть примерно так:

как вы можете видеть, этот файл содержит всего 3 столбца, мы извлечем 1-й и 3-й столбцы в массив NumPy. мы выбрали столбец индекса, будет легко делать прогнозы, так как нам просто нужно указать индекс.

import csv
time_step = []
sunspots = []
with open(‘/tmp/sunspots.csv’) as csvfile:
 reader = csv.reader(csvfile, delimiter=’,’)
 next(reader)
 for row in reader:
 sunspots.append(float(row[2]))
 time_step.append(int(row[0]))
series = np.array(sunspots)
time = np.array(time_step)
print(‘series: {}’.format(series[:5]))
print(‘time: {}’.format(time[:5]))

давайте построим серию и посмотрим, что в ней содержится.

plt.figure(figsize=(10, 6))
plot_series(time, series)

Подготовка набора данных

мы должны разделить наши временные ряды на период обучения и проверки.

split_time = 3000
time_train = time[:split_time]
x_train = series[:split_time]
time_valid = time[split_time:]
x_valid = series[split_time:]

время разделения 3000 означает, что от 0 до 3000 будет для обучения, а 3000 до конца - для проверки.

Теперь мы определим функцию для создания оконного набора данных. В наборе данных окна предыдущие n значений можно рассматривать как входные функции. А текущее значение с любой меткой времени - это метка вывода. набор данных окна состоит из фиксированного размера окна.

def windowed_dataset(series, window_size, batch_size, shuffle_buffer):
 series = tf.expand_dims(series, axis=-1)
 ds = tf.data.Dataset.from_tensor_slices(series)
 ds = ds.window(window_size + 1, shift=1, drop_remainder=True)
 ds = ds.flat_map(lambda w: w.batch(window_size + 1))
 ds = ds.shuffle(shuffle_buffer)
 ds = ds.map(lambda w: (w[:-1], w[1:]))
 return ds.batch(batch_size).prefetch(1)

теперь давайте создадим набор обучающих данных с помощью функции windowed_dataset

tf.keras.backend.clear_session()
tf.random.set_seed(51)
np.random.seed(51)
shuffle_buffer_size = 1000
window_size = 64
batch_size = 256
train_set = windowed_dataset(x_train, window_size, batch_size, shuffle_buffer_size)
print(x_train.shape)

Создание модели

tf.keras.backend.clear_session()
model = tf.keras.models.Sequential([
 tf.keras.layers.Conv1D(filters=60, kernel_size=5,
 strides=1, padding=”causal”,
 activation=”relu”,
 input_shape=[None, 1]),
 tf.keras.layers.LSTM(60, return_sequences=True),
 tf.keras.layers.LSTM(60, return_sequences=True),
 tf.keras.layers.Dense(30, activation=”relu”),
 tf.keras.layers.Dense(10, activation=”relu”),
 tf.keras.layers.Dense(1),
 tf.keras.layers.Lambda(lambda x: x * 400)
])
model.summary()

Краткое изложение модели будет выглядеть так:

Как видите, эта модель состоит из слоя свертки, слоя LSTM и плотного слоя. Если вы не знаете, что именно делают эти слои, не волнуйтесь, очень скоро я создам отдельную статью, описывающую функции всех различных типов слоев.

Теперь давайте скомпилируем и обучим модель.

optimizer = tf.keras.optimizers.SGD(lr=1e-5, momentum=0.9)
model.compile(loss=tf.keras.losses.Huber(),
 optimizer=optimizer,
 metrics=[“mae”])
history = model.fit(train_set,epochs=500)

и обучение начинается… ..

тренировка займет время, так что расслабьтесь и расслабьтесь.

Оценка модели

Теперь мы посмотрим, насколько хороша наша модель, увидев потери при обучении

# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -
# Retrieve a list of list results on training and test data
# sets for each training epoch
# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -
loss=history.history[‘loss’]
epochs=range(len(loss)) # Get number of epochs
# — — — — — — — — — — — — — — — — — — — — — — — — 
# Plot training and validation loss per epoch
# — — — — — — — — — — — — — — — — — — — — — — — — 
plt.plot(epochs, loss, ‘r’)
plt.title(‘Training loss’)
plt.xlabel(“Epochs”)
plt.ylabel(“Loss”)
plt.legend([“Loss”])
plt.figure()
zoomed_loss = loss[200:]
zoomed_epochs = range(200,500)
# — — — — — — — — — — — — — — — — — — — — — — — — 
# Plot training and validation loss per epoch
# — — — — — — — — — — — — — — — — — — — — — — — — 
plt.plot(zoomed_epochs, zoomed_loss, ‘r’)
plt.title(‘Training loss’)
plt.xlabel(“Epochs”)
plt.ylabel(“Loss”)
plt.legend([“Loss”])
plt.figure()

графики должны быть похожи на это.

Второй сюжет - это просто увеличенная последняя часть первого сюжета. Благодаря этому мы можем получить четкий статус обучения за последние 300 эпох.

Давай предскажем

Теперь, когда ваша модель обучена, будьте готовы видеть будущее.

мы создадим функцию, которая поможет нам сделать прогноз.

def model_forecast(model, series, window_size):
 ds = tf.data.Dataset.from_tensor_slices(series)
 ds = ds.window(window_size, shift=1, drop_remainder=True)
 ds = ds.flat_map(lambda w: w.batch(window_size))
 ds = ds.batch(32).prefetch(1)
 forecast = model.predict(ds)
 return forecast

теперь мы будем использовать эту функцию для прогноза.

rnn_forecast = model_forecast(model, series[…, np.newaxis], window_size)
rnn_forecast = rnn_forecast[split_time — window_size:-1, -1, 0]
plt.figure(figsize=(10, 6))
plot_series(time_valid, x_valid)
plot_series(time_valid, rnn_forecast)

Синий - это исходная серия, а оранжевый - прогнозируемая, результаты выглядят довольно неплохо😃.

Надеюсь, вы понимаете, как делать прогнозирование временных рядов с помощью TensorFlow.

пожалуйста, дайте свои отзывы или предложения. Спасибо🙂