churnguard / src /feature_engineering.py
OmarGamal48812's picture
Upload folder using huggingface_hub
d9b2b72 verified
Raw
History Blame Contribute Delete
3.08 kB
"""Feature engineering module for E-Commerce Churn dataset."""
import pandas as pd
import numpy as np
def create_features(df: pd.DataFrame) -> pd.DataFrame:
"""Create new features from the cleaned dataset.
New features:
1. tenure_bucket β€” categorical binning of Tenure
2. engagement_score β€” HourSpendOnApp * OrderCount
3. cashback_per_order β€” CashbackAmount / OrderCount
4. is_recent_buyer β€” 1 if DaySinceLastOrder <= 3
5. has_multi_device β€” 1 if NumberOfDeviceRegistered >= 4
6. is_high_spender β€” 1 if OrderAmountHikeFromlastYear > 20
"""
df = df.copy()
# 1. Tenure bucket
bins = [0, 6, 12, 24, np.inf]
labels = ["new", "settling", "established", "loyal"]
df["tenure_bucket"] = pd.cut(df["Tenure"], bins=bins, labels=labels, include_lowest=True)
# 2. Engagement score
df["engagement_score"] = df["HourSpendOnApp"] * df["OrderCount"]
# 3. Cashback per order (handle division by zero)
df["cashback_per_order"] = np.where(
df["OrderCount"] > 0,
df["CashbackAmount"] / df["OrderCount"],
0,
)
# 4. Is recent buyer
df["is_recent_buyer"] = (df["DaySinceLastOrder"] <= 3).astype(int)
# 5. Has multi device
df["has_multi_device"] = (df["NumberOfDeviceRegistered"] >= 4).astype(int)
# 6. Is high spender
df["is_high_spender"] = (df["OrderAmountHikeFromlastYear"] > 20).astype(int)
return df
def encode_features(df: pd.DataFrame) -> pd.DataFrame:
"""Encode categorical variables.
Label encoding: Gender, MaritalStatus, tenure_bucket
One-hot encoding: PreferredLoginDevice, PreferredPaymentMode, PreferedOrderCat
"""
df = df.copy()
# Label encoding
label_maps = {
"Gender": {"Male": 0, "Female": 1},
"MaritalStatus": {"Single": 0, "Married": 1, "Divorced": 2},
"tenure_bucket": {"new": 0, "settling": 1, "established": 2, "loyal": 3},
}
for col, mapping in label_maps.items():
df[col] = df[col].map(mapping)
# One-hot encoding
ohe_cols = ["PreferredLoginDevice", "PreferredPaymentMode", "PreferedOrderCat"]
df = pd.get_dummies(df, columns=ohe_cols, drop_first=True, dtype=int)
return df
def engineer_features(df: pd.DataFrame) -> pd.DataFrame:
"""Run the full feature engineering pipeline.
Steps:
1. Create 6 new features
2. Encode categorical variables
Returns:
Feature-engineered DataFrame ready for modeling.
"""
df = create_features(df)
df = encode_features(df)
return df
if __name__ == "__main__":
from data_cleaning import load_raw_data, clean
raw = load_raw_data()
cleaned = clean(raw)
print(f"Cleaned shape: {cleaned.shape}")
engineered = engineer_features(cleaned)
print(f"Engineered shape: {engineered.shape}")
print(f"\nColumns:\n{engineered.columns.tolist()}")
print(f"\nDtypes:\n{engineered.dtypes}")
engineered.to_csv("data/processed/engineered.csv", index=False)
print("\nSaved to data/processed/engineered.csv")