[Python] ARIMA Model give 0s for prediction when differentiating non Stationarity data

Discussão em 'Python' iniciado por Stack, Junho 18, 2025.

  1. Stack

    Stack Membro Participativo

    I am trying to learn ARIMA and so far I am working on this dataset

    Huge Stock Market Dataset

    i used intel stocks as you can see from the code, I was able to make it work with LSTM and that went smooth, but i dont have any experience with ARIMA

    my current problem is the forecast is a flat line, and can't figure out the problem


    import numpy as np
    import pandas as pd
    from pmdarima import auto_arima
    from statsmodels.tsa.stattools import adfuller
    from statsmodels.tsa.arima.model import ARIMA
    from sklearn.metrics import mean_squared_error, mean_absolute_error
    import matplotlib.pyplot as plt
    import warnings

    warnings.filterwarnings("ignore")

    # Load and preprocess data
    def load_data(filepath, start_date):
    df = pd.read_csv(filepath, sep=',')
    df = df[df['Date'] > start_date]
    df['Date'] = pd.to_datetime(df['Date'])
    df.set_index('Date', inplace=True)
    return df[['Close']]

    # ADF Test
    def adf_test(series):
    result = adfuller(series)
    print(f"ADF Statistic: {result[0]}, p-value: {result[1]}")
    return result[1] <= 0.05 # Stationary if p-value <= 0.05

    # Plot data
    def plot_series(series, title):
    plt.figure(figsize=(12, 6))
    plt.plot(series, label=title, color='blue', alpha=0.7)
    plt.title(title)
    plt.legend()
    plt.show()

    # Split data
    def split_data(data, split_ratio=0.8):
    train_size = int(len(data) * split_ratio)
    train, test = data[:train_size], data[train_size:]
    return train, test

    # Fit ARIMA model
    def fit_arima(train, order=None):
    if not order:
    stepwise_fit = auto_arima(train, seasonal=False, trace=True, error_action='ignore', suppress_warnings=True)
    order = stepwise_fit.order
    print(f"Selected ARIMA Order: {order}")
    model = ARIMA(train, order=order)
    return model.fit()

    # Forecast and evaluate
    def forecast_and_evaluate(model_fit, test, original_series=None, diff_order=0):
    forecast = model_fit.forecast(steps=len(test))
    forecast = pd.Series(forecast, index=test.index, name='Forecast')

    # Reverse differencing if applicable
    if diff_order > 0 and original_series is not None:
    last_train_value = original_series.iloc[-1] # Last value from original (non-differenced) training series
    forecast = forecast.cumsum() + last_train_value

    # Debugging forecast values
    print(f"First 5 forecast values (before adjustments):\n{forecast.head()}")

    # Remove negative values
    forecast[forecast < 0] = 0

    # Remove non-numeric values
    forecast = forecast.fillna(0)

    # Calculate metrics
    rmse = np.sqrt(mean_squared_error(test, forecast))
    mae = mean_absolute_error(test, forecast)
    print(f"\nRoot Mean Squared Error: {rmse}")
    print(f"Mean Absolute Error: {mae}")

    return forecast, rmse, mae

    # Plot comparison
    def plot_forecast(test, forecast, title='Actual vs Forecast'):
    plt.figure(figsize=(12, 6))
    plt.plot(test, label='Actual Test Data', color='blue', alpha=0.7)
    plt.plot(forecast, label='Forecast', color='red', linestyle='--', alpha=0.7)
    plt.title(title)
    plt.legend()
    plt.show()

    # Residual diagnostics
    def residual_diagnostics(residuals):
    plt.figure(figsize=(12, 6))
    plt.subplot(211)
    plt.plot(residuals, label='Residuals', color='purple', alpha=0.7)
    plt.title('Residuals')
    plt.legend()
    plt.subplot(212)
    plt.hist(residuals, bins=20, alpha=0.7, color='green', label='Residual Histogram')
    plt.title('Residual Histogram')
    plt.legend()
    plt.tight_layout()
    plt.show()

    # Main script
    if __name__ == "__main__":
    # Load data
    filepath = "../Datasets/Stocks/intc.us.txt"
    data = load_data(filepath, start_date='1990-01-01')

    # Check stationarity
    if not adf_test(data['Close']):
    print("Data is non-stationary. Differencing...")
    data_diff = data['Close'].diff().dropna()
    diff_order = 1
    print(f"First 5 values after differencing:\n{data_diff.head()}")
    else:
    print("Data is stationary.")
    data_diff = data['Close']
    diff_order = 0

    plot_series(data_diff, "Differenced Data")

    # Split data
    train, test = split_data(data_diff)
    original_train, original_test = split_data(data['Close'])

    # Fit ARIMA model
    model_fit = fit_arima(train)

    # Residual diagnostics
    residual_diagnostics(model_fit.resid)

    # Forecast and evaluate
    forecast, rmse, mae = forecast_and_evaluate(
    model_fit,
    test,
    original_series=original_train if diff_order > 0 else None,
    diff_order=diff_order
    )

    # Plot forecast vs actual
    plot_forecast(test, forecast, title="Actual vs Forecast")

    # Print forecast head
    print(forecast.head())

    here is the log

    ADF Statistic: -1.2717375543756217, p-value: 0.642001214544929
    Data is non-stationary. Differencing...
    First 5 values after differencing:
    Date
    1990-01-03 -0.0242
    1990-01-04 0.0164
    1990-01-05 -0.0084
    1990-01-08 0.0162
    1990-01-09 0.0240
    Name: Close, dtype: float64
    Performing stepwise search to minimize aic
    ARIMA(2,0,2)(0,0,0)[0] : AIC=9193.905, Time=0.56 sec
    ARIMA(0,0,0)(0,0,0)[0] : AIC=9200.647, Time=0.08 sec
    ARIMA(1,0,0)(0,0,0)[0] : AIC=9198.553, Time=0.06 sec
    ARIMA(0,0,1)(0,0,0)[0] : AIC=9198.409, Time=0.08 sec
    ARIMA(1,0,2)(0,0,0)[0] : AIC=9192.284, Time=0.35 sec
    ARIMA(0,0,2)(0,0,0)[0] : AIC=9198.467, Time=0.12 sec
    ARIMA(1,0,1)(0,0,0)[0] : AIC=9191.738, Time=0.23 sec
    ARIMA(2,0,1)(0,0,0)[0] : AIC=9192.008, Time=0.29 sec
    ARIMA(2,0,0)(0,0,0)[0] : AIC=9199.273, Time=0.09 sec
    ARIMA(1,0,1)(0,0,0)[0] intercept : AIC=9193.371, Time=0.64 sec

    Best model: ARIMA(1,0,1)(0,0,0)[0]
    Total fit time: 2.495 seconds
    Selected ARIMA Order: (1, 0, 1)
    First 5 forecast values (before adjustments):
    Date
    2012-04-16 NaN
    2012-04-17 NaN
    2012-04-18 NaN
    2012-04-19 NaN
    2012-04-20 NaN
    Name: Forecast, dtype: float64

    Root Mean Squared Error: 0.38750459255687414
    Mean Absolute Error: 0.2705679715302491
    Date
    2012-04-16 0.0
    2012-04-17 0.0
    2012-04-18 0.0
    2012-04-19 0.0
    2012-04-20 0.0
    Name: Forecast, dtype: float64

    Continue reading...

Compartilhe esta Página