๐ Date Features
Date Features in KDP
Turn date strings into cyclical encodings your model can actually learn from.
๐ Overview
A date is a string until you encode it. KDP parses the column, splits it into year, month, day of month and day of week, and encodes each one cyclically — as a sine/cosine pair — so December and January sit next to each other rather than at opposite ends of a number line. Optionally it adds a one-hot season.
๐ Basic Usage
The shorthand is enough for most columns:
from kdp import PreprocessingModel, FeatureType
preprocessor = PreprocessingModel(
path_data="data.csv",
features_specs={
"signup_date": FeatureType.DATE,
},
)
preprocessor.build_preprocessor()
Use the class when you need to set an option:
from kdp import PreprocessingModel
from kdp.features import DateFeature, FeatureType
preprocessor = PreprocessingModel(
path_data="data.csv",
features_specs={
"signup_date": DateFeature(
name="signup_date",
feature_type=FeatureType.DATE,
format="YYYY-MM-DD", # or "YYYY/MM/DD", each with an optional time
add_season=True, # append a 4-dim one-hot season
),
},
)
preprocessor.build_preprocessor()
โ๏ธ Configuration Parameters
DateFeature takes exactly two options. Anything else you pass is accepted
and not used, and says so in a warning.
| Parameter | Type | Default | Description |
|---|---|---|---|
format |
str | "YYYY-MM-DD" |
Layout of the date string. Dates are read as year, then month, then day, separated by - or /, and may be followed by a time -- "%Y-%m-%d", "%Y/%m/%d", "%Y-%m-%d %H:%M:%S" and "YYYY-MM-DD" all describe a column this reads. A day-first or month-first format is refused where you write it. date_format is accepted as a synonym. |
add_season |
bool | False |
Append a 4-dimensional one-hot season vector to the encoding. |
Other date options do not exist
Earlier documentation listed options such as add_year, add_month,
add_day_of_week, add_hour, add_is_weekend, add_quarter,
cyclical_encoding, add_time_since_reference, reference_date and
time_since_unit. None of them are read by KDP. DateFeature accepts
arbitrary keyword arguments, and only output_format and extract are
called out in a warning; the rest pass without a word and change nothing.
Year, month, day of month and day
of week are always extracted and always cyclically encoded; that
is not configurable. For anything beyond that, use a
custom preprocessing pipeline.
๐ What You Actually Get
Each date column expands to a fixed-width block of floats:
| Configuration | Output width | Components |
|---|---|---|
| Default | 8 | year, month, day of month, day of week — each as a (sin, cos) pair |
add_season=True |
12 | the 8 above, plus a 4-dim one-hot season |
import tensorflow as tf
# With add_season=True, "2021-06-15" encodes to 12 values:
# [sin_year, cos_year, sin_month, cos_month,
# sin_day, cos_day, sin_dow, cos_dow,
# season_0, season_1, season_2, season_3]
output = preprocessor.model({"signup_date": tf.constant([["2021-06-15"]])})
print(output.shape) # (1, 12)
Why cyclical encoding
Month 12 and month 1 are one step apart in reality but eleven apart as
integers. Encoding each component as (sin, cos) places them adjacent on a
circle, so a model can learn "end of year rolls into start of year" without
having to memorise the discontinuity.
๐ Combining With Other Features
Feature selection
Date features participate in learned feature selection:
from kdp import FeatureType, PreprocessingModel
preprocessor = PreprocessingModel(
path_data="data.csv",
features_specs={
"signup_date": FeatureType.DATE,
"amount": FeatureType.FLOAT_NORMALIZED,
},
feature_selection_placement="date", # or "all_features"
feature_selection_units=32,
feature_selection_dropout=0.2,
)
Valid feature_selection_placement values are "none", "numeric",
"categorical", "text", "date" and "all_features".
Crossing a date with a categorical
from kdp import FeatureType, PreprocessingModel
preprocessor = PreprocessingModel(
path_data="data.csv",
features_specs={
"signup_date": FeatureType.DATE,
"channel": FeatureType.STRING_CATEGORICAL,
},
feature_crosses=[("signup_date", "channel", 10)],
)
๐ ๏ธ Going Beyond the Built-in Encoding
Need hour-of-day, a weekend flag, or days since a reference date? Those are
not built in. Supply your own layers with preprocessors, which receives the
raw string column:
import keras
from kdp.features import DateFeature, FeatureType
DateFeature(
name="signup_date",
feature_type=FeatureType.DATE,
preprocessors=[MyDateParsingLayer, keras.layers.Dense],
units=16, # forwarded to Dense
)
See Custom Preprocessing Pipelines for
how preprocessors and forwarded keyword arguments work.
โฑ๏ธ Dates vs. Time Series
A DATE feature encodes one timestamp per row, independently. If you need
lags, rolling statistics or differencing across ordered rows, that is a
Time Series Feature — where a date column
serves as the sort_by key rather than as a feature itself.
๐ก Practical Notes
Keep dates as strings in your CSV
KDP parses the string itself. Pre-converting to epoch integers turns the column numeric and skips date handling entirely.
Match the format exactly
Only YYYY-MM-DD and YYYY/MM/DD parse. Normalise other layouts before writing the CSV.
add_season is cheap
Four extra dimensions, no statistics needed. Worth enabling when seasonality plausibly matters.
Dates need no statistics pass
The encoding is deterministic, so nothing is learned from your data for this column.