[Python] SciPy fails to stably determine parameters given large data scale differences

Discussão em 'Python' iniciado por Stack, Maio 30, 2025.

  1. Stack

    Stack Membro Participativo

    We are using scipy.optimize.curve_fit to fit parameters X_eff and Y_eff for an Automated Market Maker (AMM) model: y_out = (Y_eff * x_in) / (X_eff + x_in)

    We're observing extreme sensitivity in the fitted X_eff and Y_eff values when our input data points (x_in, y_out) have significantly different scales, or when there are minor variations in the larger-scale data points.

    Here is the code that demonstrates that with static hardcoded values:

    import numpy as np
    from scipy.optimize import curve_fit

    def swap_model(x_in, X_eff, Y_eff):
    denominator = X_eff + x_in
    if np.isscalar(denominator):
    return (Y_eff * x_in) / (denominator if not np.isclose(denominator, 0) else 1e-9)
    else:
    denominator_copy = np.copy(denominator)
    denominator_copy[np.isclose(denominator_copy, 0)] = 1e-9
    return (Y_eff * x_in) / denominator_copy

    bounds = ([1e-6, 1e-6], [np.inf, np.inf])

    x_test_value = 6507.3125

    print("--- Case 1: Poor Fit ---")
    x_data_bad = np.array([1, 2, 39000])
    y_data_bad = np.array([8423.724335, 16846.531751, 319765062.090722])
    y_actual_for_bad_case_test = 54311422.15982

    try:
    popt_bad, _ = curve_fit(swap_model, x_data_bad, y_data_bad, bounds=bounds, maxfev=5000)
    X_eff_bad, Y_eff_bad = popt_bad
    print(f"Fitted (Bad): X_eff = {X_eff_bad:.4f}, Y_eff = {Y_eff_bad:.4f}")
    y_pred_bad = swap_model(x_test_value, X_eff_bad, Y_eff_bad)
    error_bad = abs(y_actual_for_bad_case_test - y_pred_bad) / y_actual_for_bad_case_test * 100
    print(f"Predicted for {x_test_value:.4f}: {y_pred_bad:.4f}, Actual: {y_actual_for_bad_case_test:.4f}, Error: {error_bad:.2f}%")
    except RuntimeError as e: print(f"RuntimeError: {e}")
    except Exception as e: print(f"Other exception in bad fit: {e}")


    print("\n--- Case 2: Better Fit ---")
    x_data_good = np.array([1, 2, 32000])
    y_data_good = np.array([8430.169107, 16859.464909, 264727159.854379])
    y_actual_for_good_case_test = 54549399.392518

    try:
    popt_good, _ = curve_fit(swap_model, x_data_good, y_data_good, bounds=bounds, maxfev=5000)
    X_eff_good, Y_eff_good = popt_good
    print(f"Fitted (Good): X_eff = {X_eff_good:,.4f}, Y_eff = {Y_eff_good:,.4f}")
    y_pred_good = swap_model(x_test_value, X_eff_good, Y_eff_good)
    error_good = abs(y_actual_for_good_case_test - y_pred_good) / y_actual_for_good_case_test * 100
    print(f"Predicted for {x_test_value:.4f}: {y_pred_good:.4f}, Actual: {y_actual_for_good_case_test:.4f}, Error: {error_good:.2f}%")
    except RuntimeError as e: print(f"RuntimeError: {e}")
    except Exception as e: print(f"Other exception in good fit: {e}")


    The same code but with comments in pastebin: https://pastebin.com/V2BZPbJB

    The graph here the one that works: [​IMG]

    and here the one that does not:

    [​IMG]

    Continue reading...

Compartilhe esta Página