File size: 4,216 Bytes
907690e
49cb95b
 
 
 
 
 
 
 
68aa26c
907690e
 
49cb95b
 
 
 
 
 
 
 
 
907690e
68aa26c
49cb95b
68aa26c
907690e
49cb95b
 
68aa26c
907690e
49cb95b
 
 
68aa26c
907690e
49cb95b
 
 
 
 
68aa26c
907690e
49cb95b
 
 
 
 
68aa26c
907690e
49cb95b
 
68aa26c
907690e
49cb95b
 
 
 
68aa26c
907690e
49cb95b
 
68aa26c
907690e
49cb95b
 
 
 
 
 
68aa26c
907690e
 
68aa26c
 
907690e
 
 
 
 
68aa26c
907690e
 
68aa26c
907690e
 
 
 
 
 
 
 
 
 
 
68aa26c
907690e
 
 
 
 
 
 
 
 
 
 
 
49cb95b
907690e
 
 
 
49cb95b
907690e
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import streamlit as st
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
import tensorflow as tf
import io

# 函數定義
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)

def train_and_predict(file):
    # 載入和預處理數據
    dataframe = pd.read_csv(file, usecols=[1], engine='python')
    dataset = dataframe.values.astype('float32')
    
    # 正規化數據集
    scaler = MinMaxScaler(feature_range=(0, 1))
    dataset = scaler.fit_transform(dataset)
    
    # 分割訓練集和測試集
    train_size = int(len(dataset) * 0.67)
    test_size = len(dataset) - train_size
    train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]
    
    # 重塑為 X=t 和 Y=t+1
    look_back = 1
    trainX, trainY = create_dataset(train, look_back)
    testX, testY = create_dataset(test, look_back)
    trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1]))
    testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1]))
    
    # 創建和訓練 LSTM 網絡
    model = Sequential()
    model.add(LSTM(4, input_shape=(1, look_back)))
    model.add(Dense(1))
    model.compile(loss='mean_squared_error', optimizer='adam')
    model.fit(trainX, trainY, epochs=50, batch_size=1, verbose=0)
    
    # 進行預測
    trainPredict = model.predict(trainX)
    testPredict = model.predict(testX)
    
    # 反轉預測
    trainPredict = scaler.inverse_transform(trainPredict)
    trainY = scaler.inverse_transform([trainY])
    testPredict = scaler.inverse_transform(testPredict)
    testY = scaler.inverse_transform([testY])
    
    # 計算 RMSE
    trainScore = np.sqrt(mean_squared_error(trainY[0], trainPredict[:,0]))
    testScore = np.sqrt(mean_squared_error(testY[0], testPredict[:,0]))
    
    # 準備繪圖數據
    trainPredictPlot = np.empty_like(dataset)
    trainPredictPlot[:, :] = np.nan
    trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
    testPredictPlot = np.empty_like(dataset)
    testPredictPlot[:, :] = np.nan
    testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict
    
    return scaler.inverse_transform(dataset), trainPredictPlot, testPredictPlot, trainScore, testScore

st.title("LSTM Stock Price Prediction")

uploaded_file = st.file_uploader("Choose a CSV file", type="csv")

if uploaded_file is not None:
    # 讀取文件並進行預測
    original_data, train_predict, test_predict, train_score, test_score = train_and_predict(uploaded_file)
    
    # 顯示結果
    st.subheader("Prediction Results")
    
    # 繪製圖表
    fig, ax = plt.subplots(figsize=(12, 6))
    ax.plot(original_data, label='Original Data', color='blue')
    ax.plot(train_predict, label='Training Predictions', linestyle='--', color='green')
    ax.plot(test_predict, label='Test Predictions', linestyle='--', color='red')
    ax.set_xlabel('Time')
    ax.set_ylabel('Stock Price')
    ax.set_title('Original Data and Predictions')
    ax.legend()
    ax.grid(True, linestyle='--', alpha=0.7)
    st.pyplot(fig)
    
    # 顯示評分
    col1, col2 = st.columns(2)
    with col1:
        st.metric("Train Score (RMSE)", f"{train_score:.2f}")
    with col2:
        st.metric("Test Score (RMSE)", f"{test_score:.2f}")

else:
    st.info("Please upload a CSV file to start the prediction.")

st.markdown("""
This application uses an LSTM (Long Short-Term Memory) neural network to predict stock prices based on historical data.

To use:
1. Upload a CSV file containing historical stock price data.
2. The app will train an LSTM model on this data and make predictions.
3. You'll see a graph showing the original data and predictions, along with RMSE scores for training and test sets.

Note: The CSV file should have the stock prices in the second column.
""")