1 로지스틱 회귀분석 개요


많은 경영상의 문제와 결정은 사건이나 행동의 발생 확률을 추정하거나 이해하는 것에 관련 있습니다.
그리고 이런 사건, 행동은 이분법적인 경향이 있습니다. 이 경우 상관 관계 분석은 독립변수로 이원 종속변수(binary dependent variable; 0 또는 1 값만 가짐)를 추정합니다.

예를 들면 다음과 같습니다.

  • 인구통계학적 변수로 신문을 구독할 것인지(종속 변수=1), 구독하지 않을 것인지(종속 변수=0)를 예측한다.
  • 고객의 RFM 등급으로 특정 고객이 DM 캠페인에 응답할 것인지, 하지 않을 것인지 예측한다.
  • 고객의 프로필과 최근 행동변수의 조합으로 이동통신 가입자가 다른 이동통신 사로 이탈할지, 유지할지를 예측한다.


2 로지스틱 회귀모델


이원 종속 변수의 확률을 𝑝라고 가정합니다.
대부분 확률 \(𝑝\)와 독립 변수의 관계는 비선형입니다.
승산비(odds ratio) $𝑝/(1−𝑝) $는 질 확률(종속 변수=0) 대비 이길 확률(종속 변수=1)의 비율입니다.
이를 로그 승산비로 변환했을 때 아래 같이 독립변수와의 선형 회귀 모델화 할 수 있습니다.

\[ln⁡(𝑝/(1−𝑝 )=𝛽_0+𝛽_1 x_1+ 𝛽_2 𝑥_2+⋯+𝛽_𝑛 𝑥_𝑛−① \]
①의 식 양쪽에 \(exp⁡(𝑥)\)를 적용하면 아래와 같이 변환됩니다.

\[𝑝=(exp⁡(𝛽_0+𝛽_1 𝑥_1+⋯+𝛽_𝑛 𝑥_𝑛))/(1+exp⁡(𝛽_0+𝛽_1 𝑥_1+⋯+𝛽_𝑛 𝑥_𝑛))−②\] \[1−𝑝=1/(1+exp⁡(𝛽_0+𝛽_1 𝑥_1+⋯+𝛽_𝑛 𝑥_𝑛))−③ \]

3 로지스틱 회귀 모델의 추정


로지스틱 회귀 모델은 전체 대상의 확률 또는 우도(likelihood)를 최대화하는 parameter \(𝛽\)를 추정합니다.
하지만 각각의 확률의 곱인 전체 발생확률은 매우 작은 값이므로 아래 식과 같이 자연 로그(\(ln\))를 취해서 로그 우도를 최대화합니다.

\[ loglikelihood = ln(𝑝_1× 𝑝_2×⋯×𝑝_𝑛)=ln(p_1)+ln(p_2)+⋯ + ln(p_n)\]


3.1 혼동행렬 (Confusion Matrix)


아래 있는 혼동행렬에서 구해지는 정확도(Accuracy), 정밀도(Precision), 재현율(Recall), F1-score, Sensitivity(민감도), Specificity(특이도), ROC, AUC 와 같은 정확도 지표를 최대화하는 parameter 𝛽를 추정할 수도 있습니다.



3.2 민감도(Sensitivity), 재현율(recall) or TPR

\[Sensitivity\,(민감도)\;recall\,(재현율),\; hit\, rate,\; or\; TPR = TP / (TP+FN)\,;\quad 실제\;Positive\,중\;예측이\;맞은\;비율\]

3.3 특이도(Specificity), selectivity or TNR

\[Specificity\,(특이도)\;selectivity\; or\; TNR = FP / (FP+TN)\,;\quad 실제\;Negative\,중\;예측이\;맞은\;비율\]

3.4 정밀도(Precision), PPV or PVP

\[정밀도(Precision)\, ,\; positive\; predictive\; value\; (PPV)\; or\;PVP = TP / (TP+FP)\,;\quad Positive\,예측\;중\;예측이\;맞은\;비율\]

3.5 NPV or PVN

\[negative\; predictive\; value\, (NPV) or\;PVN = TN / (TN+FN)\,;\quad Negative\,예측\;중\;예측이\;맞은\;비율\]

3.6 정확도(Accuracy)

\[정확도\,(Accuracy) = (TP+TN) / (TP+FN+FP+TN)\,;\quad 전체\;중\;예측이\;맞은\;비율\]

3.7 F1 - score

\[F1 - score = (2×𝑃𝑟𝑒𝑠𝑐𝑖𝑠𝑖𝑜𝑛×𝑅𝑒𝑐𝑎𝑙𝑙)/(𝑃𝑟𝑒𝑐𝑖𝑠𝑖𝑜𝑛+𝑅𝑒𝑐𝑎𝑙𝑙)\,;\quad Precision\;과\;Recall의\;조화\;평균\]


4 로지스틱 회귀분석 실습



R에서 로지스틱 회귀분석은 glm() 함수를 활용합니다.

glm(formula, data, family = “binomial”)
ㅇ formula : 반응변수 ~ 설명변수1+ 설명변수2+ ….
ㅇ data : data = 데이터 이름
ㅇ family : 오차 분포와 링크 함수(link function), 로지스틱 회귀모형 family = “binomial”으로 지정


4.1 diabetes 데이터 불러오기


diabetes.csv 파일을 저장되어 있는 디렉토리에서 불러오고, 데이터프레임으로 바꾼 뒤 변수들 형태를 봅니다.


library(readr)
diabetes <- read_csv("~/archive/diabetes.csv")
## 
## -- Column specification --------------------------------------------------------
## cols(
##   Pregnancies = col_double(),
##   Glucose = col_double(),
##   BloodPressure = col_double(),
##   SkinThickness = col_double(),
##   Insulin = col_double(),
##   BMI = col_double(),
##   DiabetesPedigreeFunction = col_double(),
##   Age = col_double(),
##   Outcome = col_double()
## )
diabetes2 <- as.data.frame(diabetes)
str(diabetes2)
## 'data.frame':    768 obs. of  9 variables:
##  $ Pregnancies             : num  6 1 8 1 0 5 3 10 2 8 ...
##  $ Glucose                 : num  148 85 183 89 137 116 78 115 197 125 ...
##  $ BloodPressure           : num  72 66 64 66 40 74 50 0 70 96 ...
##  $ SkinThickness           : num  35 29 0 23 35 0 32 0 45 0 ...
##  $ Insulin                 : num  0 0 0 94 168 0 88 0 543 0 ...
##  $ BMI                     : num  33.6 26.6 23.3 28.1 43.1 25.6 31 35.3 30.5 0 ...
##  $ DiabetesPedigreeFunction: num  0.627 0.351 0.672 0.167 2.288 ...
##  $ Age                     : num  50 31 32 21 33 30 26 29 53 54 ...
##  $ Outcome                 : num  1 0 1 0 1 0 1 0 1 1 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   Pregnancies = col_double(),
##   ..   Glucose = col_double(),
##   ..   BloodPressure = col_double(),
##   ..   SkinThickness = col_double(),
##   ..   Insulin = col_double(),
##   ..   BMI = col_double(),
##   ..   DiabetesPedigreeFunction = col_double(),
##   ..   Age = col_double(),
##   ..   Outcome = col_double()
##   .. )

9개 변수, 768개의 표본 데이터가 있습니다. 모든 변수는 수치형입니다. 이 데이터는 Pima Indian 여성들이 다른 민족에 비해 당뇨병으로 고생하는 것을 보고 원인을 파악하기 위해 연구한 데이터 셋입니다.

  • Pregnancies : Number of times pregnant
  • Glucose : Plasma glucose concentration a 2 hours in an oral glucose tolerance test
  • BloodPressure : Diastolic blood pressure (mm Hg)
  • SkinThickness : Triceps skin fold thickness (mm)
  • Insulin : 2-Hour serum insulin (mu U/ml)
  • BMI : Body mass index (weight in kg/(height in m)^2)
  • DiabetesPedigreeFunction : Diabetes pedigree function
  • Age : Age (years)
  • Outcome : Class variable (0 or 1) 268 of 768 are 1, the others are 0



변수의 이름이 너무 길어서 분석할 때 불편할 수 있으므로 이름을 간단하게 바꿉니다.

names(diabetes2)<-c("임신횟수","글루코즈","혈압","피부두께","인슐린","BMI","당뇨유전인자","나이","당뇨유무")


4.2 로지스틱 회귀분석 모델링


4.2.1 필요 패키지 활성화



필요 패키지1 를 활성화합니다.

library(Epi)
library(kableExtra)
# library(pROC)
# library(ztable)
# library(moonBook)
# library(caret)


4.2.2 탐색적 데이터 분석(EDA: Exploratory Data Analysis)



전체적인 기술통계를 보고, 이진변수인 당뇨유무를 제외한 나머지 변수의 변동계수로 데이터 산포정도를 살펴봅니다.

options(digits=2)
diabetes2$당뇨유무 <- as.factor(diabetes2$당뇨유무)
summary(diabetes2) %>%
kbl(align = "c") %>%
  kable_paper(full_width = F) %>%
  column_spec(2:10, bold = T, border_right = T, background = "lightyellow") 
임신횟수 글루코즈 혈압 피부두께 인슐린 BMI 당뇨유전인자 나이 당뇨유무
Min. : 0.0 Min. : 0 Min. : 0 Min. : 0 Min. : 0 Min. : 0 Min. :0.08 Min. :21 0:500
1st Qu.: 1.0 1st Qu.: 99 1st Qu.: 62 1st Qu.: 0 1st Qu.: 0 1st Qu.:27 1st Qu.:0.24 1st Qu.:24 1:268
Median : 3.0 Median :117 Median : 72 Median :23 Median : 30 Median :32 Median :0.37 Median :29 NA
Mean : 3.8 Mean :121 Mean : 69 Mean :21 Mean : 80 Mean :32 Mean :0.47 Mean :33 NA
3rd Qu.: 6.0 3rd Qu.:140 3rd Qu.: 80 3rd Qu.:32 3rd Qu.:127 3rd Qu.:37 3rd Qu.:0.63 3rd Qu.:41 NA
Max. :17.0 Max. :199 Max. :122 Max. :99 Max. :846 Max. :67 Max. :2.42 Max. :81 NA
cv <- lapply(diabetes2[,-9],function(x){sd(x)/mean(x)})
cv %>% unlist() %>% sort(decreasing = T) %>%
kbl(align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
x
인슐린 1.44
임신횟수 0.88
피부두께 0.78
당뇨유전인자 0.70
나이 0.35
혈압 0.28
글루코즈 0.26
BMI 0.25



인슐린이 상대적으로 가장 높은 산포를 보입니다.

변수간 상관관계를 살펴봅니다.

library(ggplot2)
library(RColorBrewer)
library(psych)
## 
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
pairs.panels(diabetes2)


당뇨유뮤와는 글루코즈(0.47), BMI(0.29), 나이(0.24), 임신횟수(0.22) 등의 순으로 상관관계가 높은 것으로 나타납니다.



Pigma Indian 여성들 관련 위의 정보가 있을 때 그들에 대한 당뇨 가능성을 예측하기 위해 로지스틱 회귀모델 분석을 시도 합니다.

### 트레이닝, 테스트 데이터 분리

7:3으로 training,test를 분리합니다.

set.seed(100)
index <- sample(1:nrow(diabetes2), size = nrow(diabetes2) * 0.7)
training <- diabetes2[index, ]
test <- diabetes2[-index, ]


4.2.3 로지스틱 회귀분석 모델링



glm() 함수를 이용하여 종속변수=당뇨유무, 독립변수 그 외 모든 변수로 하는 로지스틱 회귀모델을 구하고, summary() 함수로 모델 정보를 확인합니다.

diabetes2$당뇨유무 <- as.numeric(diabetes2$당뇨유무)
d1 <- glm(당뇨유무 ~ ., data = training, family = binomial)
summary(d1)
## 
## Call:
## glm(formula = 당뇨유무 ~ ., family = binomial, data = training)
## 
## Deviance Residuals: 
##    Min      1Q  Median      3Q     Max  
## -2.462  -0.734  -0.439   0.786   2.769  
## 
## Coefficients:
##              Estimate Std. Error z value Pr(>|z|)    
## (Intercept)  -7.61831    0.79596   -9.57  < 2e-16 ***
## 임신횟수      0.10066    0.03847    2.62   0.0089 ** 
## 글루코즈      0.03452    0.00430    8.03  9.7e-16 ***
## 혈압         -0.01469    0.00600   -2.45   0.0144 *  
## 피부두께     -0.00171    0.00817   -0.21   0.8341    
## 인슐린       -0.00139    0.00101   -1.37   0.1716    
## BMI           0.07424    0.01762    4.21  2.5e-05 ***
## 당뇨유전인자  0.78653    0.34757    2.26   0.0236 *  
## 나이          0.01962    0.01105    1.78   0.0756 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 697.86  on 536  degrees of freedom
## Residual deviance: 523.53  on 528  degrees of freedom
## AIC: 541.5
## 
## Number of Fisher Scoring iterations: 5


위의 결과를 볼 때 의미 없는 변수들도 있기 때문에 이들을 제거한 모델을 찾겠습니다.


4.2.4 backward stepwise 모델링


d2 <- step(d1,direction="backward")
## Start:  AIC=542
## 당뇨유무 ~ 임신횟수 + 글루코즈 + 혈압 + 피부두께 + 인슐린 + BMI + 
##     당뇨유전인자 + 나이
## 
##                Df Deviance AIC
## - 피부두께      1      524 540
## - 인슐린        1      525 541
## <none>                 524 542
## - 나이          1      527 543
## - 당뇨유전인자  1      529 545
## - 혈압          1      530 546
## - 임신횟수      1      531 547
## - BMI           1      543 559
## - 글루코즈      1      605 621
## 
## Step:  AIC=540
## 당뇨유무 ~ 임신횟수 + 글루코즈 + 혈압 + 인슐린 + BMI + 당뇨유전인자 + 
##     나이
## 
##                Df Deviance AIC
## <none>                 524 540
## - 인슐린        1      526 540
## - 나이          1      527 541
## - 당뇨유전인자  1      529 543
## - 혈압          1      530 544
## - 임신횟수      1      531 545
## - BMI           1      545 559
## - 글루코즈      1      608 622
summary(d2)
## 
## Call:
## glm(formula = 당뇨유무 ~ 임신횟수 + 글루코즈 + 혈압 + 인슐린 + 
##     BMI + 당뇨유전인자 + 나이, family = binomial, data = training)
## 
## Deviance Residuals: 
##    Min      1Q  Median      3Q     Max  
## -2.447  -0.738  -0.440   0.784   2.763  
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)  -7.617947   0.795456   -9.58  < 2e-16 ***
## 임신횟수      0.100295   0.038449    2.61   0.0091 ** 
## 글루코즈      0.034660   0.004247    8.16  3.3e-16 ***
## 혈압         -0.014937   0.005889   -2.54   0.0112 *  
## 인슐린       -0.001473   0.000928   -1.59   0.1126    
## BMI           0.073154   0.016816    4.35  1.4e-05 ***
## 당뇨유전인자  0.780125   0.345852    2.26   0.0241 *  
## 나이          0.019915   0.010966    1.82   0.0693 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 697.86  on 536  degrees of freedom
## Residual deviance: 523.57  on 529  degrees of freedom
## AIC: 539.6
## 
## Number of Fisher Scoring iterations: 5

AIC(Akaike Information Criterion)2


최종 모델은 피부두께만을 제외하는 것을 제시하고 있습니다.


4.3 예측


4.3.1 test set에 최종 모델 적용하여 예측


test set에 최종 모델 적용하여 확률 기준 Top 10명을 추출합니다.

library(plyr)
predict2 <- predict(d2, newdata = test, type = "response")

head(sort(predict2, decreasing = TRUE),n=10)%>%
kbl(align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
x
446 0.98
207 0.94
580 0.93
246 0.92
762 0.92
760 0.91
44 0.90
260 0.88
5 0.87
57 0.87
head(arrange(data.frame(predict2,test$당뇨유무),desc(predict2)),n=10) %>%
kbl(align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
predict2 test.당뇨유무
0.98 1
0.94 1
0.93 1
0.92 1
0.92 1
0.91 1
0.90 1
0.88 1
0.87 1
0.87 1

446번 여성분이 98%로 가장 가능성이 높습니다. 그리고 예측과 실제를 비교한 결과 상위 10명 모두 당뇨병에 걸려있음을 알 수 있습니다.


4.3.2 모델 정확도 시각화


ROC curve로 시각화합니다.

predict3 <- predict(d2, newdata = test,type = "response")
ROC(predict3,test$당뇨유무, plot="ROC", AUC=T, main="logistic regression")


위의 그래프에서 최적 cut이 0.338임을 제시하고 있습니다. 즉, 확률 0.338 이상이면 당뇨로 의심하는 것을 추천하고 있습니다.
이 때 AUC3는 0.862로 좋은 수준입니다.


# 최적 컷 확인
r <- ROC(form=당뇨유무~임신횟수+글루코즈+혈압+인슐린+BMI+당뇨유전인자+나이, data=test, cuts=0.4, AUC=T)

str(r)
## List of 3
##  $ res:'data.frame': 232 obs. of  5 variables:
##   ..$ sens  : num [1:232] 1 1 0.987 0.987 0.987 ...
##   ..$ spec  : num [1:232] 0 0.00654 0.00654 0.01307 0.01961 ...
##   ..$ pvp   : num [1:232] NaN 0 0.5 0.333 0.25 ...
##   ..$ pvn   : num [1:232] 0.662 0.661 0.664 0.662 0.661 ...
##   ..$ lr.eta: num [1:232] -Inf 0.00181 0.00651 0.00684 0.0075 ...
##  $ AUC: num 0.872
##  $ lr :List of 30
##   ..$ coefficients     : Named num [1:8] -1.16e+01 1.67e-01 3.77e-02 -3.94e-03 -2.38e-04 ...
##   .. ..- attr(*, "names")= chr [1:8] "(Intercept)" "임신횟수" "글루코즈" "혈압" ...
##   ..$ residuals        : Named num [1:231] 1.34 1.03 -1.09 -1.93 153.65 ...
##   .. ..- attr(*, "names")= chr [1:231] "3" "5" "6" "8" ...
##   ..$ fitted.values    : Named num [1:231] 0.74686 0.96826 0.08164 0.48284 0.00651 ...
##   .. ..- attr(*, "names")= chr [1:231] "3" "5" "6" "8" ...
##   ..$ effects          : Named num [1:231] 2.661 2.658 4.513 0.157 0.64 ...
##   .. ..- attr(*, "names")= chr [1:231] "(Intercept)" "임신횟수" "글루코즈" "혈압" ...
##   ..$ R                : num [1:8, 1:8] -5.54 0 0 0 0 ...
##   .. ..- attr(*, "dimnames")=List of 2
##   .. .. ..$ : chr [1:8] "(Intercept)" "임신횟수" "글루코즈" "혈압" ...
##   .. .. ..$ : chr [1:8] "(Intercept)" "임신횟수" "글루코즈" "혈압" ...
##   ..$ rank             : int 8
##   ..$ qr               :List of 5
##   .. ..$ qr   : num [1:231, 1:8] -5.5387 0.0317 0.0494 0.0902 0.0145 ...
##   .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. ..$ : chr [1:231] "3" "5" "6" "8" ...
##   .. .. .. ..$ : chr [1:8] "(Intercept)" "임신횟수" "글루코즈" "혈압" ...
##   .. ..$ rank : int 8
##   .. ..$ qraux: num [1:8] 1.08 1.04 1.03 1.43 1.01 ...
##   .. ..$ pivot: int [1:8] 1 2 3 4 5 6 7 8
##   .. ..$ tol  : num 1e-11
##   .. ..- attr(*, "class")= chr "qr"
##   ..$ family           :List of 12
##   .. ..$ family    : chr "binomial"
##   .. ..$ link      : chr "logit"
##   .. ..$ linkfun   :function (mu)  
##   .. ..$ linkinv   :function (eta)  
##   .. ..$ variance  :function (mu)  
##   .. ..$ dev.resids:function (y, mu, wt)  
##   .. ..$ aic       :function (y, n, mu, wt, dev)  
##   .. ..$ mu.eta    :function (eta)  
##   .. ..$ initialize: language {     if (NCOL(y) == 1) { ...
##   .. ..$ validmu   :function (mu)  
##   .. ..$ valideta  :function (eta)  
##   .. ..$ simulate  :function (object, nsim)  
##   .. ..- attr(*, "class")= chr "family"
##   ..$ linear.predictors: Named num [1:231] 1.0819 3.4179 -2.4203 -0.0687 -5.0282 ...
##   .. ..- attr(*, "names")= chr [1:231] "3" "5" "6" "8" ...
##   ..$ deviance         : num 191
##   ..$ aic              : num 207
##   ..$ null.deviance    : num 295
##   ..$ iter             : int 5
##   ..$ weights          : Named num [1:231] 0.18906 0.03074 0.07498 0.24971 0.00647 ...
##   .. ..- attr(*, "names")= chr [1:231] "3" "5" "6" "8" ...
##   ..$ prior.weights    : Named num [1:231] 1 1 1 1 1 1 1 1 1 1 ...
##   .. ..- attr(*, "names")= chr [1:231] "3" "5" "6" "8" ...
##   ..$ df.residual      : int 223
##   ..$ df.null          : int 230
##   ..$ y                : Named num [1:231] 1 1 0 0 1 1 1 0 0 0 ...
##   .. ..- attr(*, "names")= chr [1:231] "3" "5" "6" "8" ...
##   ..$ converged        : logi TRUE
##   ..$ boundary         : logi FALSE
##   ..$ model            :'data.frame':    231 obs. of  8 variables:
##   .. ..$ 당뇨유무    : Factor w/ 2 levels "0","1": 2 2 1 1 2 2 2 1 1 1 ...
##   .. ..$ 임신횟수    : num [1:231] 8 0 5 10 8 0 1 8 13 3 ...
##   .. ..$ 글루코즈    : num [1:231] 183 137 116 115 125 118 115 99 145 88 ...
##   .. ..$ 혈압        : num [1:231] 64 40 74 0 96 84 70 84 82 58 ...
##   .. ..$ 인슐린      : num [1:231] 0 168 0 0 0 230 96 0 110 54 ...
##   .. ..$ BMI         : num [1:231] 23.3 43.1 25.6 35.3 0 45.8 34.6 35.4 22.2 24.8 ...
##   .. ..$ 당뇨유전인자: num [1:231] 0.672 2.288 0.201 0.134 0.232 ...
##   .. ..$ 나이        : num [1:231] 32 33 30 29 54 31 32 50 57 22 ...
##   .. ..- attr(*, "terms")=Classes 'terms', 'formula'  language 당뇨유무 ~ 임신횟수 + 글루코즈 + 혈압 + 인슐린 + BMI + 당뇨유전인자 + 나이
##   .. .. .. ..- attr(*, "variables")= language list(당뇨유무, 임신횟수, 글루코즈, 혈압, 인슐린, BMI, 당뇨유전인자, 나이)
##   .. .. .. ..- attr(*, "factors")= int [1:8, 1:7] 0 1 0 0 0 0 0 0 0 0 ...
##   .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. ..$ : chr [1:8] "당뇨유무" "임신횟수" "글루코즈" "혈압" ...
##   .. .. .. .. .. ..$ : chr [1:7] "임신횟수" "글루코즈" "혈압" "인슐린" ...
##   .. .. .. ..- attr(*, "term.labels")= chr [1:7] "임신횟수" "글루코즈" "혈압" "인슐린" ...
##   .. .. .. ..- attr(*, "order")= int [1:7] 1 1 1 1 1 1 1
##   .. .. .. ..- attr(*, "intercept")= int 1
##   .. .. .. ..- attr(*, "response")= int 1
##   .. .. .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 
##   .. .. .. ..- attr(*, "predvars")= language list(당뇨유무, 임신횟수, 글루코즈, 혈압, 인슐린, BMI, 당뇨유전인자, 나이)
##   .. .. .. ..- attr(*, "dataClasses")= Named chr [1:8] "factor" "numeric" "numeric" "numeric" ...
##   .. .. .. .. ..- attr(*, "names")= chr [1:8] "당뇨유무" "임신횟수" "글루코즈" "혈압" ...
##   ..$ call             : language glm(formula = form, family = binomial, data = data)
##   ..$ formula          :Class 'formula'  language 당뇨유무 ~ 임신횟수 + 글루코즈 + 혈압 + 인슐린 + BMI + 당뇨유전인자 + 나이
##   .. .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 
##   ..$ terms            :Classes 'terms', 'formula'  language 당뇨유무 ~ 임신횟수 + 글루코즈 + 혈압 + 인슐린 + BMI + 당뇨유전인자 + 나이
##   .. .. ..- attr(*, "variables")= language list(당뇨유무, 임신횟수, 글루코즈, 혈압, 인슐린, BMI, 당뇨유전인자, 나이)
##   .. .. ..- attr(*, "factors")= int [1:8, 1:7] 0 1 0 0 0 0 0 0 0 0 ...
##   .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. ..$ : chr [1:8] "당뇨유무" "임신횟수" "글루코즈" "혈압" ...
##   .. .. .. .. ..$ : chr [1:7] "임신횟수" "글루코즈" "혈압" "인슐린" ...
##   .. .. ..- attr(*, "term.labels")= chr [1:7] "임신횟수" "글루코즈" "혈압" "인슐린" ...
##   .. .. ..- attr(*, "order")= int [1:7] 1 1 1 1 1 1 1
##   .. .. ..- attr(*, "intercept")= int 1
##   .. .. ..- attr(*, "response")= int 1
##   .. .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 
##   .. .. ..- attr(*, "predvars")= language list(당뇨유무, 임신횟수, 글루코즈, 혈압, 인슐린, BMI, 당뇨유전인자, 나이)
##   .. .. ..- attr(*, "dataClasses")= Named chr [1:8] "factor" "numeric" "numeric" "numeric" ...
##   .. .. .. ..- attr(*, "names")= chr [1:8] "당뇨유무" "임신횟수" "글루코즈" "혈압" ...
##   ..$ data             :'data.frame':    231 obs. of  9 variables:
##   .. ..$ 임신횟수    : num [1:231] 8 0 5 10 8 0 1 8 13 3 ...
##   .. ..$ 글루코즈    : num [1:231] 183 137 116 115 125 118 115 99 145 88 ...
##   .. ..$ 혈압        : num [1:231] 64 40 74 0 96 84 70 84 82 58 ...
##   .. ..$ 피부두께    : num [1:231] 0 35 0 0 0 47 30 0 19 11 ...
##   .. ..$ 인슐린      : num [1:231] 0 168 0 0 0 230 96 0 110 54 ...
##   .. ..$ BMI         : num [1:231] 23.3 43.1 25.6 35.3 0 45.8 34.6 35.4 22.2 24.8 ...
##   .. ..$ 당뇨유전인자: num [1:231] 0.672 2.288 0.201 0.134 0.232 ...
##   .. ..$ 나이        : num [1:231] 32 33 30 29 54 31 32 50 57 22 ...
##   .. ..$ 당뇨유무    : Factor w/ 2 levels "0","1": 2 2 1 1 2 2 2 1 1 1 ...
##   .. ..- attr(*, "spec")=
##   .. .. .. cols(
##   .. .. ..   Pregnancies = col_double(),
##   .. .. ..   Glucose = col_double(),
##   .. .. ..   BloodPressure = col_double(),
##   .. .. ..   SkinThickness = col_double(),
##   .. .. ..   Insulin = col_double(),
##   .. .. ..   BMI = col_double(),
##   .. .. ..   DiabetesPedigreeFunction = col_double(),
##   .. .. ..   Age = col_double(),
##   .. .. ..   Outcome = col_double()
##   .. .. .. )
##   ..$ offset           : NULL
##   ..$ control          :List of 3
##   .. ..$ epsilon: num 1e-08
##   .. ..$ maxit  : num 25
##   .. ..$ trace  : logi FALSE
##   ..$ method           : chr "glm.fit"
##   ..$ contrasts        : NULL
##   ..$ xlevels          : Named list()
##   ..- attr(*, "class")= chr [1:2] "glm" "lm"
r$res %>% 
  kbl(align="c") %>%
  kable_paper(full_width = F) %>%
  column_spec(1, bold = T, border_right = T) %>%
  column_spec(2:6, width = "10em", bold = T, background = "lightyellow")
sens spec pvp pvn lr.eta
1.00 0.00 NaN 0.66 -Inf
0.00180923540018721 1.00 0.01 0.00 0.66 0.00
0.00650816644953989 0.99 0.01 0.50 0.66 0.01
0.00684400771947475 0.99 0.01 0.33 0.66 0.01
0.00749525118105162 0.99 0.02 0.25 0.66 0.01
0.00881301894827189 0.99 0.03 0.20 0.66 0.01
0.00929351476654082 0.99 0.03 0.17 0.66 0.01
0.0104927668091737 0.99 0.04 0.14 0.66 0.01
0.0108381671642712 0.99 0.05 0.12 0.65 0.01
0.0118185749650296 0.99 0.05 0.11 0.65 0.01
0.0127838997600115 0.97 0.05 0.20 0.66 0.01
0.0136159222426618 0.97 0.06 0.18 0.65 0.01
0.0137958625234578 0.97 0.07 0.17 0.65 0.01
0.0146717806112001 0.97 0.07 0.15 0.65 0.01
0.0148027859185181 0.97 0.08 0.14 0.65 0.01
0.0158248023922306 0.97 0.08 0.13 0.65 0.02
0.0159999474734226 0.97 0.09 0.12 0.65 0.02
0.016475267148367 0.97 0.10 0.12 0.64 0.02
0.0169306854038613 0.97 0.10 0.11 0.64 0.02
0.0169709274877859 0.97 0.11 0.11 0.64 0.02
0.0202947467207027 0.97 0.12 0.10 0.64 0.02
0.0209693516990903 0.97 0.12 0.10 0.64 0.02
0.0219745841467059 0.97 0.13 0.09 0.64 0.02
0.0249765059225098 0.97 0.14 0.09 0.63 0.02
0.0249968164105568 0.97 0.14 0.08 0.63 0.02
0.0282478306720559 0.97 0.15 0.08 0.63 0.03
0.0294269068790082 0.97 0.16 0.08 0.63 0.03
0.0313873508048374 0.97 0.16 0.07 0.63 0.03
0.032013762556228 0.97 0.17 0.07 0.63 0.03
0.0339397809654967 0.97 0.18 0.07 0.62 0.03
0.035791692828981 0.97 0.18 0.07 0.62 0.04
0.0366076863830642 0.97 0.19 0.06 0.62 0.04
0.036821670349697 0.97 0.20 0.06 0.62 0.04
0.037427758374 0.97 0.20 0.06 0.62 0.04
0.0381277786729862 0.97 0.21 0.06 0.61 0.04
0.0384552506663857 0.97 0.22 0.06 0.61 0.04
0.0400569579915705 0.97 0.22 0.06 0.61 0.04
0.0406466072740928 0.97 0.23 0.05 0.61 0.04
0.0414604652070402 0.97 0.24 0.05 0.61 0.04
0.0421136226798211 0.97 0.24 0.05 0.60 0.04
0.0430657558812975 0.97 0.25 0.05 0.60 0.04
0.0447548649584199 0.97 0.25 0.05 0.60 0.04
0.0457624052665871 0.97 0.26 0.05 0.60 0.05
0.0461021232024433 0.97 0.27 0.05 0.60 0.05
0.0492581588013456 0.97 0.27 0.05 0.59 0.05
0.0493252083611513 0.97 0.28 0.04 0.59 0.05
0.0496644086289427 0.97 0.29 0.04 0.59 0.05
0.0508416914590252 0.97 0.29 0.04 0.59 0.05
0.0557342170068663 0.97 0.30 0.04 0.58 0.06
0.0561685986557161 0.97 0.31 0.04 0.58 0.06
0.0573963088150741 0.97 0.31 0.04 0.58 0.06
0.0613154957454218 0.97 0.32 0.04 0.58 0.06
0.0614768661510553 0.97 0.33 0.04 0.58 0.06
0.0615383956815027 0.97 0.33 0.04 0.57 0.06
0.0654558537638958 0.97 0.34 0.04 0.57 0.07
0.0659662432133166 0.97 0.35 0.04 0.57 0.07
0.0664414186213546 0.97 0.35 0.04 0.57 0.07
0.0676000765229336 0.97 0.36 0.04 0.56 0.07
0.0713436918472708 0.97 0.37 0.03 0.56 0.07
0.0726454331741131 0.96 0.37 0.05 0.56 0.07
0.0730150496885514 0.96 0.37 0.05 0.56 0.07
0.0733851736256203 0.96 0.38 0.05 0.56 0.07
0.0764915091955421 0.96 0.39 0.05 0.56 0.08
0.0775183408161831 0.96 0.39 0.05 0.55 0.08
0.0799116068462205 0.96 0.40 0.05 0.55 0.08
0.0801498721235562 0.96 0.41 0.05 0.55 0.08
0.0804237329273299 0.96 0.41 0.05 0.55 0.08
0.0815335664247634 0.96 0.42 0.04 0.54 0.08
0.0816373771973784 0.96 0.42 0.04 0.54 0.08
0.0823481249468765 0.95 0.42 0.06 0.54 0.08
0.0866549928540866 0.95 0.43 0.06 0.54 0.09
0.0920257666519061 0.95 0.44 0.06 0.54 0.09
0.0952565095015918 0.95 0.44 0.06 0.53 0.10
0.0976614306174561 0.95 0.45 0.05 0.53 0.10
0.100878766312365 0.95 0.46 0.05 0.53 0.10
0.103369125724852 0.95 0.46 0.05 0.53 0.10
0.107070714800921 0.95 0.47 0.05 0.52 0.11
0.11274828312249 0.95 0.48 0.05 0.52 0.11
0.116311854956577 0.95 0.48 0.05 0.52 0.12
0.116647140576534 0.95 0.49 0.05 0.51 0.12
0.119660808246112 0.95 0.50 0.05 0.51 0.12
0.119673067507587 0.95 0.50 0.05 0.51 0.12
0.120012550875125 0.95 0.51 0.05 0.50 0.12
0.123249540199875 0.95 0.52 0.05 0.50 0.12
0.130554528708354 0.95 0.52 0.05 0.50 0.13
0.136697814807612 0.95 0.53 0.05 0.49 0.14
0.138421705969981 0.95 0.54 0.05 0.49 0.14
0.139904051942405 0.95 0.54 0.05 0.49 0.14
0.143207819035217 0.95 0.55 0.05 0.48 0.14
0.143852339894194 0.95 0.56 0.04 0.48 0.14
0.152103065659306 0.95 0.56 0.04 0.48 0.15
0.154548553664476 0.95 0.57 0.04 0.47 0.15
0.15742553219506 0.95 0.58 0.04 0.47 0.16
0.157725972517338 0.95 0.58 0.04 0.46 0.16
0.158050273839369 0.95 0.59 0.04 0.46 0.16
0.162458073964357 0.94 0.59 0.05 0.46 0.16
0.163177377969434 0.94 0.59 0.05 0.46 0.16
0.169569933179213 0.94 0.60 0.05 0.46 0.17
0.173861549365739 0.94 0.61 0.05 0.45 0.17
0.178121047696505 0.94 0.61 0.05 0.45 0.18
0.183041225469305 0.94 0.62 0.05 0.44 0.18
0.18382132365225 0.92 0.62 0.06 0.45 0.18
0.196835498864963 0.91 0.62 0.07 0.45 0.20
0.198714637745399 0.90 0.62 0.08 0.45 0.20
0.208828514254312 0.90 0.63 0.08 0.45 0.21
0.209105970609838 0.90 0.63 0.08 0.44 0.21
0.209975909266725 0.88 0.63 0.08 0.45 0.21
0.213161533137419 0.88 0.64 0.08 0.44 0.21
0.216804970585111 0.87 0.64 0.09 0.45 0.22
0.222696052656071 0.86 0.64 0.10 0.45 0.22
0.228563642183144 0.86 0.65 0.10 0.45 0.23
0.232886680740389 0.85 0.65 0.11 0.45 0.23
0.235145419520664 0.83 0.65 0.12 0.45 0.24
0.243221373433597 0.83 0.65 0.12 0.45 0.24
0.246195193321677 0.83 0.66 0.11 0.44 0.25
0.249546399691354 0.83 0.67 0.11 0.44 0.25
0.257914956011292 0.83 0.67 0.11 0.43 0.26
0.259338638447516 0.83 0.68 0.11 0.43 0.26
0.259645073879839 0.83 0.69 0.11 0.42 0.26
0.26265430777496 0.83 0.69 0.11 0.42 0.26
0.266965635825223 0.83 0.70 0.11 0.41 0.27
0.26983142401873 0.82 0.70 0.12 0.42 0.27
0.270051396102581 0.81 0.70 0.12 0.42 0.27
0.276740960954445 0.81 0.71 0.12 0.42 0.28
0.27712664129974 0.81 0.71 0.12 0.41 0.28
0.278212259887938 0.81 0.72 0.12 0.41 0.28
0.292289161891145 0.81 0.73 0.12 0.40 0.29
0.293024782645167 0.81 0.73 0.12 0.39 0.29
0.293936333751449 0.81 0.74 0.12 0.39 0.29
0.301246821327224 0.81 0.75 0.12 0.38 0.30
0.302484811793591 0.81 0.75 0.12 0.38 0.30
0.311609055788525 0.81 0.76 0.11 0.37 0.31
0.313429369108531 0.81 0.76 0.11 0.36 0.31
0.314357875035742 0.81 0.77 0.11 0.36 0.31
0.315372942505162 0.79 0.77 0.12 0.36 0.32
0.323343216857761 0.78 0.77 0.13 0.36 0.32
0.32416426841477 0.78 0.78 0.12 0.36 0.32
0.329428596510664 0.78 0.78 0.12 0.35 0.33
0.334519712255658 0.78 0.79 0.12 0.34 0.33
0.337816298990499 0.78 0.80 0.12 0.34 0.34
0.338711748699052 0.78 0.80 0.12 0.33 0.34
0.339142792916543 0.77 0.80 0.13 0.33 0.34
0.350742286353438 0.77 0.81 0.13 0.33 0.35
0.3523770823763 0.76 0.81 0.13 0.33 0.35
0.354773776302139 0.74 0.81 0.14 0.33 0.35
0.364166463005734 0.73 0.81 0.14 0.34 0.36
0.369111056608969 0.73 0.82 0.14 0.33 0.37
0.371810430155246 0.73 0.82 0.14 0.32 0.37
0.374157783217994 0.73 0.83 0.14 0.31 0.37
0.386669077991901 0.72 0.83 0.15 0.32 0.39
0.388414026828456 0.72 0.84 0.15 0.31 0.39
0.393416681599673 0.72 0.84 0.15 0.30 0.39
0.402045161868046 0.71 0.84 0.15 0.30 0.40
0.412464127273819 0.71 0.85 0.15 0.29 0.41
0.424677639114954 0.69 0.85 0.16 0.30 0.42
0.426343610279491 0.69 0.86 0.15 0.29 0.43
0.439091685693522 0.68 0.86 0.16 0.29 0.44
0.444198033416043 0.68 0.86 0.16 0.28 0.44
0.446989140647992 0.68 0.87 0.16 0.27 0.45
0.463021830636321 0.67 0.87 0.16 0.28 0.46
0.482817669708468 0.67 0.88 0.16 0.27 0.48
0.482844117433361 0.67 0.88 0.16 0.26 0.48
0.489013201348026 0.65 0.88 0.17 0.26 0.49
0.489991495176471 0.65 0.89 0.17 0.25 0.49
0.492758558473866 0.65 0.90 0.16 0.24 0.49
0.506040728838035 0.65 0.90 0.16 0.23 0.51
0.513550385417675 0.65 0.91 0.16 0.22 0.51
0.521004988214601 0.65 0.92 0.16 0.20 0.52
0.527328766479994 0.65 0.92 0.16 0.19 0.53
0.52997630891268 0.65 0.93 0.16 0.18 0.53
0.531180617770809 0.64 0.93 0.16 0.18 0.53
0.533424672552217 0.64 0.93 0.16 0.17 0.53
0.536666148284431 0.63 0.93 0.17 0.17 0.54
0.556190761437211 0.63 0.94 0.17 0.16 0.56
0.556394402336068 0.63 0.95 0.17 0.14 0.56
0.565516373492898 0.63 0.95 0.17 0.12 0.57
0.567985282919952 0.62 0.95 0.17 0.13 0.57
0.581122752937296 0.60 0.95 0.18 0.13 0.58
0.588240045851091 0.59 0.95 0.18 0.13 0.59
0.594464459946028 0.58 0.95 0.18 0.13 0.59
0.600662195766474 0.56 0.95 0.19 0.14 0.60
0.607553322951948 0.55 0.95 0.19 0.14 0.61
0.628338752838181 0.54 0.95 0.20 0.14 0.63
0.628646001434133 0.53 0.95 0.20 0.15 0.63
0.630907957244742 0.53 0.96 0.20 0.13 0.63
0.645243944961033 0.53 0.97 0.20 0.11 0.65
0.645373908720707 0.51 0.97 0.20 0.11 0.65
0.659294896517621 0.50 0.97 0.21 0.11 0.66
0.666549439290904 0.49 0.97 0.21 0.12 0.67
0.677881713638525 0.49 0.97 0.21 0.10 0.68
0.697749440023825 0.47 0.97 0.22 0.10 0.70
0.70208184669813 0.46 0.97 0.22 0.10 0.70
0.720190671523206 0.46 0.98 0.22 0.08 0.72
0.72056912646897 0.46 0.99 0.22 0.05 0.72
0.725647171883447 0.45 0.99 0.22 0.05 0.73
0.72715262875541 0.44 0.99 0.23 0.06 0.73
0.734922007572902 0.42 0.99 0.23 0.06 0.73
0.741605341011426 0.41 0.99 0.23 0.06 0.74
0.741963435044584 0.40 0.99 0.24 0.06 0.74
0.746467368954167 0.38 0.99 0.24 0.06 0.75
0.746857081300053 0.37 0.99 0.24 0.06 0.75
0.750354139525615 0.36 0.99 0.25 0.07 0.75
0.775632030578303 0.35 0.99 0.25 0.07 0.78
0.790405445895688 0.33 0.99 0.26 0.07 0.79
0.810555061686102 0.33 0.99 0.25 0.04 0.81
0.812992771850174 0.33 1.00 0.25 0.00 0.81
0.821277803100177 0.32 1.00 0.26 0.00 0.82
0.829191152063883 0.31 1.00 0.26 0.00 0.83
0.841628155266684 0.29 1.00 0.26 0.00 0.84
0.843139186780683 0.28 1.00 0.27 0.00 0.84
0.846038967893667 0.27 1.00 0.27 0.00 0.85
0.859187690421014 0.26 1.00 0.27 0.00 0.86
0.886987860322093 0.24 1.00 0.28 0.00 0.89
0.890207023356535 0.23 1.00 0.28 0.00 0.89
0.910322575115174 0.22 1.00 0.29 0.00 0.91
0.910438972910899 0.21 1.00 0.29 0.00 0.91
0.915168953300368 0.19 1.00 0.29 0.00 0.92
0.92006741804628 0.18 1.00 0.29 0.00 0.92
0.920414531579763 0.17 1.00 0.30 0.00 0.92
0.921687985232535 0.15 1.00 0.30 0.00 0.92
0.92710671822085 0.14 1.00 0.30 0.00 0.93
0.935671204049939 0.13 1.00 0.31 0.00 0.94
0.949218114072397 0.12 1.00 0.31 0.00 0.95
0.956591316857737 0.10 1.00 0.31 0.00 0.96
0.957088332172975 0.09 1.00 0.32 0.00 0.96
0.959239734386155 0.08 1.00 0.32 0.00 0.96
0.962415000835651 0.06 1.00 0.32 0.00 0.96
0.965461490606768 0.05 1.00 0.33 0.00 0.97
0.968259862051368 0.04 1.00 0.33 0.00 0.97
0.973214730603841 0.03 1.00 0.33 0.00 0.97
0.981426643739946 0.01 1.00 0.33 0.00 0.98
0.999372365812042 0.00 1.00 0.34 NaN 1.00



ROC함수는 세개의 리스트를 반환하는데 첫번째 res는 데이타프레임으로 각각의 lr.eta값에 대해 민감도, 특이도, PVP, PVN값을 제시합니다.


  1. 설치가 안된 패키지는 install.packages("")로 설치해야 합니다.↩︎

  2. AIC = -2log(likelihood) + 2p, p: 변수의 갯수, n: 데이터 갯수. 변수가 많은 모델은(p가 큰) 우도(likelihood)는 커집니다. AIC를 최소화 한다는 뜻은 우도(likelihood)를 가장 크게 하는 동시에 변수 갯수는 가장 적은 최적의 모델(parsimonious & explainable)을 의미합니다.↩︎

  3. AUC (Area Under the Curve)는 모델 정확도 판단 지표로 ROC 곡선 밑의 넓이입니다. AUC의 가준: .0.90-1 = excellent, 0.80-0.90 = good, 0.70-0.80 = fair, 0.60-0.70 = poor, 0.50-0.60 = fail↩︎