saneowl's picture
Update app.py
0351882 verified
import gradio as gr
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import yfinance as yf
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
import plotly.graph_objects as go
def fetch_ethereum_data():
"""
Fetch historical Ethereum price data using yfinance.
Returns DataFrame with datetime index and price information.
The data is sampled hourly for the past week.
"""
eth_ticker = yf.Ticker("ETH-USD")
# Get hourly data for the past week
hist_data = eth_ticker.history(period="7d", interval="1h")
# Keep the datetime index and Close price
return hist_data[['Close']]
def prepare_data(data, sequence_length=24):
"""
Prepare data for LSTM model by creating sequences and scaling.
Args:
data: DataFrame with price data and datetime index
sequence_length: Number of time steps to use for prediction (default: 24 hours)
"""
# Scale the data
scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(data['Close'].values.reshape(-1, 1))
# Create sequences for training
X, y = [], []
for i in range(sequence_length, len(scaled_data)):
X.append(scaled_data[i-sequence_length:i, 0])
y.append(scaled_data[i, 0])
X = np.array(X)
y = np.array(y)
# Reshape X for LSTM input
X = X.reshape(X.shape[0], X.shape[1], 1)
return X, y, scaler
def create_model(sequence_length):
"""
Create and compile LSTM model for time series prediction.
Uses a two-layer LSTM architecture followed by dense layers.
"""
model = Sequential([
LSTM(50, return_sequences=True, input_shape=(sequence_length, 1)),
LSTM(50, return_sequences=False),
Dense(25),
Dense(1)
])
model.compile(optimizer='adam', loss='mse')
return model
def predict_future_prices(model, last_sequence, scaler, days=7):
"""
Predict future prices using the trained model.
Args:
model: Trained LSTM model
last_sequence: Last sequence of known prices
scaler: Fitted MinMaxScaler
days: Number of days to predict (default: 7)
"""
future_predictions = []
current_sequence = last_sequence.copy()
# Convert days to hours since we're using hourly data
hours = days * 24
for _ in range(hours):
# Predict next price
scaled_prediction = model.predict(current_sequence.reshape(1, -1, 1), verbose=0)
# Inverse transform to get actual price
prediction = scaler.inverse_transform(scaled_prediction)[0][0]
future_predictions.append(prediction)
# Update sequence for next prediction
current_sequence = np.roll(current_sequence, -1)
current_sequence[-1] = scaled_prediction
return future_predictions
def create_prediction_plot(historical_data, future_predictions, future_dates):
"""
Create an interactive plot showing the last week of historical prices
and week-ahead predictions with hourly granularity.
Args:
historical_data: DataFrame with historical price data and datetime index
future_predictions: List of predicted prices
future_dates: List of future datetime indices for predictions
"""
fig = go.Figure()
# Plot historical data using the datetime index
fig.add_trace(go.Scatter(
x=historical_data.index,
y=historical_data['Close'],
name='Historical Prices',
line=dict(color='blue')
))
# Plot predictions
fig.add_trace(go.Scatter(
x=future_dates,
y=future_predictions,
name='Predictions',
line=dict(color='red', dash='dash')
))
fig.update_layout(
title='Ethereum Price Prediction (Hourly)',
xaxis_title='Date',
yaxis_title='Price (USD)',
hovermode='x unified'
)
return fig
def predict_ethereum():
"""
Main function for Gradio interface that orchestrates the prediction process.
Handles hourly data and generates predictions for the next week.
"""
# Fetch and prepare data
data = fetch_ethereum_data()
sequence_length = 24 # Use 24 hours of data for prediction
X, y, scaler = prepare_data(data, sequence_length)
# Create and train model
model = create_model(sequence_length)
model.fit(X, y, epochs=50, batch_size=32, verbose=0)
# Prepare last sequence for prediction
last_sequence = scaler.transform(data['Close'].values[-sequence_length:].reshape(-1, 1))
# Generate future predictions
future_predictions = predict_future_prices(model, last_sequence, scaler)
# Create future dates (hourly intervals)
last_date = data.index[-1]
future_dates = [last_date + timedelta(hours=i+1) for i in range(len(future_predictions))]
# Create and return plot
fig = create_prediction_plot(data, future_predictions, future_dates)
return fig
# Create Gradio interface
iface = gr.Interface(
fn=predict_ethereum,
inputs=None,
outputs=gr.Plot(),
title="Ethereum Price Prediction",
description="Click to generate a 7-day price prediction for Ethereum based on hourly historical data.",
theme=gr.themes.Base()
)
if __name__ == "__main__":
iface.launch()