时间序列预测需求:模型验证、未来30期预测及可视化优化
Got it, let's walk through how to tackle your slot machine revenue time series forecasting task step by step. I'll use Python (the go-to tool for this kind of work) with practical code examples and actionable explanations for each requirement.
1. Validate 2018 February Forecast Against Actual Values
First, we need to test how well our model predicts known data before trusting it for future forecasts. Here's how to do it:
Step 1: Split Your Dataset
Separate your data into a training set (all data up to 2018-01-31) and a test set (only 2018-02 data). This lets us train on historical data and compare predictions to real values.
import pandas as pd # Load your data (assumes CSV with 'ds' for dates and 'y' for revenue) df = pd.read_csv("slot_revenue.csv") df["ds"] = pd.to_datetime(df["ds"]) # Split into train (pre-Feb 2018) and test (Feb 2018) train = df[df["ds"] <= "2018-01-31"] test = df[df["ds"].between("2018-02-01", "2018-02-28")]
Step 2: Train a Seasonal Time Series Model
For revenue data, Facebook Prophet is a great choice—it handles trends, weekly/monthly seasonality, and holidays automatically. Let's set it up:
from prophet import Prophet # Initialize model with seasonality settings model = Prophet( yearly_seasonality=True, # Annual revenue trends weekly_seasonality=True, # Weekend/weekday patterns daily_seasonality=False # Unlikely daily seasonality for slot machines ) model.fit(train)
Step 3: Generate February Forecast & Compare to Actuals
Create a forecast for February 2018, then merge it with actual values to calculate performance metrics:
# Create future dataframe for Feb 2018 (28 days) future_feb = model.make_future_dataframe(periods=28) forecast_feb = model.predict(future_feb) # Isolate Feb forecast values feb_preds = forecast_feb[forecast_feb["ds"].between("2018-02-01", "2018-02-28")][["ds", "yhat"]] # Merge with actuals for comparison comparison = pd.merge(feb_preds, test[["ds", "y"]], on="ds")
Step 4: Evaluate Model Performance
Use standard metrics to measure how accurate the forecast was:
from sklearn.metrics import mean_absolute_error, mean_squared_error import numpy as np mae = mean_absolute_error(comparison["y"], comparison["yhat"]) rmse = np.sqrt(mean_squared_error(comparison["y"], comparison["yhat"])) mape = np.mean(np.abs((comparison["y"] - comparison["yhat"]) / comparison["y"])) * 100 print(f"MAE (Average Absolute Error): ${mae:.2f}") print(f"RMSE (Root Mean Squared Error): ${rmse:.2f}") print(f"MAPE (Percent Error): {mape:.2f}%")
Lower values for all metrics mean better performance. MAPE is especially useful here because it tells you how off your forecast is relative to actual revenue (e.g., a 5% MAPE means predictions are on average 5% away from real values).
2. Forecast the Next 30 Periods
Using the same trained model, extend the forecast to the next 30 days (adjust periods if your data is weekly/monthly):
# Create future dataframe for next 30 days future_30 = model.make_future_dataframe(periods=30) forecast_30 = model.predict(future_30) # Extract only the next 30 days of predictions next_30_preds = forecast_30.iloc[-30:][["ds", "yhat", "yhat_lower", "yhat_upper"]] # Print or save the results print(next_30_preds) next_30_preds.to_csv("next_30_days_forecast.csv", index=False)
The yhat_lower and yhat_upper columns give you a confidence interval—this shows the range of possible revenue values, which is critical for stakeholders to understand forecast uncertainty.
3. Optimize Visualization for the Next 3-Month Forecast
A clear, informative plot makes your forecast easy to interpret. Let's build a polished visualization using Matplotlib (static) or Plotly (interactive):
Static Polished Plot (Matplotlib)
import matplotlib.pyplot as plt # Generate 3-month forecast (90 days) future_3m = model.make_future_dataframe(periods=90) forecast_3m = model.predict(future_3m) # Set up plot plt.figure(figsize=(12, 6)) # Plot historical data plt.plot(train["ds"], train["y"], label="Historical Revenue", color="#1f77b4") # Highlight actual Feb 2018 data plt.plot(test["ds"], test["y"], label="Actual Feb 2018 Revenue", color="#2ca02c") # Plot 3-month forecast with confidence interval plt.plot(forecast_3m["ds"], forecast_3m["yhat"], label="3-Month Forecast", color="#ff7f0e") plt.fill_between( forecast_3m["ds"], forecast_3m["yhat_lower"], forecast_3m["yhat_upper"], color="#ff7f0e", alpha=0.2, label="Forecast Confidence Interval" ) # Add formatting for readability plt.title("Slot Machine Revenue: Historical, Actual Feb 2018, & 3-Month Forecast", fontsize=14) plt.xlabel("Date", fontsize=12) plt.ylabel("Revenue ($)", fontsize=12) plt.legend() plt.grid(True, linestyle="--", alpha=0.7) plt.xticks(rotation=45) plt.tight_layout() plt.show()
Interactive Plot (Plotly)
For stakeholders who want to zoom, hover, or toggle data on/off, use Plotly:
import plotly.graph_objects as go fig = go.Figure() # Add historical data fig.add_trace(go.Scatter( x=train["ds"], y=train["y"], name="Historical Revenue", mode="lines", line=dict(color="#1f77b4") )) # Add actual Feb data fig.add_trace(go.Scatter( x=test["ds"], y=test["y"], name="Actual Feb 2018 Revenue", mode="lines", line=dict(color="#2ca02c") )) # Add forecast and confidence interval fig.add_trace(go.Scatter( x=forecast_3m["ds"], y=forecast_3m["yhat"], name="3-Month Forecast", mode="lines", line=dict(color="#ff7f0e") )) fig.add_trace(go.Scatter( x=forecast_3m["ds"], y=forecast_3m["yhat_upper"], mode="lines", line=dict(color="#ff7f0e", dash="dash"), showlegend=False )) fig.add_trace(go.Scatter( x=forecast_3m["ds"], y=forecast_3m["yhat_lower"], mode="lines", line=dict(color="#ff7f0e", dash="dash"), fill="tonexty", showlegend=False )) # Update layout for clarity fig.update_layout( title="Slot Machine Revenue: Historical, Actual Feb 2018, & 3-Month Forecast", xaxis_title="Date", yaxis_title="Revenue ($)", hovermode="x unified", template="plotly_white", xaxis=dict(tickangle=45) ) fig.show()
Key Visualization Optimizations:
- Distinct Colors: Use unique colors for historical, actual, and forecast data to avoid confusion.
- Confidence Intervals: The shaded area shows forecast uncertainty—critical for setting realistic expectations.
- Readable Axes: Rotate date labels and add grid lines to make values easy to cross-reference.
- Clear Titles/Labels: Ensure anyone looking at the plot understands what it shows at a glance.
Content of the question originates from Stack Exchange, question author William Bernard

