R Markdown

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"

Including Plots

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")