rf_breastcancer_shiny
1 Kelompok 1:
- Angelia Yuflih Pambayun (23031030002)
- Septiana Nabila Dwi Halisa (23031030010)
- Nariza Rahmadani P.M (23031030012)
- Yoga Adi Saputra (23031030027)
- Nayli Kurnia ILahi (23031030045)
2 Package
## Warning: package 'readr' was built under R version 4.3.3
## Warning: package 'dplyr' was built under R version 4.3.3
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
## Warning: package 'palmerpenguins' was built under R version 4.3.3
## Warning: package 'ranger' was built under R version 4.3.3
## Warning: package 'tidymodels' was built under R version 4.3.3
## ── Attaching packages ────────────────────────────────────── tidymodels 1.3.0 ──
## ✔ broom 1.0.10 ✔ rsample 1.3.1
## ✔ dials 1.4.2 ✔ tibble 3.2.1
## ✔ ggplot2 3.5.2 ✔ tidyr 1.3.1
## ✔ infer 1.0.9 ✔ tune 1.3.0
## ✔ modeldata 1.5.1 ✔ workflows 1.3.0
## ✔ parsnip 1.3.3 ✔ workflowsets 1.1.0
## ✔ purrr 1.0.4 ✔ yardstick 1.3.2
## ✔ recipes 1.3.1
## Warning: package 'scales' was built under R version 4.3.2
## Warning: package 'purrr' was built under R version 4.3.3
## Warning: package 'tibble' was built under R version 4.3.2
## Warning: package 'tidyr' was built under R version 4.3.3
## Warning: package 'tune' was built under R version 4.3.3
## Warning: package 'workflowsets' 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()
## ✖ yardstick::spec() masks readr::spec()
## ✖ recipes::step() masks stats::step()
## Warning: package 'shiny' was built under R version 4.3.3
##
## Attaching package: 'shiny'
## The following object is masked from 'package:infer':
##
## observe
## Warning: package 'DT' was built under R version 4.3.3
##
## Attaching package: 'DT'
## The following objects are masked from 'package:shiny':
##
## dataTableOutput, renderDataTable
3 Data
path <- "C:\\Users\\ASUS\\Downloads\\breast+cancer+wisconsin+diagnostic\\wdbc.data"
bc <- read.csv(path, header = FALSE)
colnames(bc) <- c(
"id", "diagnosis",
"radius_mean", "texture_mean", "perimeter_mean", "area_mean", "smoothness_mean",
"compactness_mean", "concavity_mean", "concave_points_mean", "symmetry_mean",
"fractal_dimension_mean",
"radius_se", "texture_se", "perimeter_se", "area_se", "smoothness_se",
"compactness_se", "concavity_se", "concave_points_se", "symmetry_se",
"fractal_dimension_se",
"radius_worst", "texture_worst", "perimeter_worst", "area_worst", "smoothness_worst",
"compactness_worst", "concavity_worst", "concave_points_worst", "symmetry_worst",
"fractal_dimension_worst"
)4 Train & Save Model
4.1 Data & target — kolom fitur yang akan dipakai
4.2 Split data
4.3 Recipe preprocessing
4.4 Model Random Forest (ranger)
4.5 Workflow = recipe + Model
4.6 Simpan Workflow
#Shiny APp
# 1) LOAD MODEL RANDOM FOREST (WORKFLOW)
rf_wf <- readRDS("D:/SEMESTER 5/MESIN STATISTIK/r/rf_breastcancer_workflow.rds")
# 2) LOAD DATA ASLI UNTUK RANGE INPUT DEFAULT
path <- "C:/Users/ASUS/Downloads/breast+cancer+wisconsin+diagnostic/wdbc.data"
bc_raw <- read.csv(path, header = FALSE)
colnames(bc_raw) <- c(
"id", "diagnosis",
"radius_mean", "texture_mean", "perimeter_mean", "area_mean", "smoothness_mean",
"compactness_mean", "concavity_mean", "concave_points_mean", "symmetry_mean",
"fractal_dimension_mean",
"radius_se", "texture_se", "perimeter_se", "area_se", "smoothness_se",
"compactness_se", "concavity_se", "concave_points_se", "symmetry_se",
"fractal_dimension_se",
"radius_worst", "texture_worst", "perimeter_worst", "area_worst",
"smoothness_worst", "compactness_worst", "concavity_worst",
"concave_points_worst", "symmetry_worst", "fractal_dimension_worst"
)
bc <- bc_raw %>%
select(
diagnosis, radius_mean, texture_mean, area_mean,
smoothness_mean, compactness_mean, concavity_mean
)
num_summary <- bc %>% 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")]])
required_cols <- c(
"radius_mean","texture_mean","area_mean",
"smoothness_mean","compactness_mean","concavity_mean"
)
# 3) UI
ui <- fluidPage(
titlePanel("Breast Cancer Diagnosis Prediction (Random Forest)"),
tags$small("Model sudah dilatih & disimpan. Aplikasi ini hanya untuk prediksi."),
br(),
tabsetPanel(
# SINGLE PREDICTION
tabPanel(
"Single Prediction",
sidebarLayout(
sidebarPanel(
numericInput("radius_mean", "Radius Mean", value = med("radius_mean")),
numericInput("texture_mean", "Texture Mean", value = med("texture_mean")),
numericInput("area_mean", "Area Mean", value = med("area_mean")),
numericInput("smoothness_mean", "Smoothness", value = med("smoothness_mean")),
numericInput("compactness_mean", "Compactness", value = med("compactness_mean")),
numericInput("concavity_mean", "Concavity", value = med("concavity_mean")),
actionButton("predict_one", "Prediksi")
),
mainPanel(
h4("Hasil Prediksi Diagnosis"),
verbatimTextOutput("single_pred"),
DTOutput("single_proba")
)
)
),
#BATCH PREDICTION
tabPanel(
"Batch Prediction (CSV)",
fileInput("csv_file", "Upload CSV tanpa kolom diagnosis", accept = ".csv"),
br(),
DTOutput("batch_table"),
br(),
downloadButton("download_preds", "Unduh Hasil Prediksi CSV")
)
)
)
# 4) SERVER
server <- function(input, output, session) {
# SINGLE PREDICTION
observeEvent(input$predict_one, {
newdat <- tibble(
radius_mean = input$radius_mean,
texture_mean = input$texture_mean,
area_mean = input$area_mean,
smoothness_mean = input$smoothness_mean,
compactness_mean = input$compactness_mean,
concavity_mean = input$concavity_mean
)
cls <- predict(rf_wf, new_data = newdat, type = "class")
prb <- predict(rf_wf, new_data = newdat, type = "prob")
pred_class <- cls$.pred_class[[1]]
output$single_pred <- renderText({
glue("Prediksi diagnosis: {pred_class}")
})
output$single_proba <- renderDT({
datatable(prb, options = list(dom = "t"))
})
})
# BATCH PREDICTION
batch_data <- reactive({
req(input$csv_file)
df_raw <- readr::read_csv(input$csv_file$datapath, show_col_types = FALSE)
# cek kolom wajib
missing <- setdiff(required_cols, names(df_raw))
validate(need(length(missing) == 0,
paste("Kolom wajib:", paste(missing, collapse = ", "))))
df <- df_raw %>% mutate(across(all_of(required_cols), as.numeric))
df
})
preds_df <- reactive({
df <- batch_data()
cls <- predict(rf_wf, new_data = df, type = "class")
prb <- predict(rf_wf, new_data = df, type = "prob")
bind_cols(df, tibble(pred_diagnosis = cls$.pred_class), prb)
})
output$batch_table <- renderDT({
req(preds_df())
datatable(preds_df(), options = list(pageLength = 10))
})
output$download_preds <- downloadHandler(
filename = function() paste0("prediksi_breastcancer_", format(Sys.time(), "%Y%m%d_%H%M%S"), ".csv"),
content = function(file){
write_csv(preds_df(), file)
}
)
}
# 5) AKTIFKAN SHINY
shinyApp(ui, server)## PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
Shiny applications not supported in static R Markdown documents