Skip to Content
Course content

104: Churn Prediction Modeling in R

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you run a local gym. You don't wait until a member cancels their subscription to realize they're unhappy; you notice the "red flags" first. Maybe they stopped coming three times a week and now only show up once every ten days. Maybe they stopped booking the high-energy spin classes they used to love. Or maybe they've stopped chatting with the trainers. By the time they actually hand in the cancellation form, it's too late to save them. You're looking for the behavioral signals that precede the exit.

Churn prediction in R is exactly that, just at scale. Instead of watching a gym door, we're watching data points. Here is how those gym red flags map to our model:

  • The Frequency Drop → This is our usage_frequency feature (e.g., logins per month).
  • The Feature Abandonment → This is feature_engagement (e.g., did they stop using the premium dashboard?).
  • The Silence → This is support_tickets (either a spike in complaints or a total drop in engagement).
  • The Cancellation → This is our churn target variable (a binary 1 or 0).

Translating Behavior into a Logistic Model

Since we are predicting a binary outcome—either they stay or they go—a standard linear regression won't cut it. You can't have a "0.7 churn." You're either out the door or you're not. That's why we use Logistic Regression via the glm() function (Generalized Linear Model).

I've found that most people overcomplicate the setup. Keep it lean. Let's assume we have a dataframe called customer_data with columns for monthly_spend, tenure, and support_calls.

# We use family = "binomial" to tell R this is a logistic regression
churn_model <- glm(churn ~ monthly_spend + tenure + support_calls, 
                   data = customer_data, 
                   family = "binomial")

# Let's see which 'red flags' actually matter
summary(churn_model)

When you run that summary, don't get bogged down in every single number. Look at the Pr(>|z|) column. If the p-value is tiny (usually < 0.05), that variable is a significant predictor. If support_calls has a massive positive coefficient and a low p-value, you've just mathematically proven that more complaints lead to higher churn.

Turning Probabilities into Decisions

One thing that trips people up is that predict() doesn't give you a "Yes" or "No." It gives you a probability between 0 and 1. If the model says a customer has a 0.62 probability of churning, is that enough to trigger a discount email? That's a business decision, not a coding one.

Usually, we set a threshold (often 0.5). If the probability is above that, we flag them as "At Risk."

# Predict probabilities for our test set
probabilities <- predict(churn_model, newdata = test_data, type = "response")

# Convert those probabilities into hard classifications
predictions <- ifelse(probabilities > 0.5, 1, 0)

# Now, let's see how we actually did
confusion_matrix <- table(Observed = test_data$churn, Predicted = predictions)
print(confusion_matrix)

I always tell my juniors: look closely at the "False Negatives." In churn modeling, a False Negative is a customer the model said would stay, but they actually left. That's the most expensive mistake you can make because you didn't even try to save them. Depending on how much it costs to acquire a new customer, you might actually want to lower your threshold to 0.3 to catch more potential churners, even if it means sending a few unnecessary discount codes to happy customers.




📋 Practical Task

Building the StreamWave Retention Predictor

You've been handed a dataset from "StreamWave," a fictional streaming service. They are losing users and they want a model to identify who is at risk before the end of the month.

Your Task: Write an R script that performs the following:

  • Create a synthetic dataframe stream_data with 100 rows and the following columns: hours_watched (numeric), monthly_fee (numeric), and churned (binary 0 or 1).
  • Build a logistic regression model to predict churned based on hours_watched and monthly_fee.
  • Use the predict() function to generate churn probabilities for a new customer who watches 2 hours a month and pays a premium fee of $25.
  • Print a final message stating whether this specific customer is "At Risk" or "Loyal" based on a 0.5 probability threshold.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.