Cyclical Encoding: Stop One-Hot Encoding Months
Time features are circular, not linear. December and January are neighbours - one-hot makes them unrelated. Encode the position on a unit circle instead.
TL;DR: Time features are circular, not linear. Encode truly cyclical variables - month, hour, weekday, day of year - as two coordinates on a unit circle: sin(2π × value / period) and cos(2π × value / period). The pair makes December and January neighbours and uniquely identifies the position around the cycle, because a single sine value is ambiguous. Use it always for neural networks and linear models; for tree models, test both and pick the better cross-validation. When the pattern is not smooth, use a binary flag.
Visual Summary
The Problem
A common feature-engineering mistake with cyclical variables is encoding them as flat categories. With one-hot encoding for months, the model is told that January and December are completely unrelated - but in the calendar they are neighbours.
For truly cyclical features - hour of day, day of week, month of year, day of year - the structure is circular, not linear. The encoding should say so. One-hot removes false order, but it also removes cyclical closeness.
The Approach
The better representation is to encode the position on a unit circle instead of a line. Replace one raw month column with two cyclical coordinates:
The two-line fix
month_sin = sin(2π × month / 12)
month_cos = cos(2π × month / 12)
Each month becomes a point on a unit circle, and December and January are adjacent in feature space, so the model can see how close they are.
Why two columns
One sine value is not enough - different months can share the same sine position. The sine + cosine pair uniquely represents the angle around the cycle: one coordinate is a projection, two coordinates define the cycle.
When to use cyclical encoding
Use it when the feature has a known repeating period, meaningful order, and a wrap-around relationship - and distance between values matters to the model. For neural networks and linear models, always use cyclical encoding for time features.
When NOT to use it
Skip it when the feature is not truly cyclical (year is not cyclical), or when the pattern is not smooth - for example a sales spike only in December, where a binary flag is the better feature. For tree models with enough data, trees can learn splits per month: test both representations and pick whichever gives better cross-validation.
The Outcome
- Neural networks and linear models: always encode time features cyclically.
- Tree models (XGBoost, LightGBM): test both representations and pick the one that wins on the same validation windows.
- Spiky, single-period patterns: prefer a binary flag over sin/cos.
Key Takeaway
Design insight: Time features are circular, not linear. Encode truly cyclical variables - month, hour, weekday, day of year - as two coordinates on a unit circle: sin(2π × value / period) and cos(2π × value / period). The pair makes December and January neighbours and uniquely identifies the position around the cycle, because a single sine value is ambiguous. Use it always for neural networks and linear models; for tree models, test both and pick the better cross-validation. When the pattern is not smooth, use a binary flag.
FAQ
When should I use cyclical encoding instead of one-hot for months?
Use it whenever the feature has a known repeating period and a wrap-around relationship - month of year, hour of day, day of week, day of year. Encode each value as a pair sin(2π × value / period), cos(2π × value / period) so December and January become neighbours in feature space. For neural networks and linear models, always encode time features cyclically.
Should I use cyclical sin/cos encoding for tree models like XGBoost or LightGBM?
Not always. Trees can learn a split for each month when they have enough data, so the gain is often small - test both representations and pick whichever wins cross-validation. Also skip sin/cos when the pattern is not smooth, such as a sales spike that only happens in December: a binary flag is the better feature.