Building a Step-by-Step Machine Learning Model in R: A Beginner‘s Guide
Machine learning has revolutionized the way organizations across virtually every industry leverage their data to uncover insights, make predictions, and automate complex decisions. Whether it‘s predicting customer churn in retail, detecting financial fraud in banking, or diagnosing diseases in healthcare, machine learning empowers businesses to transform vast amounts of raw data into actionable intelligence.
While Python tends to dominate the data science and machine learning discourse these days, R remains an immensely popular and powerful language for ML practitioners, especially those with a background in statistics. In this step-by-step tutorial, we‘ll walk through the key phases of a typical machine learning project in R, from exploring and preparing the data to training and evaluating models. By the end, you‘ll have the skills and knowledge to build your own ML solutions in R.
Why Use R for Machine Learning?
R has a rich history as a language for statistical computing and data analysis. Over the years, it has evolved into a robust tool for machine learning as well, thanks to its strengths in areas like data manipulation, visualization, and a huge ecosystem of packages for virtually every ML task imaginable.
Some key advantages of R for machine learning include:
- Extensive data processing and statistical capabilities via packages like dplyr, tidyr, stringr
- Powerful data visualization via ggplot2, plotly, leaflet and more for exploratory analysis
- Wide range of ML algorithms accessible through caret, glmnet, ranger, xgboost, h2o and other packages
- Strong support for key ML workflows like resampling, feature selection, hyperparameter tuning
- Rich community and resources, including CRAN, R-bloggers, online courses, books, conferences
With that background in mind, let‘s dig into the key steps of building a machine learning model in R. We‘ll use a real-world dataset to make the concepts more concrete.
The Machine Learning Workflow in R
While the details may vary depending on the project, a typical machine learning workflow in R involves the following high-level steps:
- Exploring and visualizing the data
- Preparing the data for modeling
- Training models on the data
- Evaluating model performance
- Optimizing and finalizing the model
- Applying the model to new data
To illustrate these steps, we‘ll work with the Telco Customer Churn dataset available on Kaggle. This dataset contains information about a fictitious telecom company‘s customers, including demographic data, what services they‘ve subscribed to, and whether or not they ended up "churning" (i.e. unsubscribing and taking their business elsewhere).
Our goal will be to build a machine learning model that can predict which customers are likely to churn, so the company can proactively intervene and convince them to stay. This type of churn prediction is a common use case for ML in many customer-centric industries.
Let‘s get started by loading the necessary libraries and reading in the data:
# Load required libraries
library(tidyverse) # For data manipulation and visualization
library(caret) # For ML workflows
library(ranger) # For random forest model
# Read in data
churn_raw <- read_csv("WA_Fn-UseC_-Telco-Customer-Churn.csv")
Step 1: Exploring and Visualizing the Data
With the data loaded, our first step is to explore it and look for any initial patterns or relationships. We can start by checking the dimensions, data types, and summary statistics:
# Check dimensions
dim(churn_raw)
# Glimpse data structure
glimpse(churn_raw)
# Summary statistics
skim(churn_raw)
This reveals we have 7043 observations across 21 variables, a mix of categorical and numeric data types. The Churn variable looks to be our target, with 27% of customers having churned.
Next, we can visualize the relationships between different variables and churn. A great way to do this is with ggplot2:
# Plot distribution of tenure by churn
ggplot(churn_raw, aes(x = tenure, fill = Churn)) +
geom_density(alpha = 0.5) +
labs(title = "Tenure Distribution by Churn")
# Plot monthly charges by churn
ggplot(churn_raw, aes(x = MonthlyCharges, fill = Churn)) +
geom_density(alpha = 0.5) +
labs(title = "Monthly Charges Distribution by Churn")
# Plot churn rate by contract type
ggplot(churn_raw, aes(x = Contract, fill = Churn)) +
geom_bar(position = "fill") +
labs(title = "Churn Rate by Contract Type", y = "Proportion")
These visualizations suggest that customers with lower tenure, higher monthly charges, and month-to-month contracts churn at higher rates. This gives us some initial hints about potentially important predictors of churn.
Step 2: Preparing the Data for Modeling
With a better understanding of the data, we can move on to preparing it for modeling. Key steps here include:
- Handling missing values
- Encoding categorical variables
- Splitting into train and test sets
- Standardizing/scaling numeric features as needed
Our dataset is relatively clean, with no missing values that need imputation. However, we do need to convert categorical variables to numeric via one-hot encoding:
# One-hot encode categorical variables
churn_encoded <- churn_raw %>%
mutate_if(is.character, as.factor) %>%
dummy_cols(select_columns = c("gender", "Partner", "Dependents",
"PhoneService", "MultipleLines", "InternetService",
"OnlineSecurity", "OnlineBackup", "DeviceProtection",
"TechSupport", "StreamingTV", "StreamingMovies",
"Contract", "PaperlessBilling", "PaymentMethod"),
remove_selected_columns = TRUE)
Now let‘s split our data into training and test sets. We‘ll use a 70/30 split, and stratify by the Churn variable to ensure it‘s evenly represented across both sets:
# Split into train and test
set.seed(123) # For reproducibility
churn_split <- initial_split(churn_encoded, prop = 0.7, strata = "Churn")
churn_train <- training(churn_split)
churn_test <- testing(churn_split)
With the data prepared, we‘re ready to start modeling.
Step 3: Training Models on the Data
There are many machine learning algorithms we could use for a classification problem like customer churn. In this example, we‘ll use a random forest model. Random forests are ensemble models that combine many individual decision trees and tend to perform quite well with minimal tuning on a wide range of problems.
We can train a random forest model with the ranger package:
# Train a random forest model
rf_model <- ranger(
Churn ~ .,
data = churn_train,
num.trees = 500,
importance = "permutation"
)
Step 4: Evaluating Model Performance
With our model trained, the next step is to see how well it performs on unseen (test) data. We‘ll generate predictions on the test set and evaluate them against the actual Churn values:
# Generate predictions on test data
churn_pred <- predict(rf_model, churn_test)
# Evaluate performance
confusionMatrix(churn_pred$predictions, churn_test$Churn)
The confusion matrix shows that our initial random forest model achieves about 80% accuracy on the test set. The precision and recall for the churned class are 0.65 and 0.52 respectively, suggesting there‘s still room for improvement in terms of predicting churners.
Step 5: Optimizing and Finalizing the Model
To squeeze more performance out of our model, we can optimize its hyperparameters (number of trees, number of variables considered at each split, etc) via a technique like grid search cross-validation:
# Hyperparameter grid
hyper_grid <- expand.grid(
num.trees = c(500, 1000),
mtry = floor(sqrt(ncol(churn_train))),
min.node.size = c(1, 3, 5),
sample.fraction = c(0.5, 0.63, 0.75)
)
# Perform grid search
ctrl <- trainControl(method = "cv", number = 5)
churn_grid <- train(
Churn ~ .,
data = churn_train,
method = "ranger",
tuneGrid = hyper_grid,
trControl = ctrl
)
After finding the best hyperparameters, we can train a final model on all training data and evaluate it one last time on the test set:
# Train final model with optimal hyperparameters
final_model <- ranger(
Churn ~ .,
data = churn_train,
num.trees = churn_grid$bestTune$num.trees,
mtry = churn_grid$bestTune$mtry,
min.node.size = churn_grid$bestTune$min.node.size,
sample.fraction = churn_grid$bestTune$sample.fraction,
importance = "permutation"
)
# Generate final predictions
final_pred <- predict(final_model, churn_test)
# Evaluate final performance
confusionMatrix(final_pred$predictions, churn_test$Churn)
The tuned model achieves an accuracy of 82% with precision and recall for churners around 0.68 and 0.56 respectively. While still not perfect, this represents a meaningful improvement over the initial model.
Step 6: Applying the Model to New Data
With our final model built and validated, we can use it to predict churn on new data, e.g. next month‘s customer information:
# Read in new data
new_data <- read_csv("new_customer_data.csv")
# Preprocess new data (encoding, feature engineering, etc)
new_data_encoded <- new_data %>%
mutate_if(is.character, as.factor) %>%
dummy_cols(
select_columns = c("gender", "Partner", "Dependents",
"PhoneService", "MultipleLines", "InternetService",
"OnlineSecurity", "OnlineBackup", "DeviceProtection",
"TechSupport", "StreamingTV", "StreamingMovies",
"Contract", "PaperlessBilling", "PaymentMethod"),
remove_selected_columns = TRUE
)
# Apply model to generate churn predictions
new_data_pred <- predict(final_model, new_data_encoded)
# Combine predictions with original data
new_data_pred_df <- new_data %>%
mutate(churn_prob = new_data_pred$predictions)
We now have churn probabilities for each customer in the new dataset, enabling targeted retention efforts. For example, the company could offer special discounts or loyalty rewards to high-risk customers as identified by the model.
Summary and Next Steps
In this tutorial, we walked through the key steps of building a machine learning model in R:
- Exploring and visualizing the data
- Preparing the data for modeling
- Training a model on the data
- Evaluating model performance
- Optimizing and finalizing the model
- Applying the model to new data
While we focused on a customer churn use case and random forest model, the same general workflow applies for a wide variety of ML problems and algorithms in R.
Some potential next steps and further reading:
- Experimenting with other algorithms like logistic regression, gradient boosting, neural networks
- Implementing more advanced techniques like over/under-sampling, SMOTE, stacking ensembles
- Exploring explainable AI techniques to understand feature importance, individual predictions
- Learning about productizing models via APIs, dashboards, scheduled batch jobs
- More practice on other datasets and problem types (regression, multi-class, unsupervised, etc)
I hope this step-by-step guide gives you a solid foundation for building machine learning models in R. With its powerful syntax, rich package ecosystem, and active community, R is an amazing language for data science and ML. Happy modeling!
You can find all the code used in this tutorial on my GitHub repo. Feel free to use it as a starting point for your own machine learning projects in R!