본 분석은 피마 인디언 당뇨 데이터셋을 활용하여 생체 지표(혈당, BMI 등)가 당뇨병 발병에 미치는 영향을 분석하고, 머신러닝 모델을 통해 발병 여부를 예측하는 것을 목적으로 함.
데이터 구조 확인 중 이상치 발견
-> 이상치 제거 후 데이터 수 감소 (768 -> 392)
library(mlbench)
data(PimaIndiansDiabetes)
df <- PimaIndiansDiabetes
# 데이터 구조 확인
str(df)
## 'data.frame': 768 obs. of 9 variables:
## $ pregnant: num 6 1 8 1 0 5 3 10 2 8 ...
## $ glucose : num 148 85 183 89 137 116 78 115 197 125 ...
## $ pressure: num 72 66 64 66 40 74 50 0 70 96 ...
## $ triceps : num 35 29 0 23 35 0 32 0 45 0 ...
## $ insulin : num 0 0 0 94 168 0 88 0 543 0 ...
## $ mass : num 33.6 26.6 23.3 28.1 43.1 25.6 31 35.3 30.5 0 ...
## $ pedigree: num 0.627 0.351 0.672 0.167 2.288 ...
## $ age : num 50 31 32 21 33 30 26 29 53 54 ...
## $ diabetes: Factor w/ 2 levels "neg","pos": 2 1 2 1 2 1 2 1 2 2 ...
head(df)
## pregnant glucose pressure triceps insulin mass pedigree age diabetes
## 1 6 148 72 35 0 33.6 0.627 50 pos
## 2 1 85 66 29 0 26.6 0.351 31 neg
## 3 8 183 64 0 0 23.3 0.672 32 pos
## 4 1 89 66 23 94 28.1 0.167 21 neg
## 5 0 137 40 35 168 43.1 2.288 33 pos
## 6 5 116 74 0 0 25.6 0.201 30 neg
# 이상치 발견 및 처리
library(dplyr)
##
## 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
df_final <- df %>%
mutate(across(c(glucose, pressure, triceps, insulin, mass, age, pedigree),
~ ifelse(. == 0, NA, .))) %>%
filter(complete.cases(.))
결측치 및 이상치 유무 확인과 변수 간의 상관성 확인을 통해 데이터 타당성 검토.
# 상관관계 분석 및 시각화
library(ggcorrplot)
## Loading required package: ggplot2
corr <- round(cor(df_final[, -9]), 1) # 마지막 열(당뇨유무) 제외하고 계산, 소숫점 1자리까지 표기
ggcorrplot(corr, hc.order = TRUE, type = "lower", lab = TRUE)
분석의 재현성을 높이기 위해 기준점 생성 후 전체 70%에 해당하는 행을 무작위 추첨.
-> 이를 학습용으로 지정.
-> 남은 30%를 시험용으로 지정.
추첨된 274개의 행 중에 Diabetes를 제외한 나머지 변수들과 Diabetes 유무 사이의 관계 학습.
-> 새로운 변수값을 넣었을 때 당뇨일 확률(0~1) 분석.
set.seed(123) #분석의 재현성을 보장하기 위함.
idx <- sample(1:nrow(df_final), nrow(df_final) * 0.7)
train_data <- df_final[idx, ]
test_data <- df_final[-idx, ]
# 로지스틱 회귀 모델 생성
model <- glm(diabetes ~ ., data = train_data, family = "binomial")
이상치 제거로 인해 데이터량이 절반 가량 줄었으므로, 각 변수의 P-value값 확인.
-> 이상치 제거 전에는 여러 변수가 중요해 보였으나, 정제 후 분석 결과 Glucose만 압도적 유의성을 보임.
-> 기존에 중요하게 나타났던 Pregnant는 이상치를 제거하자 통계적 유의성을 잃었음.
summary(model)
##
## Call:
## glm(formula = diabetes ~ ., family = "binomial", data = train_data)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -1.047e+01 1.480e+00 -7.075 1.49e-12 ***
## pregnant -1.818e-02 6.877e-02 -0.264 0.7915
## glucose 4.384e-02 7.520e-03 5.830 5.54e-09 ***
## pressure -8.082e-03 1.559e-02 -0.518 0.6042
## triceps 4.754e-03 2.086e-02 0.228 0.8197
## insulin -6.464e-04 1.651e-03 -0.391 0.6955
## mass 8.197e-02 3.460e-02 2.369 0.0178 *
## pedigree 1.115e+00 5.234e-01 2.130 0.0332 *
## age 4.628e-02 2.310e-02 2.004 0.0451 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 353.67 on 273 degrees of freedom
## Residual deviance: 237.71 on 265 degrees of freedom
## AIC: 255.71
##
## Number of Fisher Scoring iterations: 5
학습 이후 당뇨 유무 예측에 가장 효과있는 변수 확인.
model 전체 중 각 변수의 영향력값 추출 후 절대값 확인.
-> important로 지정.
-> important가 높은 순으로 막대그래프 생성.
# 변수 중요도 시각화
importance <- abs(summary(model)$coefficients[-1, "z value"])
barplot(sort(importance, decreasing = TRUE), col = "steelblue", las = 2, main = "Feature Importance")
학습 모델의 결과값 그래프 도출.
test_data 결과 도출.(0~1 사이값)
-> 실제 결과값과 예측값 대조 후 roc_obj로 지정
-> 그래프 생성
-> 가로축: 오답을 정답으로 한 비율, 세로축: 정답을 정답으로 한 비율
# ROC 커브 시각화
library(pROC)
## Type 'citation("pROC")' for a citation.
##
## Attaching package: 'pROC'
## The following objects are masked from 'package:stats':
##
## cov, smooth, var
pred <- predict(model, newdata = test_data, type = "response")
roc_obj <- roc(test_data$diabetes, pred)
## Setting levels: control = neg, case = pos
## Setting direction: controls < cases
plot(roc_obj, col = "red", main = paste("ROC Curve (AUC =", round(auc(roc_obj), 3), ")"))
이상치를 제거하여 데이터가 768개에서 392개로 감소했음에도 불구하고, AUC 수치가 0.803으로 나타남. 이는 Model이 새로운 데이터를 접했을 때 당뇨 여부를 상당히 높은 정확도로 예측 가능하다고 판단할 수 있음.
당뇨 예측의 가장 결정적인 영향을 미치는 핵심 인자는 Glucose이며, 뒤를 이어 Mass, Pedigree, Age가 유의미한 예측 인자로 확인됨(P < 0.05).
반면, 기존 분석에서 중요하게 다뤄졌던 Pregnant는 이상치 제거 후 통계적 유의성을 상실함(P-value 0.79). 이는 측정 오류가 포함된 데이터가 모델의 판단을 왜곡시킬 수 있음을 보여주며, 당뇨 예측에는 임신 횟수보다 내과적 지표와 유전적 요인이 더 본질적인 인자임을 입증함.
1.Model의 교차 검증
-> 난수 시드값을 다양하게 적용하여 특정 데이터에만 편향된 것이 아님을 입증해야함.
2.변수 선택 최적화
-> 유의미하지 않은 인자들을 제외한 간소화된 모델의 성능 변화를 확인할 필요가 있음.