In today’s fast-moving world, we often need to use complex tools like machine learning to make sense of data and solve problems. However, these tools can be pretty tricky to use, especially if you’re not a tech expert. That’s where Shiny comes in! Shiny is an open packages from RStudio, which provides a web application framework to create interactive web application called Shiny apps. Shiny is like a magic wand for turning these powerful but confusing tools into easy-to-use web apps. While Shiny is often used to create interactive dashboard visualizations, in this article, we’ll explore a slightly different but equally exciting aspect of Shiny: deploying machine learning models. We’ll see how Shiny makes it super simple to deploy your machine learning creations, even if you’re not a tech whiz. So, let’s dive into the world of Shiny and discover how it can bring the power of machine learning to your fingertips in our fast-paced digital age.

In broad strokes, here are the steps we’ll be exploring in this article:

  1. Getting to know Shiny!
  2. Saving Your Machine Learning Model as an RDS File
  3. Connecting the Machine Learning Model and Shiny Input through Action Button
  4. Deploying to shinyapps.io

In this article, we will explore the employee turnover prediction dashboard, which you can access at https://algoritmadatascience.shinyapps.io/Dashboard-Employee-Turnover/, and it will provide an overview like this:

Let’s get started!

0.1 Getting to know Shiny!

Before we dive into the technical stuff, let’s get familiar with Shiny and its main parts. A basic Shiny app is like building with three important R scripts:

  • global.R: Think of this as the backstage manager. It gets everything ready for your app’s performance. Here, you gather the tools you’ll need (like libraries), bring in the props (your data), and make sure everything is set up just right.

  • ui.R: This is where you design the look of your app. Imagine it as the stage where your audience sees everything. You decide how it should appear, what buttons and sliders the audience can use, and how it all fits together.

  • server.R: Now, this is where the real action happens. Think of it as the engine of your app. In the server script, you make things happen based on what the audience (your app’s users) does. You listen to their requests, do some magic behind the scenes (like processing data or running models), and then show them the results.

These three scripts work together, like a team putting on a play. global.R sets up the backstage, ui.R designs the stage, and server.R directs the performance. Together, they create a web app that can do cool stuff, like showing data or even deploying machine learning models. If you’re feeling uncertain about where to begin your journey into learning Shiny, a valuable resource is the book “Mastering Shiny” by O’Reilly Media, which provides comprehensive insights. You can access it online through this link: Mastering Shiny.

0.2 Saving Your Machine Learning Model as an RDS File

First, of course, we need to have a machine learning model that we will deploy in Shiny. To make the process more efficient and secure, it is advisable to store the machine learning model in RDS format. This ensures that when it is deployed in Shiny, it does not consume excessive memory or time. Here is an example of how to save a random forest model in RDS format using the saveRDS() function and store it with the name randomforest.RDS.

set.seed(417)

control <- trainControl(method = "repeatedcv", number = 10, repeats = 10)

# build model
model <- train(x = data_train[,-27],y = data_train[,27],method = "rf", trControl = control)

# save model
saveRDS(model, "randomforest.RDS")

0.3 Connecting the Machine Learning Model and Shiny Input through Action Button

0.3.1 Creating Shiny Input for Model Prediction

In the “Dashboard Employee Turnover”, we have 4 shiny input sections, which contain the predictor variables needed by the machine learning model that has been created, as shown in the following image.

In running a machine learning model, we undoubtedly need input predictor variables so that the model can function. These predictors are incorporated into the model through shiny inputs located in the ui.R script, and you can design them as creatively as you like. This time, we’ve placed these predictors into a collapsible box, which is a box that can be opened or closed when clicked. In the image above, each box is labeled with instructions that the user needs to follow if they want to use this dashboard. This is the title of the open box is “Please complete this survey based on employee answers.”. The collapsible box we use is optional. You can explore the Shiny structure further and choose other options by reading the following link: Structure Shiny.

In that box, we present predictor variables in the form of a survey using sliderInput(). If you wish to select a different type of input, you can check it out at the following link: shiny input or more. The example code in the collapsible box above is as follows.

box(
  title = "Please complete this survey based on employee answers!",
  solidHeader = TRUE,
  enable_label = TRUE,
  status = "primary",
  collapsible = TRUE,
  collapsed = TRUE,
  width = 6,
  p(
    "These questions provide insights into various aspects of the work environment using a simple 5-point scale."
  ),
  
  sliderInput(
    inputId = "ENVIRONMENT_SATISFACTION",
    label = "1. How satisfied are you with your current work environment?",
    min = 1, max = 5, value = 1
  ),
  sliderInput(
    inputId = "JOB_INVOLVEMENT",
    label = "2. How involved do you feel in your current job?",
    min = 1, max = 5, value = 1
  ),
  sliderInput(
    inputId = "JOB_SATISFACTION",
    label = "3. How satisfied are you with your current job?",
    min = 1, max = 5, value = 1
  ),
  sliderInput(
    inputId = "PERFORMANCE_RATING",
    label = "4. How would you rate your overall performance in your role?",
    min = 1,  max = 5, value = 1
  ),
  sliderInput(
    inputId = "WORK_LIFE_BALANCE",
    label = "5. How satisfied are you with your work-life balance?",
    min = 1, max = 5, value = 1
  ),
  sliderInput(
    inputId = "RELATIONSHIP_SATISFACTION",
    label = "6. How satisfied are you with your work relationship?",
    min = 1, max = 5, value = 1
  )
)

0.3.2 Connecting the Machine Learning Model with Shiny Input

0.3.2.1 Action Button

We will link the shiny input to the machine learning model using a button on the dashboard called an action button. You can create an action button using the actionButton(inputId = "action", label = "Check the Result!") function in ui.R. It has two parameters: inputId, which will be used to identify the action button in server.R, and label, which is used to name the action button in ui.R. Then, in server.R, we will use the action button as a condition. If the action button is clicked, a process in server.R will be executed. To gain a deeper understanding of the Action Button in Shiny, we recommend referring to the official documentation of action button.

0.3.2.2 Connecting action button with the shiny input

After creating the action button, we can proceed to server.R, which is where we execute various processes to obtain the output from the machine learning model. In server.R, we will identify the inputs entered in ui.R and run our machine learning model to predict the input data that has been provided. To understand how the action button connects shiny input and machine learning, please observe the following code in server.R.

name <- eventReactive(input$action, input$NAME)

test_data <- eventReactive(input$action, {
  data_input <- data.frame(
    AGE = input$AGE,
    DAILY_RATE = input$DAILY_RATE,
    DISTANCE_FROM_HOME = input$DISTANCE_FROM_HOME,
    EDUCATION = input$EDUCATION,
    ENVIRONMENT_SATISFACTION = input$ENVIRONMENT_SATISFACTION,
    GENDER = input$GENDER,
    HOURLY_RATE = input$HOURLY_RATE,
    JOB_INVOLVEMENT = input$JOB_INVOLVEMENT,
    JOB_LEVEL = input$JOB_LEVEL,
    JOB_SATISFACTION = input$JOB_SATISFACTION,
    MARITAL_STATUS = input$MARITAL_STATUS,
    MONTHLY_INCOME = input$MONTHLY_INCOME,
    MONTHLY_RATE = input$MONTHLY_RATE,
    NUM_COMPANIES_WORKED = input$NUM_COMPANIES_WORKED,
    PERCENT_SALARY_HIKE = input$PERCENT_SALARY_HIKE,
    PERFORMANCE_RATING = input$PERFORMANCE_RATING,
    RELATIONSHIP_SATISFACTION = input$RELATIONSHIP_SATISFACTION,
    STANDARD_HOURS = input$STANDARD_HOURS,
    STOCK_OPTION_LEVEL = input$STOCK_OPTION_LEVEL,
    TOTAL_WORKING_YEARS = input$TOTAL_WORKING_YEARS,
    TRAINING_TIMES_LAST_YEAR = input$TRAINING_TIMES_LAST_YEAR,
    WORK_LIFE_BALANCE = input$WORK_LIFE_BALANCE,
    YEARS_AT_COMPANY = input$YEARS_AT_COMPANY,
    YEARS_IN_CURRENT_ROLE = input$YEARS_IN_CURRENT_ROLE,
    YEARS_SINCE_LAST_PROMOTION = input$YEARS_SINCE_LAST_PROMOTION,
    YEARS_WITH_CURR_MANAGER = input$YEARS_WITH_CURR_MANAGER
  )
  
  data_predict <- data_input %>% mutate_at(colnames(data_input), as.numeric)
  
})

The code above shows that we are storing the inputs entered in ui.R to server.R for further processing. Since the dashboard requires various inputs, such as employee names using textInput() in ui.R, we save them as a function called name() in server.R using the eventReactive() function with parameters inputID from actionButton() and textInput(). The way the eventReactive() function works is that when the action button is clicked, the shiny input from textInput() is stored in a function called name(). Because the predictors for the machine learning model in this dashboard are in dataframe format, we proceed to create a dataframe using eventReactive(). We also perform data preprocessing, which in this case involves changing the data type of all predictor variables to numeric. It’s important to note that when saving predictor inputs in server.R, you should create the input data exactly the same as when building the machine learning model to be used, including any data preprocessing steps..

0.3.2.3 Connecting shiny input with the machine learning using action button

After the action button is connected to the input data, the next step is to process the input data through the machine learning model so that we can generate prediction outputs from our model in ui.R. Here is an overview of the Employee Turnover Prediction dashboard output.

We will carry out this process within server.R. The process involves making predictions from the preprocessed input data using the machine learning model that we have saved as an RDS file. It’s important to note that the prediction function performed should be tailored to the type of machine learning used and the desired output. Here is an example of the code for a prediction function for a random forest model that generates the probability of employee turnover:

prediction <- eventReactive(input$action, {
  rf_model <- readRDS("data_input/randomforest.RDS")
  
  pred <- predict(rf_model, test_data(), type = "prob")
  
  pred[,2]
  
})

To make the output of machine learning predictions displayed on the dashboard more informative, we can also modify it. In this case, we want to present the results in the form of a narrative, indicating whether the employees we input into the dashboard are predicted to be likely to leave the company or stay in the company. Since the output is in text format, we use the renderText() function in server.R, paired with this code snippet, which is verbatimTextOutput() in ui.R. To gain a better grasp of the necessary outputs to utilize in both the server.R and ui.R files, we recommend consulting the Shiny cheatsheet. Here is an example of the code in server.R:

output$text_result <- renderText({
    prediksi <- as.numeric(prediction() > 0.5) %>% as.factor()
    
    decode <- function(x){
      case_when(x == "1" ~ paste0("likely to leave the company with probability of ", round(prediction()*100,1),"%."),
                x == "0" ~ "likely to stay in the company."
      )}
    
    
    paste0(name(), " is ", decode(prediksi))
  })

0.4 Deploying to shinyapps.io

After successfully running your prediction dashboard on your local computer, the final step is to deploy it to Shinyapps on the web, allowing easy access for many people. You can find detailed steps on how to deploy Shinyapps to the web at this official shiny link.

Don’t panic if you encounter any failures during deployment, as this is a common occurrence. You can troubleshoot the errors by running the code rsconnect::showLogs() in the RStudio Console and resolving the identified issues. Typically, these errors are related to missing package dependencies. You can also refer to the Posit documentation for troubleshooting deployment errors.

Here is the core process when we want to deploy a machine learning model in a Shiny app. In fact, you can explore many more possibilities for deploying machine learning models according to the design you desire because Shiny is highly flexible. You can view the following Shiny gallery to explore Shiny designs more extensively. There, you’ll even find example code to help you get started. Once you have a grasp of how Shiny works, creating useful and visually appealing web applications using Shiny will become very straightforward. Unlock the limitless potential of Shiny and let your creativity run wild in deploying machine learning models that not only work efficiently but also look stunning. Learning will never stop, so keep exploring the exciting world of data science!