Skip to content

plot_and_save module

calculate_metrics(predictions, actuals, threshold=0.8)

Calculate epsilon, beta and additional metrics (RMSE, RMSLE, MAPE, Bias, MAE).

Parameters:

Name Type Description Default
predictions array-like

Predicted values.

required
actuals array-like

Actual values.

required
threshold float

Relative error threshold. Defaults to 0.8.

0.8

Returns:

Type Description
tuple

Tuple containing: - epsilon (float): Epsilon value. - beta (float): Beta value. - rmse (float): Root mean square error. - rmsle (float): Root mean square log error. - mape (float): Mean absolute percentage error. - bias (float): Bias value. - mae (float): Mean absolute error.

Source code in hypercoast/moe_vae/plot_and_save.py
def calculate_metrics(predictions, actuals, threshold=0.8):
    """Calculate epsilon, beta and additional metrics (RMSE, RMSLE, MAPE, Bias, MAE).

    Args:
        predictions (array-like): Predicted values.
        actuals (array-like): Actual values.
        threshold (float, optional): Relative error threshold. Defaults to 0.8.

    Returns:
        tuple: Tuple containing:
            - epsilon (float): Epsilon value.
            - beta (float): Beta value.
            - rmse (float): Root mean square error.
            - rmsle (float): Root mean square log error.
            - mape (float): Mean absolute percentage error.
            - bias (float): Bias value.
            - mae (float): Mean absolute error.
    """
    # Apply the threshold to filter out predictions with large relative error
    # mask = np.abs(predictions - actuals) / np.abs(actuals+1e-10) < threshold
    # filtered_predictions = predictions[mask]
    # filtered_actuals = actuals[mask]
    predictions = np.where(predictions <= 1e-10, 1e-10, predictions)
    actuals = np.where(actuals <= 1e-10, 1e-10, actuals)
    filtered_predictions = predictions
    filtered_actuals = actuals

    # Calculate epsilon and beta
    log_ratios = np.log10(filtered_predictions / filtered_actuals)
    Y = np.median(np.abs(log_ratios))
    Z = np.median(log_ratios)
    epsilon = 100 * (10**Y - 1)
    beta = 50 * np.sign(Z) * (10 ** np.abs(Z) - 1)

    # Calculate additional metrics
    rmse = np.sqrt(np.mean((filtered_predictions - filtered_actuals) ** 2))
    rmsle = np.sqrt(
        np.mean(
            (np.log10(filtered_predictions + 1) - np.log10(filtered_actuals + 1)) ** 2
        )
    )
    mape = 50 * np.median(
        np.abs((filtered_predictions - filtered_actuals) / filtered_actuals)
    )
    bias = 10 ** (np.mean(np.log10(filtered_predictions) - np.log10(filtered_actuals)))
    mae = 10 ** np.mean(
        np.abs(np.log10(filtered_predictions) - np.log10(filtered_actuals))
    )

    return epsilon, beta, rmse, rmsle, mape, bias, mae

plot_results(predictions_rescaled, actuals_rescaled, save_dir, threshold=10, mode='test')

Plot the results of the MoE-VAE model.

Parameters:

Name Type Description Default
predictions_rescaled array-like

Predicted values.

required
actuals_rescaled array-like

Actual values.

required
save_dir str

Directory to save the plot.

required
threshold float

Relative error threshold. Defaults to 10.

10
mode str

Mode of the plot. Defaults to "test".

'test'
Source code in hypercoast/moe_vae/plot_and_save.py
def plot_results(
    predictions_rescaled, actuals_rescaled, save_dir, threshold=10, mode="test"
):
    """Plot the results of the MoE-VAE model.

    Args:
        predictions_rescaled (array-like): Predicted values.
        actuals_rescaled (array-like): Actual values.
        save_dir (str): Directory to save the plot.
        threshold (float, optional): Relative error threshold. Defaults to 10.
        mode (str, optional): Mode of the plot. Defaults to "test".
    """

    actuals = actuals_rescaled.flatten()
    predictions = predictions_rescaled.flatten()

    log_actuals = np.log10(actuals)
    log_predictions = np.log10(predictions)

    # mask = np.abs(predictions - actuals) / np.abs(actuals+1e-10) < threshold
    mask = np.abs(log_predictions - log_actuals) < threshold
    filtered_predictions = predictions[mask]
    filtered_actuals = actuals[mask]

    log_actual = np.log10(np.where(actuals == 0, 1e-10, actuals))
    log_prediction = np.log10(np.where(predictions == 0, 1e-10, predictions))

    filtered_log_actual = np.log10(
        np.where(filtered_actuals == 0, 1e-10, filtered_actuals)
    )
    filtered_log_prediction = np.log10(
        np.where(filtered_predictions == 0, 1e-10, filtered_predictions)
    )

    epsilon, beta, rmse, rmsle, mape, bias, mae = calculate_metrics(
        filtered_predictions, filtered_actuals, threshold
    )

    valid_mask = np.isfinite(filtered_log_actual) & np.isfinite(filtered_log_prediction)
    slope, intercept = np.polyfit(
        filtered_log_actual[valid_mask], filtered_log_prediction[valid_mask], 1
    )
    x = np.array([-4, 4])
    y = slope * x + intercept

    plt.figure(figsize=(6, 6))

    plt.plot(x, y, linestyle="--", color="blue", linewidth=0.8)
    lims = [-4, 4]
    plt.plot(lims, lims, linestyle="-", color="black", linewidth=0.8)

    sns.scatterplot(x=log_actual, y=log_prediction, alpha=0.5)

    sns.kdeplot(
        x=filtered_log_actual,
        y=filtered_log_prediction,
        levels=3,
        color="black",
        fill=False,
        linewidths=0.8,
    )

    plt.xlabel("Actual Values", fontsize=16, fontname="Ubuntu")
    plt.ylabel("Predicted Values", fontsize=16, fontname="Ubuntu")
    plt.xlim(-4, 4)
    plt.ylim(-4, 4)
    plt.grid(True, which="both", ls="--")

    plt.legend(
        title=(
            f"MAE = {mae:.2f}, RMSE = {rmse:.2f}, RMSLE = {rmsle:.2f} \n"
            f"Bias = {bias:.2f}, Slope = {slope:.2f} \n"
            f"MAPE = {mape:.2f}%, ε = {epsilon:.2f}%, β = {beta:.2f}%"
        ),
        fontsize=16,
        title_fontsize=12,
        prop={"family": "Ubuntu"},
    )

    plt.xticks(fontsize=20, fontname="Ubuntu")
    plt.yticks(fontsize=20, fontname="Ubuntu")

    plt.savefig(os.path.join(save_dir, f"{mode}_plot.pdf"), bbox_inches="tight")
    plt.close()

save_and_plot_results_from_excel(predictions, actuals, sample_ids, dates, original_excel_path, save_dir)

Save and plot the results from an Excel file.

Parameters:

Name Type Description Default
predictions array-like

Predicted values.

required
actuals array-like

Actual values.

required
sample_ids array-like

IDs of the samples.

required
dates array-like

Dates of the samples.

required
original_excel_path str

Path to the original Excel file.

required
save_dir str

Directory to save the results.

required
Source code in hypercoast/moe_vae/plot_and_save.py
def save_and_plot_results_from_excel(
    predictions, actuals, sample_ids, dates, original_excel_path, save_dir
):
    """Save and plot the results from an Excel file.

    Args:
        predictions (array-like): Predicted values.
        actuals (array-like): Actual values.
        sample_ids (array-like): IDs of the samples.
        dates (array-like): Dates of the samples.
        original_excel_path (str): Path to the original Excel file.
        save_dir (str): Directory to save the results.
    """
    os.makedirs(save_dir, exist_ok=True)

    filename = os.path.basename(original_excel_path)
    dataset_name = os.path.splitext(filename)[0]

    save_results_to_excel(
        sample_ids,
        actuals,
        predictions,
        os.path.join(save_dir, f"{dataset_name}.xlsx"),
        dates=dates,
    )
    plot_results(predictions, actuals, save_dir, mode=dataset_name)

save_model_structure_from_classes(save_path)

Save the model structure from classes to a file.

Parameters:

Name Type Description Default
save_path str

Path to save the model structure.

required
Source code in hypercoast/moe_vae/plot_and_save.py
def save_model_structure_from_classes(save_path):
    """Save the model structure from classes to a file.

    Args:
        save_path (str): Path to save the model structure.
    """
    classes = [SparseDispatcher, VAE, MoE_VAE]

    with open(save_path, "w") as f:
        for cls in classes:
            f.write(f"# === Source for {cls.__name__} ===\n")
            f.write(inspect.getsource(cls))
            f.write("\n\n")

save_results_to_excel(ids, actuals, predictions, file_path, dates=None)

Save prediction results to an Excel file. - If dates are included, output ID, Date, Actual, Predicted; - Otherwise, output ID, Actual, Predicted.

Parameters:

Name Type Description Default
ids array-like

IDs of the samples.

required
actuals array-like

Actual values.

required
predictions array-like

Predicted values.

required
file_path str

Path to save the Excel file.

required
dates array-like

Dates of the samples. Defaults to None.

None
Source code in hypercoast/moe_vae/plot_and_save.py
def save_results_to_excel(ids, actuals, predictions, file_path, dates=None):
    """
    Save prediction results to an Excel file.
    - If dates are included, output ID, Date, Actual, Predicted;
    - Otherwise, output ID, Actual, Predicted.

    Args:
        ids (array-like): IDs of the samples.
        actuals (array-like): Actual values.
        predictions (array-like): Predicted values.
        file_path (str): Path to save the Excel file.
        dates (array-like, optional): Dates of the samples. Defaults to None.
    """
    if dates is not None:
        df = pd.DataFrame(
            {"ID": ids, "Date": dates, "Actual": actuals, "Predicted": predictions}
        )
    else:
        df = pd.DataFrame({"ID": ids, "Actual": actuals, "Predicted": predictions})

    df.to_excel(file_path, index=False)