This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.
When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
set.seed(123)
library(readr)
library(dplyr)
##
## 다음의 패키지를 부착합니다: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(caret)
## 필요한 패키지를 로딩중입니다: ggplot2
## 필요한 패키지를 로딩중입니다: lattice
df<- read_csv("C:/Users/lg/Downloads/wage_missing_train.csv")
## Rows: 115000 Columns: 29
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (6): Y, age, child, studftpt, industry, state
## lgl (23): male, female, white, black, asian, hispanic, private, privatenp, g...
##
## ℹ 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.
df_test <- read_csv("C:/Users/lg/OneDrive/바탕 화면/wage_missing_test.csv")
## Rows: 64148 Columns: 29
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (6): Y, age, child, studftpt, industry, state
## lgl (23): male, female, white, black, asian, hispanic, private, privatenp, g...
##
## ℹ 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.
# 2. 결측치 제거 (Random Forest는 NA 처리 안 됨)
df <- na.omit(df)
# 3. Y는 factor로 설정 (이미 factor일 가능성 높지만 명시적으로)
df$Y <- as.factor(df$Y)
# 4. 데이터 분할
set.seed(123)
train_idx <- createDataPartition(df$Y, p = 0.8, list = FALSE)
train_df <- df[train_idx, ]
test_df <- df[-train_idx, ]
# 2. 논리형 변수 → 수치형으로 변환
logical_vars <- names(df_test)[sapply(df_test, is.logical)]
df_test[logical_vars] <- lapply(df_test[logical_vars], as.numeric)
# 3. 정규화 (train 기준 평균, 표준편차 사용 — rf_tuned가 train_df 기준이기 때문)
scale_vars <- c("age", "child")
scale_means <- sapply(train_df[scale_vars], mean)
scale_sds <- sapply(train_df[scale_vars], sd)
df_test[scale_vars] <- scale(df_test[scale_vars], center = scale_means, scale = scale_sds)
# 4. 결측치 제거
df_test <- na.omit(df_test)
# 5. Y를 factor로 변환 (train_df의 Y와 같은 levels 사용)
df_test$Y <- factor(df_test$Y, levels = levels(train_df$Y)) # usually "Zero", "One"
sapply(df,class)
## Y male female white black asian hispanic private
## "factor" "logical" "logical" "logical" "logical" "logical" "logical" "logical"
## privatenp govfed govsta govloc age married child childpres
## "logical" "logical" "logical" "logical" "numeric" "logical" "numeric" "logical"
## veteran gr12 high scol asso bach mast grad
## "logical" "logical" "logical" "logical" "logical" "logical" "logical" "logical"
## citizen union studftpt industry state
## "logical" "logical" "numeric" "numeric" "numeric"
Note that the echo = FALSE parameter was added to the
code chunk to prevent printing of the R code that generated the
plot.
set.seed(123)
library(randomForest)
## randomForest 4.7-1.2
## Type rfNews() to see new features/changes/bug fixes.
##
## 다음의 패키지를 부착합니다: 'randomForest'
## The following object is masked from 'package:ggplot2':
##
## margin
## The following object is masked from 'package:dplyr':
##
## combine
# 5. 모델 학습
model_rf <- randomForest(Y ~ ., data = train_df, ntree = 100, importance = TRUE)
# 6. 예측
#pred_rf <- predict(model_rf, newdata = df_test)
# 7. 평가
#confusionMatrix(pred_rf, df_test$Y)
# 8. 변수 중요도 시각화
#varImpPlot(model_rf)
set.seed(123)
# 원본 데이터에서 설계행렬 생성 (모델링용)
x_all <- model.matrix(Y ~ ., data = df)[, -1] # Y 제외한 설명변수
# Y를 0/1 numeric으로 변환
y_numeric <- ifelse(df$Y == "1" | df$Y == "One", 1, 0)
# 데이터 분할
set.seed(123) # 재현 가능성
train_idx <- caret::createDataPartition(y_numeric, p = 0.8, list = FALSE)
x_train <- x_all[train_idx, ]
x_test <- x_all[-train_idx, ]
y_train_numeric <- y_numeric[train_idx]
y_test_numeric <- y_numeric[-train_idx]
# ✅ 지금 요청한 부분: factor로 변환
y_train_factor <- factor(y_train_numeric, levels = c(0, 1), labels = c("0", "1"))
y_test_factor <- factor(y_test_numeric, levels = c(0, 1), labels = c("0", "1"))
set.seed(123)
control <- trainControl(
method = "cv", # 교차검증 방식
number = 5, # 폴드 수
classProbs = TRUE, # 확률 예측
summaryFunction = twoClassSummary # ROC, Sens, Spec 사용
)
# 3. 튜닝할 파라미터 그리드 정의
grid <- expand.grid(mtry = c(1, 2, 3))
# Y를 factor로 변환하면서 처음부터 레벨을 caret-friendly하게 지정
y_train_factor <- factor(y_train_numeric, levels = c(0,1), labels = c("Zero", "One"))
y_test_factor <- factor(y_test_numeric, levels = c(0,1), labels = c("Zero", "One"))
# 최종 데이터프레임 구성
train_df <- data.frame(Y = y_train_factor, x_train)
test_df <- data.frame(Y = y_test_factor, x_test)
# 4. 모델 학습
rf_tuned <- train(
Y ~ ., data = train_df,
method = "rf",
metric = "ROC", # 최적화 기준: ROC AUC
trControl = control,
tuneGrid = grid,
ntree = 200
)
# 5. 결과 확인
print(rf_tuned)
## Random Forest
##
## 34995 samples
## 28 predictor
## 2 classes: 'Zero', 'One'
##
## No pre-processing
## Resampling: Cross-Validated (5 fold)
## Summary of sample sizes: 27996, 27996, 27995, 27997, 27996
## Resampling results across tuning parameters:
##
## mtry ROC Sens Spec
## 1 0.5586708 0.000000000 1.0000000
## 2 0.5648761 0.002150908 0.9995294
## 3 0.5663210 0.022113449 0.9913148
##
## ROC was used to select the optimal model using the largest value.
## The final value used for the model was mtry = 3.
plot(rf_tuned)
set.seed(123)
# 1. factor 변환
train_df$Y <- factor(y_train_numeric, levels = c(0,1), labels = c("Zero", "One"))
test_df$Y <- factor(y_test_numeric, levels = c(0,1), labels = c("Zero", "One"))
# 2. formula 정의
f <- as.formula(Y ~ .)
# 3. model.matrix 적용 (동일하게)
x_train <- model.matrix(f, data = train_df)[, -1]
x_test <- model.matrix(f, data = test_df)[, -1]
# 4. 다시 데이터프레임으로 구성
train_df_final <- data.frame(Y = train_df$Y, x_train)
test_df_final <- data.frame(Y = test_df$Y, x_test)
grid <- expand.grid(mtry = 3) # 고정
# 5. 모델 학습
rf_tuned <- train(
Y ~ ., data = train_df_final,
method = "rf",
metric = "ROC",
trControl = control,
tuneGrid = grid,
ntree = 200
)
# 6. 예측
pred_rf <- predict(rf_tuned, newdata = test_df_final)
# 예측
#pred_rf <- predict(rf_tuned, newdata = test_df_final)
set.seed(123)
# 평가
library(caret)
conf_rf <- confusionMatrix(pred_rf, test_df_final$Y, positive = "One")
# 결과 출력
cat("정확도:", round(conf_rf$overall["Accuracy"], 4), "\n")
## 정확도: 0.661
cat("특이도(Specificity):", round(conf_rf$byClass["Specificity"], 4), "\n")
## 특이도(Specificity): 0.0222
cat("민감도(Sensitivity):", round(conf_rf$byClass["Sensitivity"], 4), "\n")
## 민감도(Sensitivity): 0.9905
conf_rf
## Confusion Matrix and Statistics
##
## Reference
## Prediction Zero One
## Zero 66 55
## One 2911 5716
##
## Accuracy : 0.661
## 95% CI : (0.6509, 0.6709)
## No Information Rate : 0.6597
## P-Value [Acc > NIR] : 0.4068
##
## Kappa : 0.0165
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.99047
## Specificity : 0.02217
## Pos Pred Value : 0.66257
## Neg Pred Value : 0.54545
## Prevalence : 0.65969
## Detection Rate : 0.65341
## Detection Prevalence : 0.98617
## Balanced Accuracy : 0.50632
##
## 'Positive' Class : One
##
saveRDS(rf_tuned,"tuned_model_rds")