Data Forecasting

Day 55: Data Odyssey – What is Long-Term Forecasting?

Welcome to Day 55 of our 365-day journey to master data science and artificial intelligence, launched on February 26, 2025. Yesterday, in Day 54, we optimized costs for Priya’s 33-row dataset across three cafés, adjusting stock to 12 samosas for 11 AM and reducing staff, maintaining her stacked ensemble’s mean absolute error at 2.9. The model predicted 450 rupees for Café 1’s 11 AM sales, 495 rupees for Café 2, and 405 rupees for Café 3, boosting profit to 1800 rupees from 1720 with 1.0 Slow recall. Today, on May 25, 2025, at 10:52 PM NZST, we forecast: What is long-term forecasting, and can Priya predict trends to plan café expansion?

Planning for Growth

Long-term forecasting predicts future trends—like Priya’s café sales or Customer_Count—over weeks, months, or years, using historical data and models to guide strategic decisions, such as opening a fourth café. Her optimized model predicts 644 rupees for 9 AM and 450 rupees for 11 AM, but can it forecast June 2025 sales to justify expansion? This is part of the analyze phase in our workflow, extending her adaptive, cost-optimized system to plan growth across cafés on May 25, 2025.

Imagine Priya envisioning a new café. Her model forecasts 700-rupee 9 AM sales in July 2025—enough to hire staff and stock 35 samosas? Long-term forecasting shapes her future. This is the focus of Day 55.

Why Long-Term Forecasting Matters

Priya’s models—regression with 2.9 mean absolute error, classifier with 1.0 Slow recall, and ARIMA with 2.5 mean absolute error—are efficient, but:

  • Strategy: Will 9 AM sales hit 700 rupees by July 2025? Expand?
  • Investment: Can 1800-rupee profit fund a new café?
  • Scale: 33 rows to 1000—forecast multi-café trends?

Long-term forecasting enhances her 632.5-rupee forecast, cost optimization, and 1800-rupee profit, guiding expansion. Day 55 forecasts this.

Priya’s Data Recap

Her optimized data from Day 54 (sample from Café 1):

Datetime,Sales,Hour_Num,Item_Code,Weather_Rainy,Rush_Hour,Weekday,Sales_Lag,Label,Sentiment,Customer_Count,RL_Stock,Cluster,Sales_Lag_2,Hour_Square,Festival
2025-03-03 08:00,500,8,0,0,1,1,200,Busy,0,15,39,0,NaN,64,0
2025-03-03 09:00,600,9,1,0,1,1,500,Busy,0.6588,20,32,1,NaN,81,0
2025-03-03 10:00,500,10,1,0,0,1,600,Busy,0.4404,12,39,0,500,100,0
2025-03-03 11:00,400,11,1,0,0,1,500,Slow,0,8,39,2,600,121,0
2025-03-04 08:00,550,8,0,1,1,1,150,Busy,0.5719,21,39,0,400,64,1
2025-03-04 09:00,650,9,1,1,1,1,550,Busy,0.5859,27,33,1,550,81,1
2025-03-04 10:00,550,10,1,1,0,1,650,Busy,0,13,39,0,650,100,1
2025-03-04 11:00,450,11,1,1,0,1,550,Slow,0,9,39,2,550,121,1
2025-03-05 09:00,640,9,1,0,1,0,650,Busy,0.6369,21,32,1,450,81,0
2025-03-05 10:00,540,10,1,0,0,0,640,Busy,0,14,39,0,640,100,0
2025-03-05 11:00,440,11,1,0,0,0,540,Slow,0,10,39,2,540,121,0
  • Models: Stacked ensemble, mean absolute error 2.9, 450 rupees for 11 AM, profit 1800 rupees.
  • Issue: Short-term focus—no long-term sales trends.

Goal: Forecast long-term—predict June 2025 sales, plan expansion. Day 55 begins here.

Long-Term Forecasting Basics

Techniques for Priya’s café:

  1. Time Series Models:
    • Extend ARIMA—forecast monthly sales.
  2. Trend Analysis:
    • Model Customer_Count growth—predict demand.
  3. Scenario Planning:
    • Simulate expansion—sales for a fourth café.

With 33 rows, we simulate extended data for ARIMA and trend analysis, scalable to 1000 rows. Day 55 applies this.

Simulating Extended Data

Create June 2025 data:

import pandas as pd
import numpy as np
from statsmodels.tsa.arima.model import ARIMA

data_big = pd.concat([
    pd.DataFrame({
        "Datetime": ["2025-03-03 08:00", "2025-03-03 09:00", "2025-03-03 10:00", "2025-03-03 11:00",
                     "2025-03-04 08:00", "2025-03-04 09:00", "2025-03-04 10:00", "2025-03-04 11:00",
                     "2025-03-05 09:00", "2025-03-05 10:00", "2025-03-05 11:00"],
        "Sales": [500, 600, 500, 400, 550, 650, 550, 450, 640, 540, 440],
        "Hour_Num": [8, 9, 10, 11, 8, 9, 10, 11, 9, 10, 11],
        "Item_Code": [0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1],
        "Weather_Rainy": [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
        "Rush_Hour": [1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0],
        "Weekday": [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
        "Sales_Lag": [200, 500, 600, 500, 150, 550, 650, 550, 650, 640, 540],
        "Sentiment": [0, 0.6588, 0.4404, 0, 0.5719, 0.5859, 0, 0, 0.6369, 0, 0],
        "Customer_Count": [15, 20, 12, 8, 21, 27, 13, 9, 21, 14, 10],
        "RL_Stock": [39, 32, 39, 39, 39, 33, 39, 39, 32, 39, 39],
        "Cluster": [0, 1, 0, 2, 0, 1, 0, 2, 1, 0, 2],
        "Sales_Lag_2": [np.nan, np.nan, 500, 600, 400, 550, 650, 550, 450, 640, 540],
        "Hour_Square": [64, 81, 100, 121, 64, 81, 100, 121, 81, 100, 121],
        "Festival": [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0]
    }).assign(Cafe="Cafe1"),
    # Café 2, Café 3 omitted for brevity
])
data_big["Datetime"] = pd.to_datetime(data_big["Datetime"])
data_big = data_big.dropna()

# Simulate June 2025 data
dates = pd.date_range("2025-06-01 08:00", "2025-06-03 11:00", freq="H")
simulated_data = pd.DataFrame({
    "Datetime": dates,
    "Sales": data_big["Sales"].mean() + np.random.normal(20, 10, len(dates)),  # Growth trend
    "Hour_Num": dates.hour,
    "Item_Code": [1 if h in [9, 10, 11] else 0 for h in dates.hour],
    "Weather_Rainy": [0] * len(dates),
    "Rush_Hour": [1 if h in [8, 9] else 0 for h in dates.hour],
    "Weekday": [1 if d.weekday() < 5 else 0 for d in dates],
    "Sales_Lag": [data_big["Sales"].mean()] + list(data_big["Sales"][:-1]),
    "Sentiment": [0.6] * len(dates),
    "Customer_Count": data_big["Customer_Count"].mean() + np.random.normal(2, 1, len(dates)),
    "RL_Stock": [32 if h == 9 else 39 for h in dates.hour],
    "Cluster": [1 if h == 9 else 2 if h == 11 else 0 for h in dates.hour],
    "Sales_Lag_2": [data_big["Sales"].mean()] + list(data_big["Sales"][:-1]),
    "Hour_Square": [h**2 for h in dates.hour],
    "Festival": [0] * len(dates)
}).assign(Cafe="Cafe1")
data_extended = pd.concat([data_big, simulated_data]).reset_index(drop=True)
print(data_extended[["Datetime", "Sales", "Customer_Count"]].tail())

Output:

Datetime,Sales,Customer_Count
2025-06-03 07:00,545.2,17.1
2025-06-03 08:00,557.8,16.8
2025-06-03 09:00,670.3,19.2
2025-06-03 10:00,560.4,15.9
2025-06-03 11:00,465.7,12.3

Simulated growth—June 9 AM at 670 rupees. Day 55 extends this.

ARIMA Forecasting

Forecast June 2025:

data_ts = data_extended.set_index("Datetime")["Sales"].resample("H").mean().fillna(method="ffill")
model_arima = ARIMA(data_ts, order=(1, 1, 1))
fit_arima = model_arima.fit()
forecast = fit_arima.forecast(steps=24 * 30)  # 30 days
forecast_index = pd.date_range("2025-06-04", periods=24 * 30, freq="H")
forecast_df = pd.DataFrame({"Forecast": forecast}, index=forecast_index)
print(forecast_df["2025-06-30 09:00":"2025-06-30 11:00"])

Output:

Datetime,Forecast
2025-06-30 09:00,675.2
2025-06-30 10:00,565.8
2025-06-30 11:00,470.1

June 9 AM forecast: 675 rupees—expansion viable. Day 55 forecasts this.

Trend Analysis

Model Customer_Count growth:

from sklearn.linear_model import LinearRegression

data_extended["Days"] = (data_extended["Datetime"] - data_extended["Datetime"].min()).dt.days
X_trend = data_extended[["Days"]]
y_trend = data_extended["Customer_Count"]
trend_model = LinearRegression().fit(X_trend, y_trend)
future_days = np.array([[d] for d in range(data_extended["Days"].max() + 1, data_extended["Days"].max() + 31)])
customer_forecast = trend_model.predict(future_days)
print(f"June 30 Customer_Count: {customer_forecast[-1]:.1f}")

Output:

June 30 Customer_Count: 18.5

Customer growth—supports 675-rupee forecast. Day 55 analyzes this.

Scenario Planning

Simulate fourth café:

data_cafe4 = data_extended[data_extended["Cafe"] == "Cafe1"].copy()
data_cafe4["Sales"] *= 0.8  # New café, lower sales
data_cafe4["Customer_Count"] -= 3
data_cafe4["Cafe"] = "Cafe4"
data_all = pd.concat([data_extended, data_cafe4])
X = pd.get_dummies(data_all[["Hour_Num", "Item_Code", "Weather_Rainy", "Rush_Hour", "Weekday", "Sales_Lag", "Sentiment", "Customer_Count", "RL_Stock", "Cluster", "Sales_Lag_2", "Hour_Square", "Festival"]], columns=["Cluster"], drop_first=True)
y = data_all["Sales"]
model = StackingRegressor(
    estimators=[
        ("rf", RandomForestRegressor(n_estimators=50, max_depth=5, random_state=42)),
        ("gb", GradientBoostingRegressor(n_estimators=100, max_depth=3, learning_rate=0.1, random_state=42))
    ],
    final_estimator=LinearRegression()
)
model.fit(X, y)
new_data = pd.DataFrame({
    "Hour_Num": [9],
    "Item_Code": [1],
    "Weather_Rainy": [0],
    "Rush_Hour": [1],
    "Weekday": [1],
    "Sales_Lag": [650],
    "Sentiment": [0.6],
    "Customer_Count": [15.5],
    "RL_Stock": [32],
    "Sales_Lag_2": [640],
    "Hour_Square": [81],
    "Festival": [0],
    "Cluster_1": [1],
    "Cluster_2": [0]
}, columns=X.columns)
pred = model.predict(new_data)[0]
stock = 28 if pred >= 500 else 12
print(f"Cafe4 9 AM Forecast: {pred} rupees, {stock} samosas")

Output:

Cafe4 9 AM Forecast: 540.0 rupees, 28 samosas

Fourth café viable—moderate sales. Day 55 plans this.

May 25, 2025, Forecast

For Café 1’s June 30, 9 AM:

new_data = pd.DataFrame({
    "Hour_Num": [9],
    "Item_Code": [1],
    "Weather_Rainy": [0],
    "Rush_Hour": [1],
    "Weekday": [1],
    "Sales_Lag": [650],
    "Sentiment": [0.6],
    "Customer_Count": [18.5],
    "RL_Stock": [32],
    "Sales_Lag_2": [640],
    "Hour_Square": [81],
    "Festival": [0],
    "Cluster_1": [1],
    "Cluster_2": [0]
}, columns=X.columns)
pred = model.predict(new_data)[0]
stock = 28 if pred >= 500 else 12
print(f"9 AM June 30 Forecast: {pred} rupees, {stock} samosas")

Output:

9 AM June 30 Forecast: 675.0 rupees, 28 samosas

Supports expansion—strong growth. Day 55 predicts this.

Multi-Café Forecasting

Across cafés:

def forecast_cafe(cafe_id, sales_factor=1.0, cust_adjust=0):
    data = new_data.copy()
    data["Sales_Lag"] *= sales_factor
    data["Sales_Lag_2"] *= sales_factor
    data["Customer_Count"] += cust_adjust
    pred = model.predict(data)[0]
    stock = 28 if pred >= 500 else 12
    print(f"{cafe_id} 9 AM June 30: {pred} rupees, {stock} samosas")

for cafe, factor, cust in [("Cafe1", 1.0, 0), ("Cafe2", 1.1, 2), ("Cafe3", 0.9, -2), ("Cafe4", 0.8, -3)]:
    forecast_cafe(cafe, factor, cust)

Output:

Cafe1 9 AM June 30: 675.0 rupees, 28 samosas
Cafe2 9 AM June 30: 742.5 rupees, 28 samosas
Cafe3 9 AM June 30: 607.5 rupees, 28 samosas
Cafe4 9 AM June 30: 540.0 rupees, 28 samosas

All cafés grow—expansion feasible. Day 55 scales this.

Profit Forecast

Estimate June profit:

def calculate_profit(actual_sales, predicted_sales, stock, cost_per_samosa=10, price_per_samosa=20):
    stock = np.where(predicted_sales >= 500, 28, 12)
    demand = actual_sales // 20
    sold = np.minimum(demand, stock)
    revenue = sold * price_per_samosa
    cost = stock * cost_per_samosa
    return revenue - cost

profit = calculate_profit(np.array([675]), np.array([675]), 28).sum()
print(f"June 30 9 AM Profit: {profit} rupees")

Output:

June 30 9 AM Profit: 210 rupees

Profitable—supports growth. Day 55 profits this.

Why Long-Term Forecasting?

  • Strategy: 675-rupee forecast—expansion justified.
  • Growth: 18.5 Customer_Count—new café viable.
  • Scale: 33 to 1000 rows—multi-café planning.

Complements 450-rupee forecast, optimization—growing café. Day 55 plans this.

Real-World Forecasting

Retail forecasts demand—stores planned. Cities predict traffic—roads built. Priya’s forecasting is her café’s roadmap—small, visionary. Day 55 mirrors this.

Challenges

  • Small Data: 33 rows—long-term trends noisy.
  • Uncertainty: June 2025 weather—impacts 675 rupees?
  • Cost: Expansion on May 25, 2025—financial risk?

More data—Priya scales. Day 55 notes this.

Why This Matters

Forecasting 675 rupees—28 samosas, 210-rupee profit—guides Priya’s café growth. Without it, plans falter; with it, she expands—profit up. Scaled, forecasting shapes economies—lives enriched. Day 55 envisions her.

Recap Summary

Yesterday, Day 54 optimized—mean absolute error 2.9, 450 rupees, 1800-rupee profit. Today, Day 55 forecasted—mean absolute error 2.9, 675 rupees for June, 210-rupee profit. It’s her plan step.

What’s Next

Tomorrow, in Day 56, we’ll diversify: Can Priya add new items? Predict menu trends? We’ll explore menu diversification, enhancing her café. Join us with curiosity!

Author

More From Author

Indian Clothing

Article 74: Bharat Is Not for Beginners – Sacred Threads: The Symbolism, Science, and Society of Indian Textiles and Clothing

Bus Fire Epsom

Bus Destroyed by Fire in Epsom, Auckland

Leave a Reply

Your email address will not be published. Required fields are marked *