Cyclical feature encoding and the midnight paradox

A few months back I was looking at a dashboard for a high-traffic client. They were predicting hourly sales to size their server scaling, classic AWS Lambda territory. Every night at midnight their accuracy fell off a cliff. Customers had not stopped buying. The model just saw a huge gap between 23:59 and 00:01, because it was treating time as a straight line when time is a circle. That is the problem cyclical feature encoding solves.

I call it the “midnight paradox.” Feed the model an integer for the hour, 0 to 23, and it assumes 23 sits a long way from 0. The jump from 23 to 0 reads like a cliff even though the two points are two minutes apart. Anyone who has wrestled with better WordPress data processing for time-series logs knows how annoying these boundary errors get.

Why your model is time-blind

Most models, from a simple linear regression to a deep neural network, read numbers as distances along a line. Cyclical feature encoding stops you asking the model to learn that 0 follows 23. You map the time onto coordinates on a circle instead, something like latitude and longitude for a clock face. That matters when you are optimizing WooCommerce REST API performance and time-based data carries most of your analytics.

Years ago my first thought was to one-hot encode the hours. Twenty-four binary columns, job done. For some models it makes things worse. You throw away the proximity information: 2 AM is no longer near 3 AM as far as the model is concerned, they are two unrelated categories. Your dimensionality also balloons, which is no help when you are chasing performance.

Trigonometric mapping

The fix is a sine and cosine transformation. Calculate both and every time point gets a unique (x, y) coordinate on a unit circle, so 23:59 and 00:01 sit close together in the feature space. The same trick handles any repeating pattern, whether that is days, weeks or wind direction. The math is in the NumPy documentation, and scikit-learn’s approach to periodic features is worth a read too.

# Example of bbioon_cyclical_encoding in Python
import numpy as np
import pandas as pd

def bbioon_encode_time(df, col, max_val):
    # Map the value to a circle (0 to 2*pi)
    df[col + '_sin'] = np.sin(2 * np.pi * df[col] / max_val)
    df[col + '_cos'] = np.cos(2 * np.pi * df[col] / max_val)
    return df

# Assuming 'hour' column exists from 0-23
# We use 24 as the max_val for hours
# This ensures midnight and 11PM are adjacent
data = pd.DataFrame({'hour': range(24)})
encoded_data = bbioon_encode_time(data, 'hour', 24)

Do not use sine on its own. With sine alone, 6 AM and 6 PM come out to the same value, and the model confuses the morning rush with the evening commute. Both coordinates together are what give each hour a unique fingerprint on the circle. It is a well-worn feature engineering trick that plenty of senior devs keep in their back pocket.

What it did for the client

When we put cyclical feature encoding in for that client, their RMSE (root mean squared error) dropped straight away. We had not touched the model architecture. We just stopped handing it a bad representation of time. It helps most with distance-based models like KNN and SVM, though tree-based models like XGBoost also pick up the patterns faster.

Time features get messy fast. If you are tired of debugging someone else’s mess and you want your data strategy to hold up, send me a message. I have probably seen it before and fixed it twice.

The short version

  • Linear encoding puts a fake cliff at the start and end of every cycle.
  • One-hot encoding drops the relationship between adjacent time points.
  • Trigonometric mapping keeps both proximity and unique identity.
  • Sine only works paired with cosine, or symmetry ruins the feature.

Next time your predictions look strange around the start of the week or the end of the day, check the features first. If you are treating a circle like a line, that is where to start.

author avatar
Ahmad Wael
I'm a WordPress and WooCommerce developer with 15+ years of experience building custom e-commerce solutions and plugins. I specialize in PHP development, following WordPress coding standards to deliver clean, maintainable code. Currently, I'm exploring AI and e-commerce by building multi-agent systems and SaaS products that integrate technologies like Google Gemini API with WordPress platforms, approaching every project with a commitment to performance, security, and exceptional user experience.