Holiday Package Purchase Prediction

Overview

Built an end-to-end binary classification model using Random Forest to predict customer holiday package purchase behaviour — covering data cleaning, feature encoding, exploratory data analysis, model training, and evaluation.

Problem statement

"Trips & Travel.Com" wants to expand its customer base by offering a new Wellness Tourism Package. Historically, 18% of contacted customers purchased a package, but marketing costs were high because contacts were random. The goal is to use available customer data to predict which customers are likely to purchase a package and therefore make marketing spend more efficient.

Data collection

The dataset (20 columns, 4,888 rows) is sourced from Kaggle. Key columns include demographic information, contact/pitch details, income, number of previous trips, and whether the product was taken (ProdTaken).

Data cleaning & feature engineering

  • Fixed inconsistent categorical labels (e.g. Fe Male → Female, Single → Unmarried).
  • Imputed missing values: median for numeric columns (Age, DurationOfPitch, NumberOfTrips, MonthlyIncome), mode for categorical columns (TypeofContact, NumberOfFollowups, PreferredPropertyStar, NumberOfChildrenVisiting).
  • Dropped CustomerID and created TotalVisiting = NumberOfPersonVisiting + NumberOfChildrenVisiting.
  • Encoded categorical variables with label encoding prior to modeling.

Modeling

Used a Random Forest classifier with randomized hyperparameter search (RandomizedSearchCV) and cross-validation to find strong hyperparameters. Final model evaluated on a held-out test set with metrics including accuracy, precision, recall, F1 and ROC-AUC.

Model performance dashboard screenshot
Feature importance chart ROC curve

Key code (excerpt)

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split, RandomizedSearchCV

X = df.drop(['ProdTaken'], axis=1)
y = df['ProdTaken']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

rf = RandomForestClassifier()
rf_params = {
    'n_estimators':[100,200,500,1000],
    'max_depth':[5,8,15,None,10],
    'max_features':[5,7,'auto',8],
    'min_samples_split':[2,8,15,20]
}
rand_search = RandomizedSearchCV(rf, rf_params, n_iter=50, cv=3, n_jobs=-1)
rand_search.fit(X_train, y_train)

best = rand_search.best_estimator_
# evaluate on test set and plot ROC

Highlights

  • Model ROC-AUC ≈ 0.86 (example result from validation).
  • Top predictors include Age, Income, and PastPurchases (see feature importance).
  • Full reproducible notebook available on GitHub.

View the code and notebook on GitHub

← Back to portfolio