为什么我预测的LSTM模型左移并且准确度为0

问题描述 投票:0回答:1

我看过其他一些帖子,其中的 LSTM 模型发生了变化,但是在研究它们时我没有找到解决方案。我在 Sequential_Input 函数中切片数据的方式有问题吗?有没有人有什么建议?而且奇怪的是,精度始终为零,而不是某种更随机地收敛到 1。

下面是模型的代码和图像。

import pandas as pd
import utilities
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import sklearn as sk
import pathlib
from ItemIdEnum import item
from sklearn.preprocessing import MinMaxScaler, StandardScaler
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_percentage_error
from sklearn.model_selection import train_test_split
from sklearn.model_selection import TimeSeriesSplit
import seaborn as sns
from statsmodels.graphics.gofplots import qqplot
from scipy.stats import norm, uniform


def Sequential_Input_LSTM(df, input_sequence):
    df_np = df.to_numpy()
    X = []
    y = []
    
    for i in range(len(df_np) - input_sequence):
        row = [a for a in df_np[i:i + input_sequence]]
        X.append(row)
        label = df_np[i + input_sequence]
        y.append(label)
        
    return np.array(X), np.array(y)

def createLSTM(itemName: str, data: pd.DataFrame, n_input: int, n_features: int, epochs: int, batch_size: int, save: bool, savePlot: bool) -> None:
    cwd = pathlib.Path().cwd()
    path = cwd.joinpath("LSTM_models/"+itemName)
    try:
        path.mkdir(parents=True, exist_ok=False)
    except FileExistsError as e:
        print(e)
        pass
    
    early_stop = tf.keras.callbacks.EarlyStopping(monitor = 'loss', patience = 5)
    data = utilities.convertFromZuluTime(data)
    data = utilities.removeOutliers(data)

    data = data.drop(columns=['range','universe_id','http_last_modified'])
    data['issued'] = pd.to_datetime(data['issued'],origin='unix',unit='D')
    date_time = pd.to_datetime(data['issued'])
    data.set_index('issued',inplace=True)
    plt.figure()
    data['price'].hist()
    plt.savefig(f'{path/itemName}_predata_standarize_hist.png')
    plt.figure()
    data['price'].plot(ylabel='Price')
    plt.savefig(f'{path/itemName}_predata_standarize_plot.png')
    xFeat = data
   
    sc =MinMaxScaler()
    X_ft = sc.fit_transform(xFeat.values)
    X_ft = pd.DataFrame(X_ft, index=xFeat.index, columns=xFeat.columns)
    plt.figure()
    data['price'].hist()
    plt.savefig(f'{path/itemName}_postdata_standarize_hist.png')
    plt.figure()
    data['price'].plot()
    plt.savefig(f'{path/itemName}_postdata_standarize_plot.png')
    n_input = n_input  

    df_min_model_data = X_ft['price']

    X, y = Sequential_Input_LSTM(df_min_model_data, n_input)
    trainSplit = 0.8
    splitIDX = int(np.floor(len(X)*trainSplit))
    dateIndex = date_time
    XTrain, xTest = X[:splitIDX], X[splitIDX:]
    yTrain, yTest = y[:splitIDX], y[splitIDX:]
    XTrainDates, xTestDates = dateIndex[:splitIDX], dateIndex[splitIDX+10:]


    n_features = n_features

    lstm = tf.keras.models.Sequential()
    lstm.add(tf.keras.layers.InputLayer((n_input,n_features)))
    lstm.add(tf.keras.layers.LSTM(100,return_sequences=True,activation='relu'))
    lstm.add(tf.keras.layers.Dropout(0.5))
    lstm.add(tf.keras.layers.LSTM(100,return_sequences=True,activation='relu'))
    lstm.add(tf.keras.layers.LSTM(50))
    lstm.add(tf.keras.layers.Dense(50, activation='relu', kernel_initializer='he_normal'))
    lstm.add(tf.keras.layers.Dense(1))
    lstm.compile(loss='mean_squared_error',optimizer='adam', metrics=[tf.keras.metrics.RootMeanSquaredError(),tf.keras.metrics.Accuracy()])
    lstm.summary()

    history = lstm.fit(XTrain,yTrain,epochs=epochs,batch_size=batch_size,shuffle=False,validation_data=(xTest,yTest), callbacks = [early_stop] )
    lstm.evaluate(xTest,yTest,verbose=0) # type: ignore
    if save == True:
        tf.keras.models.save_model(lstm, somePath")
    
    test_predictions1 = lstm.predict(xTest).flatten()

    X_test_list = []
    for i in range(len(xTest)):
        X_test_list.append(xTest[i][0])
    
    test_predictions_df1 = pd.DataFrame({'X_test':list(X_test_list), 
                                    'LSTM Prediction':list(test_predictions1)})

    test_predictions_df1.plot(title=f'{itemName} LSTM Prediction vs Actual',ylabel='Price')
    plt.show()
    
    if savePlot == True:
        plt.figure()
        test_predictions_df1.plot(title=f'{itemName} LSTM Prediction vs Actual',ylabel='Price')
        plt.savefig(f'{path/itemName}_prediction_plot.png')

        print(history.history.keys())
        plt.figure()
        plt.plot(history.history['loss'],label='loss')
        plt.plot(history.history['val_loss'],label='val_loss')
        plt.title('loss')
        plt.ylabel('loss')
        plt.xlabel('epoch')
        plt.legend()
        plt.savefig(f'{path/itemName}_loss_plot.png')
        plt.figure()
        plt.plot(history.history['accuracy'],label='accuracy')
        plt.plot(history.history['val_accuracy'],label='val_accuracy')
        plt.title('accuracy')
        plt.ylabel('accuracy_values')
        plt.xlabel('epoch')
        plt.legend()
        plt.savefig(f'{path/itemName}_accuracy_plot.png')
        plt.figure()
        plt.plot(history.history['root_mean_squared_error'],label='root_mean_squared_error')
        plt.plot(history.history['val_root_mean_squared_error'],label='val_root_mean_squared_error')
        plt.title('root_mean_squared_error')
        plt.ylabel('root_mean_squared_values')
        plt.xlabel('epoch')
        plt.legend()
        plt.savefig(f'{path/itemName}_root_mean_squared_error_plot.png')

python tensorflow machine-learning lstm
1个回答
0
投票

看起来这是一个预测问题。因为它是按顺序获取数据,所以模型会通过预测来响应脉冲峰值,而不是学习预测它们。看起来这与您的模型所得到的最接近,并且您的图可能就是该数据上的最小损失。

您可以尝试 MSE、MAPE 等,而不是准确度(在 TensorFlow/keras 中是一个分类指标),这会更接近我认为您正在寻找的东西。

© www.soinside.com 2019 - 2024. All rights reserved.