Cycles/xgboost/plot_results.py

207 lines
7.0 KiB
Python

import numpy as np
import dash
from dash import dcc, html
import plotly.graph_objs as go
import threading
def display_actual_vs_predicted(y_test, test_preds, timestamps, n_plot=200):
import plotly.offline as pyo
n_plot = min(n_plot, len(y_test))
plot_indices = timestamps[:n_plot]
actual = y_test[:n_plot]
predicted = test_preds[:n_plot]
trace_actual = go.Scatter(x=plot_indices, y=actual, mode='lines', name='Actual')
trace_predicted = go.Scatter(x=plot_indices, y=predicted, mode='lines', name='Predicted')
data = [trace_actual, trace_predicted]
layout = go.Layout(
title='Actual vs. Predicted BTC Close Prices (Test Set)',
xaxis={'title': 'Timestamp'},
yaxis={'title': 'BTC Close Price'},
legend={'x': 0, 'y': 1},
margin={'l': 40, 'b': 40, 't': 40, 'r': 10},
hovermode='closest'
)
fig = go.Figure(data=data, layout=layout)
pyo.plot(fig)
def plot_target_distribution(y_train, y_test):
import plotly.offline as pyo
trace_train = go.Histogram(
x=y_train,
nbinsx=100,
opacity=0.5,
name='Train',
marker=dict(color='blue')
)
trace_test = go.Histogram(
x=y_test,
nbinsx=100,
opacity=0.5,
name='Test',
marker=dict(color='orange')
)
data = [trace_train, trace_test]
layout = go.Layout(
title='Distribution of Target Variable (Close Price)',
xaxis=dict(title='BTC Close Price'),
yaxis=dict(title='Frequency'),
barmode='overlay'
)
fig = go.Figure(data=data, layout=layout)
pyo.plot(fig)
def plot_predicted_vs_actual_log_returns(y_test, test_preds, timestamps=None, n_plot=200):
import plotly.offline as pyo
import plotly.graph_objs as go
n_plot = min(n_plot, len(y_test))
actual = y_test[:n_plot]
predicted = test_preds[:n_plot]
if timestamps is not None:
x_axis = timestamps[:n_plot]
x_label = 'Timestamp'
else:
x_axis = list(range(n_plot))
x_label = 'Index'
# Line plot: Actual vs Predicted over time
trace_actual = go.Scatter(x=x_axis, y=actual, mode='lines', name='Actual')
trace_predicted = go.Scatter(x=x_axis, y=predicted, mode='lines', name='Predicted')
data_line = [trace_actual, trace_predicted]
layout_line = go.Layout(
title='Actual vs. Predicted Log Returns (Test Set)',
xaxis={'title': x_label},
yaxis={'title': 'Log Return'},
legend={'x': 0, 'y': 1},
margin={'l': 40, 'b': 40, 't': 40, 'r': 10},
hovermode='closest'
)
fig_line = go.Figure(data=data_line, layout=layout_line)
pyo.plot(fig_line, filename='log_return_line_plot.html')
# Scatter plot: Predicted vs Actual
trace_scatter = go.Scatter(
x=actual,
y=predicted,
mode='markers',
name='Predicted vs Actual',
opacity=0.5
)
# Diagonal reference line
min_val = min(np.min(actual), np.min(predicted))
max_val = max(np.max(actual), np.max(predicted))
trace_diag = go.Scatter(
x=[min_val, max_val],
y=[min_val, max_val],
mode='lines',
name='Ideal',
line=dict(dash='dash', color='red')
)
data_scatter = [trace_scatter, trace_diag]
layout_scatter = go.Layout(
title='Predicted vs Actual Log Returns (Scatter)',
xaxis={'title': 'Actual Log Return'},
yaxis={'title': 'Predicted Log Return'},
showlegend=True,
margin={'l': 40, 'b': 40, 't': 40, 'r': 10},
hovermode='closest'
)
fig_scatter = go.Figure(data=data_scatter, layout=layout_scatter)
pyo.plot(fig_scatter, filename='log_return_scatter_plot.html')
def plot_predicted_vs_actual_prices(actual_prices, predicted_prices, timestamps=None, n_plot=200):
import plotly.offline as pyo
import plotly.graph_objs as go
n_plot = min(n_plot, len(actual_prices))
actual = actual_prices[:n_plot]
predicted = predicted_prices[:n_plot]
if timestamps is not None:
x_axis = timestamps[:n_plot]
x_label = 'Timestamp'
else:
x_axis = list(range(n_plot))
x_label = 'Index'
# Line plot: Actual vs Predicted over time
trace_actual = go.Scatter(x=x_axis, y=actual, mode='lines', name='Actual Price')
trace_predicted = go.Scatter(x=x_axis, y=predicted, mode='lines', name='Predicted Price')
data_line = [trace_actual, trace_predicted]
layout_line = go.Layout(
title='Actual vs. Predicted BTC Prices (Test Set)',
xaxis={'title': x_label},
yaxis={'title': 'BTC Price'},
legend={'x': 0, 'y': 1},
margin={'l': 40, 'b': 40, 't': 40, 'r': 10},
hovermode='closest'
)
fig_line = go.Figure(data=data_line, layout=layout_line)
pyo.plot(fig_line, filename='price_line_plot.html')
# Scatter plot: Predicted vs Actual
trace_scatter = go.Scatter(
x=actual,
y=predicted,
mode='markers',
name='Predicted vs Actual',
opacity=0.5
)
# Diagonal reference line
min_val = min(np.min(actual), np.min(predicted))
max_val = max(np.max(actual), np.max(predicted))
trace_diag = go.Scatter(
x=[min_val, max_val],
y=[min_val, max_val],
mode='lines',
name='Ideal',
line=dict(dash='dash', color='red')
)
data_scatter = [trace_scatter, trace_diag]
layout_scatter = go.Layout(
title='Predicted vs Actual Prices (Scatter)',
xaxis={'title': 'Actual Price'},
yaxis={'title': 'Predicted Price'},
showlegend=True,
margin={'l': 40, 'b': 40, 't': 40, 'r': 10},
hovermode='closest'
)
fig_scatter = go.Figure(data=data_scatter, layout=layout_scatter)
pyo.plot(fig_scatter, filename='price_scatter_plot.html')
def plot_prediction_error_distribution(predicted_prices, actual_prices, nbins=100):
"""
Plots the distribution of signed prediction errors between predicted and actual prices,
coloring negative errors (under-prediction) and positive errors (over-prediction) differently.
"""
import plotly.offline as pyo
import plotly.graph_objs as go
errors = np.array(predicted_prices) - np.array(actual_prices)
# Separate negative and positive errors
neg_errors = errors[errors < 0]
pos_errors = errors[errors >= 0]
trace_neg = go.Histogram(
x=neg_errors,
nbinsx=nbins,
opacity=0.75,
marker=dict(color='blue'),
name='Negative Error (Under-prediction)'
)
trace_pos = go.Histogram(
x=pos_errors,
nbinsx=nbins,
opacity=0.75,
marker=dict(color='orange'),
name='Positive Error (Over-prediction)'
)
layout = go.Layout(
title='Distribution of Prediction Errors (Signed)',
xaxis=dict(title='Prediction Error (Predicted - Actual)'),
yaxis=dict(title='Frequency'),
barmode='overlay',
bargap=0.05
)
fig = go.Figure(data=[trace_neg, trace_pos], layout=layout)
pyo.plot(fig, filename='prediction_error_distribution.html')