5-Type Seasonality Classification: How the Algorithm Distinguishes Peak, Off-Season, and False Signals
Complete seasonality classification algorithm: 52-week profiling with exponential year-over-year decay, low variability detection (±30% threshold), adjacent peak merging, year-boundary wraparound handling, and 5 types for every product-week combination.
Seasonality is the most underestimated factor in inventory management. Most ERP systems know that "winter products sell in winter." But that's useless for a buyer who needs to understand: is this product at peak now, already declining, or hasn't reached its peak yet? Should they discount or wait? Are zero sales dead stock or just off-season?
Our seasonality engine solves this through a 5-type classification: every product-week combination receives one of 5 types that determines what demand phase it's in. This isn't an abstract metric — the seasonality type directly drives markdown logic, procurement decisions, and dead stock detection.
52-Week Profile with Exponential Decay
For every SKU, a demand profile is built across 52 ISO-year weeks. But data from different years isn't equally valuable: last year's pattern matters more than the year before, because markets change — competitors appear, products exit, buyer habits shift.
We apply exponential decay by year:
- •Current year: weight ≈ 1.0
- •1 year ago: weight ≈ 0.61
- •2 years ago: weight ≈ 0.37
- •3 years ago: weight ≈ 0.22
Practically this means: if a product peaked in week 46 for three consecutive years but shifted to week 44 this year — the profile reflects the shift rather than clinging to the outdated pattern. But if current-year data is sparse (new product), the historical profile provides stability.
For missing weeks (new products, data gaps), zero-interpolation is applied: the value is calculated as the average of neighboring weeks to prevent artificial spikes or drops in the profile.
Low Variability Detection (Flat Detection)
Before applying any seasonal classification, the system checks: does seasonality even exist? The criterion: if 75% or more of weeks fall within the [0.7, 1.3] range relative to the annual mean, the product is classified as flat — no pronounced seasonality.
This is critically important for retail assortment. Many basic everyday products — cleaning supplies, batteries, bandages, basic hygiene items — have genuinely flat demand year-round. Applying a seasonal model to these products creates phantom peaks and valleys that lead to bad ordering: overstocking before a "peak" that doesn't exist, and stockouts during an "off-season" that isn't one.
In our retail analysis, ~37% of SKUs were classified as flat. This means over a third of the assortment should be forecast with simple trend models, not forced through seasonal decomposition.
5 Seasonality Types
Every SKU × ISO-week combination is classified into one of 5 types:
| Type | Code | Criterion | Example |
|---|---|---|---|
| Off-season | 0 | Below seasonal threshold | Sunscreen in December |
| Peak | 1 | Above 90th percentile of annual profile | Cold remedies in week 46 |
| High season | 2 | Above 60th percentile | Allergy products in week 16 |
| Discount window | 3 | 2 weeks after end of high/peak block | Cold remedies after flu season |
| Spot | 4 | Elevated demand block ≤ 3 weeks, isolated from main seasonal block | One-time promo spike |
Adjacent Peak Merging (Cyclical Bridging)
Seasonal demand rarely runs as a smooth plateau — it pulsates. Within a peak season, there can be brief 1-2 week dips (holidays, weekends, weather anomalies). A naive classification would mark these dips as "off-season," fragmenting the seasonal block.
The algorithm solves this through adjacent peak merging: if two peak/high blocks are separated by a gap of 4 weeks or fewer, they're merged into one continuous block. Intermediate weeks receive type "high season" (2) instead of "off-season" (0).
This prevents the system from making bad decisions: without merging, a buyer would receive a "season ended" alert (and markdown recommendation) in the middle of an ongoing peak.
Year-Boundary Wraparound
A critical edge case: flu season. The peak begins around weeks 46-48 and continues through weeks 4-8 of the next year. Naive week-1-to-52 classification treats this as two separate seasons: one at year-end (46-52) and another at year-start (1-8).
The engine handles year-boundary wraparound: during classification, the system checks whether a peak at weeks 50-52 is a continuation of a peak at weeks 1-4. If so, the entire 50→4 block is recognized as one continuous season. This ensures that:
- Markdowns aren't recommended between December 31 and January 1 in the middle of flu season - Procurement is planned for the entire continuous peak, not two fragments - The controller agent doesn't flag January sales as anomalous
Automatic Discount Window Generation (Type 3)
After every peak or high block ends, the system automatically creates a 2-week discount window (type 3). The logic: when a peak ends, stock purchased for peak demand remains. If not sold quickly, it becomes dead stock for the entire off-season period.
Type 3 directly drives the pricing agent: products in type 3 receive a recommended discount of 25% (long block) or 15% (short block). This is post-peak clearance tied to seasonality mathematics, not buyer intuition.
Spot Pattern Detection (Type 4)
The spot type is for isolated demand spikes unrelated to the main season. Criterion: an elevated demand block of 3 weeks or fewer, separated from the nearest seasonal block. Typical cause: a one-time promotion, marketing campaign, or seasonal holiday.
Why this matters: the controller agent uses type 4 to prevent false purchases. If the forecast shows rising demand but the seasonality engine classified the corresponding period as spot — the controller warns: "this is a one-time spike from last year, not a recurring pattern. Verify before ordering."
How Seasonality Drives Other Modules
The 5-type classification isn't an end in itself. It serves as input for three critical systems:
1. Dead stock detection. Criterion #2 in the 4-criteria filter: a product isn't considered dead if its current week is type 0 (off-season). Allergy products with zero sales in January aren't dead — they're sleeping. Without seasonal context, the system would recommend liquidating seasonal inventory — a double loss.
2. Purchase recommendations. The procurement engine looks 4 weeks ahead (PURCHASE_RECOMMENDATIONS_WEEKS_AHEAD = 4): if type 1 (peak) or type 2 (high season) appears in the next 4 weeks, and current stock is under 30 days (TARGET_DAYS = 30) — a purchase recommendation is generated.
3. Markdowns. Type 3 → 25% discount (post-peak clearance). Type 4 → 15-25% (spot window). Dead stock in-season (types 1-2 with >30 day supply) → 25%. Dead stock out-of-season → 50%.
Results: Retail Chain
On data from 1,000 SKUs in a retail chain:
- •37% of SKUs — flat seasonality (no pronounced seasonal patterns)
- •28% of SKUs — one pronounced seasonal peak (type 1)
- •19% of SKUs — extended high season (type 2, >8 weeks)
- •9% of SKUs — dual season (spring + fall, typical for allergy products)
- •7% of SKUs — spot patterns (type 4, promo-dependent)
Longest continuous peak block: 16 weeks (cold remedies, week 44 → week 8 via year-boundary). Shortest spot block: 1 week (one-time promotion).
Key Takeaways
- •±30% threshold for flat detection prevents applying seasonal models to products with flat demand — an error that creates phantom peaks and stockouts.
- •5-type classification turns abstract seasonality into concrete business actions: buy, markdown, wait, or transfer.
- •Peak merging with gap ≤ 4 weeks prevents the system from fragmenting a seasonal block.
- •Year-boundary wraparound is critical for winter categories with peaks spanning New Year.
- •Type 4 (spot) protects against false purchases based on one-time promo spikes from the previous year.
Research & Insights
Start free audit