Notes on compiling this document:
In the code chunk above (entitled “setup”) echo is set to TRUE. This means that the code in your chunks will be displayed, along with the results, in your compiled document.
Below is code to clean and prepare the data set for modeling. Before running that code, follow these preparatory steps:
Download the RMarkdown template and the data sets for the assignment from Canvas.
Copy or move these files from your downloads folder to a folder dedicated to this class–say, MKTG-6487.
You need to define this folder as your “working directory.” To do so, navigate to that folder using the files tab in the lower right quadrant in RStudio. (You should see your files you moved into this folder in the previous step.) Click the “More” button in the menu under the Files tab and select “Set As Working Directory.”
Once the files are in the right location on your computer then run this code to clean and format the data:
# You must run this code to format the data set properly!
advise_invest <- read_csv("adviseinvest.csv") %>% # Download data
select(-product) %>% # Remove the product column
filter(income > 0, # Filter out mistaken data
num_accts < 5) %>%
mutate(answered = factor(ifelse(answered==0, "no","yes"), # Turn answered into yes/no factor
levels = c("no", "yes")),
female = factor(female), # Make categorical variables into factors
job = factor(job),
rent = factor(rent),
own_res = factor(own_res),
new_car = factor(new_car),
mobile = factor(mobile),
chk_acct = factor(chk_acct),
sav_acct = factor(sav_acct))
## Rows: 29502 Columns: 14
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (14): answered, income, female, age, job, num_dependents, rent, own_res,...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
And here is code to load the data set of prospective customers from your working directory. Note that in order to use this data set for prediction, the variables need to be formatted exactly the same as in the data used to fit the model. It does not include a target variable because the event of answering or not answering has not happened yet for scheduled customers.
prospective <- read_csv("customer_data.csv") %>%
mutate(female = factor(female),
job = factor(job),
rent = factor(rent),
own_res = factor(own_res),
new_car = factor(new_car),
mobile = factor(mobile),
chk_acct = factor(chk_acct),
sav_acct = factor(sav_acct))
## Rows: 1000 Columns: 13
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): customer_id
## dbl (12): income, female, age, job, num_dependents, rent, own_res, new_car, ...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
One of the simplifying assumptions we will make in this project is that all the customers who answer the phone will purchase a product. (This assumption is actually verified by the data.) To model “answered” in this case is therefore equivalent to modeling “purchased.”
There are costs and benefits in this case. We will assume that customers purchase a product for $100 dollars. This was the average cost of AdviseInvest products, according to the Director of Sales. Also, as we learned in the interview, the agent time to make the sale is worth $25. Profit would therefore be $75 dollars for an answered call and a purchase. In sum:
Benefit: True positive. The customer is predicted to answer, does answer, and purchases a product for $100 for a profit of 100 - 25 = $75.
Cost: False positive. The customer is predicted to answer, but does not answer, so there is a loss of $25. (We assume the agent cannot schedule another call at the last minute, or spends the entire time slot trying to make the call.)
For this exercise, we propose that customers who are not predicted to answer will not be called, so there would be no benefits and no costs for them.
However, this proposal is for illustration only. Below you will be asked to come up with a final recommendation for the Director of Sales, and you should feel free to craft a solution—whatever that might be—that fits the details of the case.
One thing to keep in mind for this final phase of the project is that a predictive model is always developed using historical data. The end goal, however, is to predict the future occurrence of the event that has been modeled. In this exercise, you will practice using data on new customers—that is, customers who have not yet been called—to predict whether they will answer. How you use these predictions in solving the business problem is up to you.
if (!require(tree)) {
install.packages("tree")
library(tree)
}
## Loading required package: tree
tree_model <- tree(answered ~ ., data = advise_invest)
predictions <- predict(tree_model, type = "class")
conf_matrix <- table(Actual = advise_invest$answered, Predicted = predictions)
TP <- conf_matrix[2, 2] # True Positives
FP <- conf_matrix[1, 2] # False Positives
TN <- conf_matrix[1, 1] # True Negatives
FN <- conf_matrix[2, 1] # False Negatives
cat("Number of True Positives (TP):", TP, "\n")
## Number of True Positives (TP): 10684
cat("Number of False Positives (FP):", FP, "\n")
## Number of False Positives (FP): 1920
cat("Number of True Negatives (TN):", TN, "\n")
## Number of True Negatives (TN): 11455
cat("Number of False Negatives (FN):", FN, "\n")
## Number of False Negatives (FN): 5440
cost_benefit_matrix <- matrix(c(75, -25, 0, 0), nrow = 2, byrow = TRUE,
dimnames = list(c("predicted yes", "predicted no"),
c("observed yes", "observed no")))
profit_matrix <- conf_matrix * cost_benefit_matrix
total_profit <- sum(profit_matrix)
cat("Total Expected Profit:", total_profit, "\n")
## Total Expected Profit: 811125
if (!require(rpart)) {
install.packages("rpart")
library(rpart)
}
tree_model_rpart <- rpart(answered ~ ., data = advise_invest)
predicted_probs_rpart <- predict(tree_model_rpart, type = "prob")
threshold <- 0.3
predicted_labels_thresholded_rpart <- ifelse(predicted_probs_rpart[, "yes"] >= threshold, "yes", "no")
conf_matrix_new_rpart <- table(Actual = advise_invest$answered, Predicted = predicted_labels_thresholded_rpart)
cost_benefit_matrix <- matrix(c(75, -25, 0, 0), nrow = 2, byrow = TRUE,
dimnames = list(c("predicted yes", "predicted no"),
c("observed yes", "observed no")))
profit_matrix_new_rpart <- conf_matrix_new_rpart * cost_benefit_matrix
total_profit_new_rpart <- sum(profit_matrix_new_rpart)
cat("Total Expected Profit with threshold 0.3 using 'rpart':", total_profit_new_rpart, "\n")
## Total Expected Profit with threshold 0.3 using 'rpart': 625525
library(tidyverse)
library(rpart)
prospective <- read_csv("customer_data.csv") %>%
mutate(female = factor(female),
job = factor(job),
rent = factor(rent),
own_res = factor(own_res),
new_car = factor(new_car),
mobile = factor(mobile),
chk_acct = factor(chk_acct),
sav_acct = factor(sav_acct))
## Rows: 1000 Columns: 13
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): customer_id
## dbl (12): income, female, age, job, num_dependents, rent, own_res, new_car, ...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
predicted_labels <- predict(tree_model, newdata = prospective, type = "class")
threshold <- 0.3
contact_list <- prospective %>%
filter(predicted_labels == "yes")
num_customers_on_contact_list <- nrow(contact_list)
cat("Number of customers on the contact list:", num_customers_on_contact_list, "\n")
## Number of customers on the contact list: 450