library(randomForest)
## randomForest 4.7-1.2
## Type rfNews() to see new features/changes/bug fixes.
df <- read.delim(file.choose(), sep = "\t", , stringsAsFactors=FALSE)

# 2. 의미 기반 수치 매핑 정의

 

# Sonority (낮음 → 높음)

sonority_map <- c("sto"=1,   # stop

                  "aff"=2,   # affricate

                  "fri"=3,   # fricative

                  "nas"=4,   # nasal

                  "liq"=5,   # liquid

                  "glide"=6, # glide (if any)

                  "vow"=7)   # vowel

 

# Anteriority (앞 → 뒤)

ant_map <- c("lab"=1,  # labial

             "den"=2,  # dental

             "alv"=3,  # alveolar

             "pal"=4,  # palatal

             "vel"=5,  # velar

             "glo"=6)  # glottal

 

# Height (낮음 → 높음)

height_map <- c("low"=1, "mid"=2, "hig"=3)

 

# Frontness (뒤 → 앞)

front_map <- c("bac"=1, "cen"=2, "fro"=3)

 

# 자질별 매핑 적용 함수

map_to_numeric <- function(col, map) {

  as.numeric(map[as.character(col)])

}

 

# 3. sonority 자질 매핑 적용

df$son_o1 <- map_to_numeric(df$manner_o1, sonority_map)

df$son_c1 <- map_to_numeric(df$manner_c1, sonority_map)

df$son_o2 <- map_to_numeric(df$manner_o2, sonority_map)

df$son_c2 <- map_to_numeric(df$manner_c2, sonority_map)

 

# 4. anteriority 자질 매핑 적용

df$ant_o1 <- map_to_numeric(df$place_o1, ant_map)

df$ant_c1 <- map_to_numeric(df$place_c1, ant_map)

df$ant_o2 <- map_to_numeric(df$place_o2, ant_map)

df$ant_c2 <- map_to_numeric(df$place_c2, ant_map)

 

# 5. height 및 frontness 매핑

df$hei1 <- map_to_numeric(df$height1, height_map)

df$hei2 <- map_to_numeric(df$height2, height_map)

df$fro1 <- map_to_numeric(df$front1, front_map)

df$fro2 <- map_to_numeric(df$front2, front_map)

 

# 7. 타겟 변수 변환 (1 = male, -1 = female)

df$gen <- factor(df$gen, levels=c(-1, 1), labels=c("female", "male"))

 

# 8. 사용할 변수 목록 정의 및 결측치 제거

numeric_vars <- c("son_o1", "son_c1", "son_o2", "son_c2",

                  "ant_o1", "ant_c1", "ant_o2", "ant_c2",

                  "hei1", "hei2", "fro1", "fro2")

used_vars <- c(numeric_vars,"gen")

 

df <- df[, used_vars]

 

# numeric 변수에 한해서 NA를 0으로 대체

df[numeric_vars][is.na(df[numeric_vars])] <- 0

 

 

# 9. 훈련/테스트 데이터 나누기

set.seed(423)

train_idx <- sample(nrow(df), 0.7 * nrow(df))

df.train <- df[train_idx, ]

df.test <- df[-train_idx, ]

 

# 10. 랜덤 포레스트 모델 훈련

set.seed(12335)

rf.model <- randomForest(gen ~ ., data = df.train,

                         na.action = na.roughfix, importance = TRUE)

 

# 11. 테스트셋 예측 및 정확도 평가

rf.pred <- predict(rf.model, newdata = df.test)

cat("혼동 행렬:\\n")
## 혼동 행렬:\n
print(table(Actual = df.test$gen, Predicted = rf.pred))
##         Predicted
## Actual   female male
##   female     61   24
##   male       26   69
cat("정확도:", mean(df.test$gen == rf.pred), "\\n")
## 정확도: 0.7222222 \n
# 12. 변수 중요도 시각화

windows(width=7.0, height=5.5)

varImpPlot(rf.model, pch=21, color="black", bg="skyblue", pt.cex=1.2,

           main="Variable Importance for Gender Classification")

 

# 13. 변수 중요도 수치 출력

importance(rf.model)
##            female       male MeanDecreaseAccuracy MeanDecreaseGini
## son_o1  1.2914970 -1.9496890           -0.4054327        14.963669
## son_c1 14.8594878 11.8452764           18.0717910        10.502598
## son_o2  4.5226700  6.0416219            8.4039039        13.603077
## son_c2  7.9311518  2.5754257            8.4337160         9.026777
## ant_o1 -2.2627602 -0.9534533           -2.4735057        12.605761
## ant_c1 17.2279482 13.0329328           20.4751445        13.212391
## ant_o2  7.9166599  9.7191330           13.6774057        14.069727
## ant_c2 11.9559484  2.9854032           11.6268125        13.579563
## hei1   -0.4927563  3.5149737            1.9949087        11.221710
## hei2    7.1946261 -1.0777629            4.8078016        13.438683
## fro1   -5.5576443  8.9082679            2.8438871         7.801489
## fro2    1.8272455  8.8572443            7.7221908         8.277980