if (!require("shiny")) install.packages("shiny")
if (!require("naivebayes")) install.packages("naivebayes")
if (!require("e1071")) install.packages("e1071")
if (!require("caret")) install.packages("caret")
if (!require("shinythemes")) install.packages("shinythemes")
if (!require("shinyjs")) install.packages("shinyjs")
library(shiny)
library(naivebayes)
library(e1071)
library(caret)
library(shinythemes)
library(shinyjs)
# 데이터 불러오기
movie <- read.csv("c:\\data\\movie2.csv", stringsAsFactors=TRUE, fileEncoding = "euc-kr")
# 결측치 확인
colSums(is.na(movie))
# 훈련 데이터와 테스트 데이터로 분리
set.seed(1)
k <- createDataPartition(movie$장르, p=0.8, list=F)
train_data <- movie[k, ]
test_data <- movie[-k, ]
# 나이브 베이즈 모델 생성
new_model <- naive_bayes(장르 ~ ., data=train_data)
# UI 정의
ui <- fluidPage(
useShinyjs(),
theme = shinytheme("flatly"),
tags$head(
tags$style(HTML("
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@600&display=swap');
body {
font-family: 'Noto Sans KR', sans-serif;
font-weight: 600;
background-color: #1c1c1e;
color: #ffffff;
}
.title-panel {
text-align: center;
margin-bottom: 20px;
color: #ffffff;
}
.input-panel {
background-color: #2c2c2e;
padding: 20px;
border-radius: 10px;
margin-bottom: 20px;
}
.result-panel {
background-color: #2c2c2e;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
display: none;
}
.btn-primary {
width: 100%;
margin-top: 10px;
background-color: #5c656a;
border: none;
}
.btn-primary:hover {
background-color: #252a2d;
}
.input-panel h3 {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
text-align: center;
}
"))
),
titlePanel(
div(
"영화 장르 예측기",
class = "title-panel",
style = "margin: 0 auto; width: 100%; max-width: 600px;"
)
),
div(
class = "input-panel",
h3("입력 정보를 선택하세요"),
fluidRow(
column(6, selectInput("age", "나이", choices = unique(movie$나이), selected = unique(movie$나이)[1])),
column(6, selectInput("gender", "성별", choices = unique(movie$성별), selected = unique(movie$성별)[1]))
),
fluidRow(
column(6, selectInput("job", "직업", choices = unique(movie$직업), selected = unique(movie$직업)[1])),
column(6, selectInput("married", "결혼여부", choices = unique(movie$결혼여부), selected = unique(movie$결혼여부)[1]))
),
fluidRow(
column(6, selectInput("relationship", "이성친구 여부", choices = unique(movie$이성친구), selected = unique(movie$이성친구)[1]))
),
fluidRow(
column(12, actionButton("predict", "예측하기", class = "btn btn-primary"))
)
),
div(
id = "result-box",
class = "result-panel",
h3("예측 결과"),
verbatimTextOutput("prediction")
),
tags$script(HTML("
$(document).ready(function() {
window.resizeTo(400, 800);
});
"))
)
# 서버 로직 정의
server <- function(input, output, session) {
observeEvent(input$predict, {
test_data <- data.frame(
나이 = input$age,
성별 = input$gender,
직업 = input$job,
결혼여부 = input$married,
이성친구 = input$relationship
)
result <- predict(new_model, test_data, type = "prob")
output$prediction <- renderPrint({
result
})
show("result-box")
})
hide("result-box")
}
# Shiny 앱 실행
shinyApp(ui = ui, server = server)