Boosting Insurance Revenue with Machine Learning: A Cross Sell Prediction Solution
Cross selling, or selling an additional product or service to an existing customer, is a core growth strategy for many businesses – and the insurance industry is no exception. If an auto insurance policyholder also buys homeowners insurance from the same carrier, the carrier benefits from increased revenue and the customer benefits from bundling discounts and a more streamlined experience.
But with a large customer base, how can insurers predict which customers are most likely to buy an additional policy? The answer lies in machine learning. By analyzing past customer behavior, machine learning models can identify patterns and predict future cross sell opportunities with a high degree of accuracy.
In this article, we‘ll walk through the steps of building a cross sell prediction model, using an auto insurance use case. Whether you‘re relatively new to data science or a seasoned practitioner, this end-to-end solution will deepen your understanding of key machine learning concepts and provide a template for solving similar business problems.
Problem Statement
To frame our business problem as a data science problem, let‘s say we work for an auto insurance company that wants to expand its customer base for other insurance products like homeowners insurance. Our goal is to build a model that predicts which of our existing auto insurance customers are most likely to also buy homeowners insurance from us.
We have a dataset of past customer data, including information like age, location, policy details, claims history, and whether or not the customer purchased homeowners insurance from us. We‘ll use this historical data to train a binary classification model to predict the probability of a customer buying homeowners insurance.
Some initial hypotheses we might want to test:
- Customers who bundle auto and homeowners policies get a discount, so price-sensitive customers may be more likely to cross sell
- Customers who own homes are more likely to buy homeowners insurance compared to renters
- Customers with a history of auto claims may be more risk-averse and inclined to buy other insurance products
- Married customers and customers with children may be in more stable life stages and open to additional policies
Exploratory Data Analysis
With our problem framed, let‘s dig into the data. We‘ll start with exploratory data analysis to get a sense for what the data contains, check for missing values and outliers, view correlations between variables, and test our initial hypotheses.
Key steps:
- Read in the data from CSV files into Pandas dataframes
- Merge datasets if needed, keeping track of training vs test data
- Examine data types, summary statistics, and check for missing/infinite values
- Visualize distributions of individual variables and potential relationships between them, especially with respect to the target variable
- Formulate additional hypotheses to test based on insights from EDA
Code sample for correlation heatmap:
import seaborn as sns
correlations = data.corr()
sns.heatmap(correlations, cmap="coolwarm", annot=True)

Data Cleaning & Preparation
Now that we‘re familiar with our data, we need to clean and preprocess it to get it ready for modeling. This involves steps like:
- Removing or imputing missing values
- Encoding categorical variables as numbers
- Feature scaling
- Splitting data into train, validation, and test sets
Since our target variable is binary (1 if customer bought homeowners insurance, 0 if not), we also need to check if our classes are imbalanced. If one outcome is much rarer than the other, we‘ll need to use techniques like oversampling the minority class or adjusting class weights.
Code for splitting data:
from sklearn.model_selection import train_test_split
X = data_cleaned.drop(‘bought_homeowners_insurance‘, axis=1)
y = data_cleaned[‘bought_homeowners_insurance‘]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=42)
Feature Engineering
With clean, preprocessed data in hand, we can now turn our attention to feature engineering. The goal is to create new variables that aren‘t in the original data but that can improve the predictive power of our model.
Some examples:
- Interaction terms that combine two variables (like age * income)
- Grouping levels of categorical variables
- Ratios or other mathematical transformations
- Binning continuous variables
- Domain-driven features (like customer lifetime value)
Ultimately, the features you create will depend on your unique dataset and business domain, but the overarching goal is to leverage your data in sophisticated ways to uncover patterns.
Code for grouping rare categorical levels:
Vehicle_Age_counts = data[‘Vehicle_Age‘].value_counts()
threshold = 200
rare_levels = Vehicle_Age_counts[Vehicle_Age_counts < threshold].index
data[‘Vehicle_Age_grouped‘] = data[‘Vehicle_Age‘].apply(lambda x: "Other" if x in rare_levels else x)
Model Training & Tuning
Now the fun part – actually building our predictive models! Because this is a binary classification task, we have many options of algorithms to try:
- Logistic regression
- Decision trees & random forests
- XGBoost
- Support vector machines
- Neural networks
- And more
We don‘t necessarily need to try every model type, but it‘s good practice to experiment with at least a few to see which performs best. We also want to tune the hyperparameters of our models to eke out incremental performance gains.
Key steps:
- Fit models on training data
- Make predictions on validation data
- Evaluate performance and compare models
- Tune hyperparameters using techniques like grid search
- Select final model
- Evaluate final model on held-out test set
Code for training and evaluating models:
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
rf = RandomForestClassifier(n_estimators=100, random_state=42)
params = {
‘max_depth‘: [5, 10, None],
‘min_samples_split‘: [2, 5, 10]
}
rf_grid = GridSearchCV(estimator=rf,param_grid=params,cv=5,n_jobs=-1,verbose=2)
rf_grid.fit(X_train,y_train)
print("Best parameters: {}".format(rf_grid.bestparams))
from sklearn.metrics import roc_auc_score
preds_val = rf_grid.predict_proba(X_val)[:,1]
print("Validation AUC: {}".format(roc_auc_score(y_val,preds_val)))
Model Insights & Interpretation
Once we‘ve trained a high-performing model, we want to open the black box and interpret what it has learned. This often involves examining feature importances, partial dependence plots, and SHAP values to understand how the model is making predictions.
Model interpretability is crucial because:
- It can surface new insights about customer behavior and lead to better business decisions
- It allows us to check if the model is making decisions for the right reasons based on domain knowledge
- In regulated industries like insurance, we may need to justify the model‘s decisions to stakeholders
Code for visualizing feature importances:
import matplotlib.pyplot as plt
importances = rf_grid.bestestimator.featureimportances
indices = np.argsort(importances)[::-1]
features = X_train.columns
plt.figure(figsize=(10,6))
plt.title("Feature importances")
plt.bar(range(X_train.shape[1]), importances[indices])
plt.xticks(range(X_train.shape[1]), features[indices], rotation=60, ha = ‘right‘)
plt.show()

Business Impact & Next Steps
We‘ve done it! We‘ve built a highly predictive cross sell model. But our work isn‘t over. To actually achieve business impact, we need to integrate our model into existing marketing systems and processes. This involves:
- Saving out the model file and writing code to load it and make predictions on new data
- Working with business partners to design a contact strategy for customers most likely to cross sell
- Monitoring the model‘s performance over time as new data comes in
- Retraining the model periodically so it remains accurate
Future improvements to the model could include leveraging additional data sources, trying more sophisticated techniques like stacked ensembles, or expanding predictions to other product lines. The opportunities are endless – which is what makes this work so exciting!
Conclusion
In this article, we walked through the key steps of building a machine learning model to predict which auto insurance customers are likely to also buy homeowners insurance:
- Defining the business problem
- Exploring and cleaning the data
- Engineering informative features
- Training and tuning models
- Interpreting the model‘s predictions
- Deploying the model to drive business decisions
While the specific dataset and use case were focused on insurance, the same process can be adapted to cross sell prediction problems across industries. The key is letting the data guide your decisions while keeping the business context front and center.
Especially as models become more complex, it‘s critical to stay grounded in the "why" behind the data science. Cross sell models are ultimately about surfacing customer needs and delivering value through timely, relevant product suggestions. Done responsibly, it‘s a win-win for the business and the customer.
I hope this article has given you a practical framework for tackling cross sell prediction, along with the confidence to implement machine learning solutions. Remember, the hardest part is often just getting started. Happy modeling!