【问题标题】:How do I predict the near future value correctly in python?如何在 python 中正确预测近期的值?
【发布时间】:2021-03-06 07:57:42
【问题描述】:

我需要帮助,我目前正在将我的 LSTM 模型部署在 flask python 中,我正在尝试将我的结果加载到新的 csv 文件中,但最终,它加载了重复的结果,所以我不知道哪一行代码是做错了,请调整我并给我一些提示非常感谢!

模型.py

import numpy as np
from math import sqrt
from numpy import concatenate
from matplotlib import pyplot
from pandas import read_csv
from pandas import DataFrame
from pandas import concat
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout
from pickle import dump




def create_dataset(dataset, look_back=1):
    dataX, dataY = [], []
    for i in range(len(dataset)-look_back-1):
        a = dataset[i:(i+look_back), 0]
        dataX.append(a)
        dataY.append(dataset[i + look_back, 0])
    return np.array(dataX), np.array(dataY)
    
# load dataset
np.random.seed(7)
# load the dataset
dataframe = read_csv('Sales.csv', usecols=[1], engine='python', skipfooter=3)
dataset = dataframe.values
dataset = dataset.astype('float32')
# normalize the dataset
scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)
# split into train and test sets
train_size = int(len(dataset) * 0.67)
test_size = len(dataset) - train_size
train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]
# reshape into X=t and Y=t+1
look_back = 1
train_X, train_Y = create_dataset(train, look_back)
test_X, test_Y = create_dataset(test, look_back)
# reshape input to be [samples, time steps, features]
train_X = np.reshape(train_X, (train_X.shape[0], 1, train_X.shape[1]))
test_X = np.reshape(test_X, (test_X.shape[0], 1, test_X.shape[1]))



model = Sequential()
model.add(LSTM(128, return_sequences=True ,input_shape=(train_X.shape[1], train_X.shape[2])))
model.add(Dropout(0.2))
model.add(LSTM(64))


model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')
history = model.fit(train_X, train_Y, epochs=100, batch_size=128, validation_data=(test_X, test_Y), verbose=2, shuffle=False)


#save the model
model.save('model.h5')

app.py

from flask import Flask, make_response, request, render_template
from pandas import DataFrame
import io
from pandas import datetime
from io import StringIO
import csv
import pandas as pd
import numpy as np
import pickle
import os
from keras.models import load_model
from sklearn.preprocessing import MinMaxScaler
import datetime
from datetime import timedelta, datetime
from dateutil.relativedelta import relativedelta

app = Flask(__name__)

@app.route('/')
def form():
    return """
        <html>
            <body>
                <h1>Let's TRY to Predict..</h1>
                </br>
                </br>
                <p> Insert your CSV file and then download the Result
                <form action="/transform" method="post" enctype="multipart/form-data">
                    <input type="file" name="data_file" class="btn btn-block"/>
                    </br>
                    </br>
                    <button type="submit" class="btn btn-primary btn-block btn-large">Predict</button>
                </form>

                 <div class="ct-chart ct-perfect-fourth"></div>

            </body>
        </html>
    """

@app.route('/transform', methods=["POST"])
def transform_view():
 if request.method == 'POST':
    f = request.files['data_file']
    if not f:
        return "No file"

    
    stream = io.StringIO(f.stream.read().decode("UTF8"), newline=None)
    csv_input = csv.reader(stream)
    stream.seek(0)
    result = stream.read()
    df = pd.read_csv(StringIO(result), usecols=[1])
    
    #extract month value
    df2 = pd.read_csv(StringIO(result))
    matrix2 = df2[df2.columns[0]].to_numpy()
    list1 = matrix2.tolist()
     
    # load the model from disk
    model = load_model('model.h5')
    dataset = df.values
    dataset = dataset.astype('float32')
    scaler = MinMaxScaler(feature_range=(0, 1))
    dataset = scaler.fit_transform(dataset)
    dataset = np.reshape(dataset, (dataset.shape[0], 1, dataset.shape[1]))
    predict = model.predict(dataset)
    transform = scaler.inverse_transform(predict)

    X_FUTURE = 100
    transform = np.array([])
    last = dataset[-1]
    for i in range(X_FUTURE):
        curr_prediction = model.predict(np.array([last]))
        last = np.concatenate([last[1:], curr_prediction])
        transform = np.concatenate([transform, curr_prediction[0]])
        
    transform = scaler.inverse_transform([transform])[0]

    dicts = []
    curr_date = pd.to_datetime(list1[-1])
    for i in range(X_FUTURE):
        curr_date = curr_date +  relativedelta(month=1)
        dicts.append({'Predictions':transform[i], "Month": curr_date})


    new_data = pd.DataFrame(dicts).set_index("Month")
    ##df_predict = pd.DataFrame(transform, columns=["predicted value"])
          

    response = make_response(new_data.to_csv(index = True, encoding='utf8'))
    response.headers["Content-Disposition"] = "attachment; filename=result.csv"
    return response

if __name__ == "__main__":
    app.run(debug=True, port = 9000, host = "localhost")

这是加载到新 csv 文件的结果

【问题讨论】:

  • 在你的 LSTM 中重复预测是正确答案的情况吗?可能你的 LSTM 就是这样训练出来的,而且代码没有错误。
  • 哦,真的,但日期不会一样吧?
  • 我也分享我的模型
  • @Arty 请帮帮我~
  • Pandas 无法从 dateutil 包中识别 relativedelta,这就是为什么将它添加到 date 会产生错误结果的原因。请尝试这样做curr_date = curr_date + pd.DateOffset(months = 1),这将在您的月份列中生成正确的不同日期。

标签: python flask lstm web-deployment prediction


【解决方案1】:

我认为您的结果正确(即重复),您的 LSTM 训练正确(但准确率可能较低),重复不是错误,而是正确答案。

关于重复的 Month 列值 - 原因是 Pandas 无法从 dateutil 包中识别 relativedelta,因此将其添加到 date 会产生错误的结果。请尝试这样做curr_date = curr_date + pd.DateOffset(months = 1),这将在您的月份列中生成正确的不同日期。

【讨论】:

    猜你喜欢
    • 2021-07-11
    • 2020-04-15
    • 2019-09-29
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 2020-08-19
    • 2018-12-15
    相关资源
    最近更新 更多