时间序列卷积神经网络(TCN)是一种用于处理时间序列数据的深度学习模型
1. TCN优点
相较于传统的循环神经网络(RNN)和长短期记忆网络(LSTM),TCN 具有以下优点:
- 长期依赖性建模能力: TCN 使用了带有不同扩张率(dilation rate)的卷积层,使得网络可以捕捉到序列中不同尺度的模式和长期依赖性,从而能够更好地建模长期的时间相关性
- 参数效率: 相对于循环神经网络(RNN)和长短期记忆网络(LSTM)等传统的递归结构,TCN 中的卷积操作可以高效地并行计算,减少了参数数量和计算复杂度,从而加速了训练和推理过程
- 平移不变性: TCN 使用的卷积操作是平移不变的,即不论输入序列的时间位置如何改变,模型学习到的特征仍然有效,这使得模型更加稳健,能够更好地适应序列数据中的时间偏移和变化
- 易于并行化: TCN 中的卷积操作可以非常有效地并行计算,因此在现代硬件(如 GPU)上能够充分发挥并行计算的优势,加速训练过程
- 可扩展性: TCN 模型结构相对灵活,可以根据任务的需求进行简单的修改和扩展。例如,通过调整网络的深度、宽度、卷积核大小和扩张率等超参数,可以适应不同的时间序列数据和任务
- 不需要状态存储: 与传统的 RNN 和 LSTM 不同,TCN 不需要显式地存储和更新隐藏状态,这减少了内存占用并简化了模型的实现和调试过程
2. TCN Github网址
https://github.com/philipperemy/keras-tcn
3 . 代码实现
3.1 数据展示
import pandas as pd
import numpy as np
df = pd.read_excel('数据.xlsx',index_col=0, parse_dates=['数据时间'])
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(15, 5))
plt.plot(df['总有功功率(kw)'], label='原始数据', color='g', alpha=0.3)
plt.title('时序图')
plt.grid(True)
plt.legend()
plt.show()
3.2 数据形状处理
# 0-1标准化
df_max = np.max(df['总有功功率(kw)'])
df_min = np.min(df['总有功功率(kw)'])
df_bz = (df['总有功功率(kw)']-df_min)/(df_max-df_min)
def prepare_data(data, win_size):
X = [] # 用于存储输入特征的列表
y = [] # 用于存储目标值的列表
# 遍历数据,形成样本窗口
for i in range(len(data) - win_size):
temp_x = data[i:i + win_size] # 提取窗口大小范围内的输入特征
temp_y = data[i + win_size] # 提取对应的目标值
X.append(temp_x)
y.append(temp_y)
# 转换列表为 NumPy 数组
X = np.asarray(X)
y = np.asarray(y)
# 将数据维度调整为适用于TCN模型的形式
X = np.expand_dims(X, axis=-1)
return X, y
win_size = 12
X, y = prepare_data(df_bz.values, win_size)
# 假设X和y是已经准备好的适用于TCN模型的输入特征和目标值矩阵
train_size = int(len(X) * 0.7) # 训练集占总样本数的70%
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]
# 打印训练集和测试集的形状
print("训练集形状:", X_train.shape, y_train.shape)
print("测试集形状:", X_test.shape, y_test.shape)
代码对时间序列数据进行0-1标准化处理,并将其转换为适用于TCN模型的训练数据格式,并最终划分为训练集和测试集,在这里数据集为单序列数据,时间窗口为12
3.3 LSTM模型建立
lstm模型代码参考往期文章 基于VMD分解的VMD-LSTM时间序列预测模型实现,大力提升预测精度! 其中存在对于该数据的lstm模型建立代码
3.4 简单卷积神经网络模型建立
import tensorflow.compat.v1 as tf
from tensorflow.keras.layers import Conv1D, MaxPooling1D, Flatten, Dense
from tensorflow.keras.models import Sequential
# 构建卷积神经网络
model = Sequential()
model.add(Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(win_size, 1)))
model.add(MaxPooling1D(pool_size=2))
model.add(Conv1D(filters=128, kernel_size=3, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(10, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# 编译和训练模型
model.compile(optimizer='adam', loss='mse')
history = model.fit(X_train, y_train, epochs=100, batch_size=32, validation_data=(X_test, y_test))
# 可视化训练集和测试集的损失
import matplotlib.pyplot as plt
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()
from sklearn import metrics
y_pred = model.predict(X_test)
# 计算均方误差(MSE)
mse = metrics.mean_squared_error(y_test, np.array([i for arr in y_pred for i in arr]))
# 计算均方根误差(RMSE)
rmse = np.sqrt(mse)
# 计算平均绝对误差(MAE)
mae = metrics.mean_absolute_error(y_test, np.array([i for arr in y_pred for i in arr]))
from sklearn.metrics import r2_score # 拟合优度
r2 = r2_score(y_test, np.array([i for arr in y_pred for i in arr]))
print("均方误差 (MSE):", mse)
print("均方根误差 (RMSE):", rmse)
print("平均绝对误差 (MAE):", mae)
print("拟合优度:", r2)
模型评价指标,模型指标解读参考往期文章 回归任务常见评价指标解读以及Python实现
def predict_future_values(model, sequence, future_steps):
prediction_results = []
for _ in range(future_steps):
# 检查序列的维度并调整形状
if len(sequence.shape) == 1:
sequence = sequence.reshape(1, sequence.shape[0], 1)
elif len(sequence.shape) == 2:
sequence = sequence.reshape(1, sequence.shape[0], sequence.shape[1])
# 对当前序列进行预测
next_day_prediction = model.predict(sequence)
# 将预测结果加入到结果列表中
prediction_results.append(next_day_prediction[0, 0])
# 更新序列,舍弃第一个时间步,将预测结果加入序列末尾
sequence = np.append(sequence[:, 1:, :], next_day_prediction.reshape(1, 1, 1), axis=1)
return prediction_results
sequence = X_test[-1]
future_predictions = predict_future_values(model, sequence, 10)
series = np.array(future_predictions)*(df_max-df_min)+df_min
plt.figure(figsize=(15,4), dpi =300)
plt.plot(y_test*(df_max-df_min)+df_min, color = 'c', label = '每日实际功率波动曲线')
plt.plot(y_pred*(df_max-df_min)+df_min, color = 'r', label = '预测每日功率波动曲线')
plt.plot(range(len(y_pred), len(y_pred)+len(series)), series, color = 'b', label = '向后预测30天')
plt.title('每日实际功率波动与预测每日功率波动比对图')
plt.grid(True)
plt.xlabel('时间')
plt.ylabel('总有功功率(kw)')
plt.legend()
plt.show()
根据训练的模型和序列数据进行未来值的预测,最后将预测结果与实际值进行可视化对比
3.5 TCN模型建立
from tcn import TCN
model_tcn = Sequential()
model_tcn.add(TCN(nb_filters=64, kernel_size=6, activation='relu', input_shape=(win_size, 1), dilations=[1, 2, 4, 8, 16]))
model_tcn.add(Flatten())
model_tcn.add(Dense(32, activation='relu'))
model_tcn.add(Dense(10, activation='relu'))
model_tcn.add(Dense(1, activation='sigmoid'))
# 编译和训练模型
model_tcn.compile(optimizer='adam', loss='mse')
history = model_tcn.fit(X_train, y_train, epochs=100, batch_size=32, validation_data=(X_test, y_test))
# 可视化训练集和测试集的损失
import matplotlib.pyplot as plt
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()
model\_tcn.summary()
from sklearn import metrics
y_pred = model_tcn.predict(X_test)
# 计算均方误差(MSE)
mse = metrics.mean_squared_error(y_test, np.array([i for arr in y_pred for i in arr]))
# 计算均方根误差(RMSE)
rmse = np.sqrt(mse)
# 计算平均绝对误差(MAE)
mae = metrics.mean_absolute_error(y_test, np.array([i for arr in y_pred for i in arr]))
from sklearn.metrics import r2_score # 拟合优度
r2 = r2_score(y_test, np.array([i for arr in y_pred for i in arr]))
print("均方误差 (MSE):", mse)
print("均方根误差 (RMSE):", rmse)
print("平均绝对误差 (MAE):", mae)
print("拟合优度:", r2)
future_predictions = predict_future_values(model_tcn, sequence, 10)
series = np.array(future_predictions)*(df_max-df_min)+df_min
plt.figure(figsize=(15,4), dpi =300)
plt.plot(y_test*(df_max-df_min)+df_min, color = 'c', label = '每日实际功率波动曲线')
plt.plot(y_pred*(df_max-df_min)+df_min, color = 'r', label = '预测每日功率波动曲线')
plt.plot(range(len(y_pred), len(y_pred)+len(series)), series, color = 'b', label = '向后预测10天')
plt.title('每日实际功率波动与预测每日功率波动比对图')
plt.grid(True)
plt.xlabel('时间')
plt.ylabel('总有功功率(kw)')
plt.legend()
plt.show()
3.6 模型对比
TCN模型相较于CNN和LSTM模型在均方误差、均方根误差、平均绝对误差和拟合优度等评价指标上均表现更好
4 . 往期推荐
基于VMD分解的VMD-CNN-LSTM时间序列预测模型实现
基于VMD分解的VMD-LSTM时间序列预测模型实现,大力提升预测精度!
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~