The features you create often matter more than the model you pick. Extract signal from dates, combine columns, and bin values into features a model can use.
Why: a good feature hands the model signal it could not otherwise find — often improving results more than swapping algorithms. When: engineer features using domain knowledge about what actually drives the target. Where: this is the highest-leverage, most creative part of the ML pipeline.
Ways to create features:
extract a timestamp -> hour, day-of-week, is_weekend, month
combine price + quantity -> total; height + weight -> BMI
aggregate per-user mean/count/recency from event logs
bin continuous age -> child / adult / senior
interact feature_A * feature_B when they matter together
Domain knowledge > cleverness. Ask "what would a human use to decide?"Why: a raw timestamp is useless to most models, but the hour, day of week, or "is weekend" hidden inside it is highly predictive for many problems. When: explode every datetime column into its informative parts. Where: use the pandas .dt accessor for vectorized extraction.
import pandas as pd
df["ts"] = pd.to_datetime(df["ts"])
df["hour"] = df["ts"].dt.hour
df["dayofweek"] = df["ts"].dt.dayofweek # 0 = Monday
df["is_weekend"] = (df["ts"].dt.dayofweek >= 5).astype(int)
df["month"] = df["ts"].dt.monthWhy: derived ratios and totals often carry more signal than their parts, and binning a continuous value into groups can expose a non-linear relationship. When: combine columns that interact (price × quantity), bin when the effect is stepwise not smooth. Where: pd.cut makes labeled bins; keep engineering logic in functions so it applies identically to train and test.
import pandas as pd, numpy as np
# Combine:
df["total"] = df["price"] * df["quantity"]
# Bin a continuous feature into ordered groups:
df["age_group"] = pd.cut(
df["age"], bins=[0, 12, 18, 65, np.inf],
labels=["child", "teen", "adult", "senior"],
)
print(df["age_group"].value_counts())