File size: 5,430 Bytes
ebf57c0
4eaa6d3
 
 
 
 
 
 
 
ebf57c0
 
 
 
 
 
4eaa6d3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ebf57c0
 
4eaa6d3
 
ebf57c0
 
4eaa6d3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ebf57c0
4eaa6d3
 
 
 
ebf57c0
4eaa6d3
 
ebf57c0
4eaa6d3
 
 
 
ebf57c0
4eaa6d3
 
ebf57c0
4eaa6d3
 
ebf57c0
4eaa6d3
 
ebf57c0
4eaa6d3
 
 
ebf57c0
4eaa6d3
 
 
ebf57c0
4eaa6d3
 
ebf57c0
4eaa6d3
 
 
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import yfinance as yf
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM, GRU
from statsmodels.tsa.arima.model import ARIMA
from kerastuner.tuners import RandomSearch

# Function to load stock data using yfinance
def get_stock_data(symbol, start_date, end_date):
    stock_data = yf.download(symbol, start=start_date, end=end_date)
    return stock_data['Close']

# Function to normalize data and prepare it for LSTM/GRU
def prepare_data(data):
    scaler = MinMaxScaler(feature_range=(0, 1))
    scaled_data = scaler.fit_transform(data.values.reshape(-1, 1))
    return scaled_data, scaler

# Function to create LSTM model
def create_lstm_model(input_shape, hp):
    model = Sequential()
    model.add(LSTM(units=hp.Int('units', min_value=32, max_value=512, step=32),
                   return_sequences=True, input_shape=input_shape))
    model.add(LSTM(units=hp.Int('units', min_value=32, max_value=512, step=32),
                   return_sequences=True))
    model.add(LSTM(units=hp.Int('units', min_value=32, max_value=512, step=32)))
    model.add(Dense(units=1))
    model.compile(optimizer='adam', loss='mean_squared_error')
    return model

# Function to create GRU model
def create_gru_model(input_shape, hp):
    model = Sequential()
    model.add(GRU(units=hp.Int('units', min_value=32, max_value=512, step=32),
                   return_sequences=True, input_shape=input_shape))
    model.add(GRU(units=hp.Int('units', min_value=32, max_value=512, step=32),
                   return_sequences=True))
    model.add(GRU(units=hp.Int('units', min_value=32, max_value=512, step=32)))
    model.add(Dense(units=1))
    model.compile(optimizer='adam', loss='mean_squared_error')
    return model

# Function to create ARIMA model
def create_arima_model(data, hp):
    # The order parameter is the hyperparameter to be tuned
    p = hp.Int('p', min_value=1, max_value=5, step=1)
    d = hp.Int('d', min_value=0, max_value=1, step=1)
    q = hp.Int('q', min_value=1, max_value=5, step=1)
    
    model = ARIMA(data, order=(p, d, q))
    return model

# Function to create Keras Tuner RandomSearch
def create_tuner(model_builder, objective):
    return RandomSearch(model_builder,
                        objective=objective,
                        max_epochs=10,
                        factor=3,
                        directory='keras_tuner_logs',
                        project_name='stock_price_forecasting')

# Function to fit ARIMA model using Keras Tuner
def tune_arima_model(data, tuner, hp):
    # The ARIMA model is fit differently than neural networks
    model = tuner.oracle.get_best_trials(1)[0].hyperparameters.values
    order = (model['p'], model['d'], model['q'])

    # Fit ARIMA model
    arima_model = ARIMA(data, order=order)
    arima_model_fit = arima_model.fit()

    # Make predictions
    forecast_steps = tuner.oracle.get_best_trials(1)[0].metrics.values['steps']
    arima_forecast = arima_model_fit.get_forecast(steps=forecast_steps)
    arima_predictions = arima_forecast.predicted_mean

    return arima_predictions

# Function to create ensemble forecast by averaging predictions
def ensemble_forecast(predictions_list):
    return pd.DataFrame(predictions_list).mean(axis=0)

# Load stock data
symbol = 'AAPL'  # Replace with the desired stock symbol
start_date = '2021-01-01'
end_date = '2022-01-01'
stock_prices = get_stock_data(symbol, start_date, end_date)

# Define input shape for LSTM
input_shape = (60, 1)

# Objective for Keras Tuner
def objective(hp):
    lstm_model = create_lstm_model(input_shape, hp)
    lstm_model.fit(x_train, y_train, epochs=10, validation_split=0.2)
    loss = lstm_model.evaluate(x_test, y_test)
    return loss

# Create Keras Tuner for LSTM
tuner_lstm = create_tuner(create_lstm_model, objective)

# Split data into training and testing sets for LSTM
scaled_data, scaler = prepare_data(stock_prices)
input_data = scaled_data.reshape(-1, 1)

train_size = int(len(input_data) * 0.80)
train_data, test_data = input_data[0:train_size, :], input_data[train_size:len(input_data), :]

x_train, y_train = [], []
for i in range(60, len(train_data)):
    x_train.append(train_data[i - 60:i, 0])
    y_train.append(train_data[i, 0])

x_train, y_train = np.array(x_train), np.array(y_train)
x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))

x_test, y_test = [], []
for i in range(60, len(test_data)):
    x_test.append(test_data[i - 60:i, 0])
    y_test.append(test_data[i, 0])

x_test, y_test = np.array(x_test), np.array(y_test)
x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], 1))

# Tune LSTM model
tuner_lstm.search(x_train, y_train, epochs=10, validation_split=0.2)

# Retrieve the best LSTM model
best_lstm_model = tuner_lstm.get_best_models(num_models=1)[0]

# Make LSTM predictions
lstm_predictions = best_lstm_model.predict(x_test)
lstm_predictions = scaler.inverse_transform(lstm_predictions)

# Tune ARIMA model
tuner_arima = create_tuner(create_arima_model, 'val_loss')
tuner_arima.search(stock_prices, epochs=10, validation_split=0.2)

# Retrieve the best ARIMA model
arima_predictions = tune_arima_model(stock_prices, tuner_arima, x_test, y_test)

# Tune GRU model (similar to LSTM tuning)
tuner_gru = create_tuner(create_gru_model, objective)
tuner