Deployment PimaIndia Diabetes
Deploy Random Forest Diabetes Prediction (Shiny)
Packages
## Warning: package 'mlbench' was built under R version 4.3.3
## ── Attaching packages ────────────────────────────────────── tidymodels 1.4.1 ──
## ✔ broom 1.0.10 ✔ recipes 1.3.1
## ✔ dials 1.4.2 ✔ rsample 1.3.1
## ✔ dplyr 1.1.4 ✔ tailor 0.1.0
## ✔ ggplot2 4.0.1 ✔ tidyr 1.3.1
## ✔ infer 1.0.9 ✔ tune 2.0.1
## ✔ modeldata 1.5.1 ✔ workflows 1.3.0
## ✔ parsnip 1.3.3 ✔ workflowsets 1.1.1
## ✔ purrr 1.2.0 ✔ yardstick 1.3.2
## Warning: package 'dplyr' was built under R version 4.3.3
## Warning: package 'tidyr' was built under R version 4.3.3
## Warning: package 'yardstick' was built under R version 4.3.3
## ── Conflicts ───────────────────────────────────────── tidymodels_conflicts() ──
## ✖ purrr::discard() masks scales::discard()
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ✖ recipes::step() masks stats::step()
## Warning: package 'ranger' was built under R version 4.3.3
##
## Attaching package: 'shiny'
## The following object is masked from 'package:infer':
##
## observe
##
## Attaching package: 'DT'
## The following objects are masked from 'package:shiny':
##
## dataTableOutput, renderDataTable
## Warning: package 'glue' was built under R version 4.3.3
Load Data
Train dan Save Model
Recipe preprocessing
Random Forest Model Specification
Shiny App
rf_wf <- readRDS("rf_diabetes_workflow.rds")
# Load dataset untuk referensi default UI values
data("PimaIndiansDiabetes")
df <- PimaIndiansDiabetes
num_cols <- names(df)[names(df) != "diabetes"]
# Summary untuk nilai default input
num_summary <- df %>% summarise(
across(where(is.numeric), list(
min = ~min(., na.rm = TRUE),
max = ~max(., na.rm = TRUE),
med = ~median(., na.rm = TRUE)
))
)
med <- function(nm) as.numeric(num_summary[[paste0(nm, "_med")]])
# UI
ui <- fluidPage(
titlePanel("Prediksi Diabetes (Random Forest)"),
tags$small("Model sudah dilatih & disimpan — hanya untuk prediksi."),
tabsetPanel(
# TAB 1: Single Prediction
tabPanel(
"Single Prediction",
sidebarLayout(
sidebarPanel(
do.call(tagList, lapply(num_cols, function(col){
numericInput(col, col, value = med(col))
}))
,
actionButton("predict_one", "Prediksi")
),
mainPanel(
h4("Hasil Prediksi"),
verbatimTextOutput("single_pred"),
DTOutput("single_proba")
)
)
),
# TAB 2: Batch CSV Prediction
tabPanel(
"Batch Prediction (CSV)",
fileInput("csv_file", "Upload CSV tanpa kolom 'diabetes'"),
DTOutput("batch_out"),
downloadButton("download_preds", "Download hasil prediksi")
)
)
)
# SERVER
server <- function(input, output, session){
# --------------- SINGLE INPUT ----------------
observeEvent(input$predict_one, {
newdata <- as_tibble(setNames(
lapply(num_cols, function(col) input[[col]]),
num_cols
))
cls <- predict(rf_wf, new_data = newdata, type = "class")
prob <- predict(rf_wf, new_data = newdata, type = "prob")
output$single_pred <- renderText({
glue("Prediksi: {cls$.pred_class}")
})
output$single_proba <- renderDT({
datatable(prob, rownames = FALSE)
})
})
# ---------------- CSV INPUT -------------------
batch_data <- reactive({
req(input$csv_file)
read.csv(input$csv_file$datapath)
})
batch_pred <- reactive({
df_new <- batch_data()
cls <- predict(rf_wf, new_data = df_new, type = "class")
prob <- predict(rf_wf, new_data = df_new, type = "prob")
bind_cols(df_new, tibble(pred_diabetes = cls$.pred_class), prob)
})
output$batch_out <- renderDT({
req(batch_pred())
datatable(batch_pred(), options = list(pageLength = 10))
})
output$download_preds <- downloadHandler(
filename = function() "prediksi_diabetes.csv",
content = function(file){
write.csv(batch_pred(), file, row.names = FALSE)
}
)
}
shinyApp(ui, server)Shiny applications not supported in static R Markdown documents