종강도 했으니 다시 이번학기 배운 내용들을 정리하면서 꾸준히 블로그에 기록해놓을 생각
로지스틱 회귀모형 (logistic regression model)
위 처럼 타겟변수 y가 이항변수인 경우 이를 예측하기 위한 회귀모형은 선형회귀식과는 조금 다르다.
이와같은 타겟변수를 선형회귀식에 적합시키려하면 다음과 같은 형태가 될텐데
이 방법은 모형이 출력하는 예측값이 실수값이기 때문에 그대로 적용하는 것이 곤란해진다. 예를들어 0.35나 -1.5와 같은 값이 y의 예측값으로 도출되었을 경우 이 값을 이항변수 y에서 0이나 1로 분류하는 기준이 필요할 것이다.
우선 반응변수 y가 이항변수인 경우 조건부 평균을 따져보면
학습해야 하는 회귀함수가 조건부 "확률"값을 도출해줘야 한다. 함수값이 0과1 사이의 범위로 제한되기 때문에 선형식 대신 다른 함수모형을 가정하는데 그게 바로 시그모이드 함수를 합성한 형태의 확장모형이다.
그럼 왜 시그모이드 함수를 사용할까? 시그모이드 함수는 다음 그림처럼 생겼다.
sigmoid function : 실수 전체 영역에서 증가, 0과 1사이의 값을 가짐
시그모이드가 합성되어있는 확장모형을 통해 0과1사이의 예측값이 도출되면 이 값이 주어진 x값에 대응되는 y값이 1일 가능성에 대한 점수를 원래의 선형모형 f를 사용해 구한 뒤 시그모이드 함수를 이용해 0과 1사이의 숫자로 정규화 하는 과정을 거치는 것이다.
logit function은 sigmoid의 역함수로 시그모이드가 포함된 확장모형을 로짓함수를 통해 다음과 같이 선형모형의 형태로 나타낼 수 있다.
이때 계산과정에서 등장하는
이부분을 오즈비(odds ratio)라고 한다. 즉, 로지스틱 회귀모형은 오즈비의 로그값에 대한 선형모형으로 이해할 수 있다.
회귀계수 β또한 오즈비를 기준으로 해석이 가능하다. 예를들어 세번째 예측변수 x3에 대한 회귀계수 β3값이 1.2라면, 다른 예측변수 값이 동일한 수준으로 통제된 상태에서 x3가 한단위 증가하면 로그 오즈비가 1.2만큼 증가함을 의미하고 이에 따라 오즈비는 e^1.2=3.32배가 된다. 이항분류이기 때문에 오즈비를 y가 1이되는 경향성에 대한 score로 사용한다면 x3가 한단위 증가함에 따라 y=1이 되는 경향성이 3.32배로 증가한다고 해석할 수 있다.
회귀모형을 통해 y값을 예측하는 것은 cut-off값을 적용해 분류하는 방식을 사용한다. cut-off가 0.5라면 모형에 의해 예측된 확률이 0.5이상이라면 1로, 그 밑이라면 0으로 예측한다.
# 모형 학습
손실함수 L(β) :
분류 문제이기 때문에 손실함수는 학습용 데이터의 이항 반응변수y를 one-hot-encoding한 것의 cross-entropy를 사용한다.
학습의 목표는 손실함수 L(β)을 최소로하는 β값을 찾는 것. 여기서 학습데이터에 대해 구한 cross-entropy의 평균 또는 합으로 정의되는 손실함수를 최소로 하는 β값을 찾는 것은 log-likelihood function ℓ(β)을 최대로 하는 MLE와 같다.
gradient descent를 통한 β값 학습 :
β ← β−η∇L(β) => β값을 지속적으로 업데이트 해나가는 반복 알고리즘
1. 초기화 난수로 β의 초기치를 정한다.
2. 알고리즘에 따라 β값을 업데이트 한다.
3. 반복 수렴할 때 까지 2단계를 반복.
# 로지스틱 회귀모형을 이용한 클래스 예측 (분류)
adult예제 데이터로 logistic classification을 구현해보자. 우선 타겟변수는 wage로 50K넘는 임금을 받는 사람을 1, 그 미만을 0 이라고 분류하는 모형을 학습시키고자 한다. 독립변수들은 age, workclass, education, occupation등등.
adult <- read.csv(file = "./dat/adult.csv", stringsAsFactors = TRUE)
summary(adult)
학습전에 train-test-split 7:3비율로 해주고
set.seed(0)
print(N <- nrow(adult))
print(N.tr <- round(0.7*N))
tr <- sort(sample(1:N, N.tr, replace = FALSE))
adult.tr <- adult[tr,]
adult.te <- adult[-tr,]
학습에는 glm함수를 사용한다. 다음과 같이 모형을 설정하고 학습시키기.
glm.fit <- glm(wage ~ age + workclass + education
+ occupation + race + sex
+ capital_gain + hours_per_week,
family = "binomial",
data = adult.tr)
이제 train data로 학습시킨 모형의 test data에 대한 예측성능을 확인한다.
예측 결과 평가는 confusion matrix와 roc plot에 기반한 예측 성능 측정 코드를 따로 다음과 같이 따로 구현,
HarmonicMean <- function(a, b) 2*a*b/(a + b)
AccuracyMeasures <- function(pred, actual, cutoff = 0.5) {
ctable <- table(Actual = actual,
Predicted = 1*(pred >= cutoff))
cat("Confusion matrix: \n")
print(ctable)
cat("\n")
accuracy <- round(sum(diag(ctable))/sum(ctable), 4)
specificity <- round(ctable[1, 1]/sum(ctable[1,]), 4)
precision <- round(ctable[2, 2]/sum(ctable[,2]), 4)
recall <- round(ctable[2, 2]/sum(ctable[2,]), 4)
f1 <- round(HarmonicMean(precision, recall), 4)
data.frame(Accuracy = accuracy,
Specificity = specificity,
Sensitivity = recall,
Precision = precision,
Recall = recall,
F1 = f1)
}
ROC.plot <- function(Pred, Actual)
# Pred: predicted class probability
# Actual: indicator for actual class
{
require(ROCR)
Prediction <- prediction(Pred, Actual)
Perf <- performance(Prediction,
measure = "tpr", x.measure = "fpr")
plot(Perf, main = "ROC curve", cex.axis = 0.7)
abline(0, 1, lty = 2)
auc <- performance(Prediction, "auc")@y.values[[1]]
text(0.7, 0.5, paste("AUC = ", round(auc, 4)))
return(list(AUC = auc))
}
우선 confusion matrix를 통해 accuracy, precision,recall,specificity등을 계산.
Predicted.glm <- predict(glm.fit, newdata = adult.te, type = "response")
cutoff <- 0.5
Actual <- 1*(adult.te$wage == " >50K")
AccuracyMeasures(pred = Predicted.glm, actual = Actual)
기본적으로 설정된 cut-off -value는 0.5이므로 이 값을 바꿔가며 어떤게 더 좋은 성능을 내는지 확인하기
cutoffs <- seq(from = 0.3, to = 0.7, by = 0.1)
for (cutoff in cutoffs) {
cat("[Cutoff = ", cutoff, "]\n\n", sep = "")
print(AccuracyMeasures(pred = Predicted.glm, actual = Actual, cutoff = cutoff))
cat("----------------------------------------------------------\n\n")
}
## [Cutoff = 0.3]
##
## Confusion matrix:
## Predicted
## Actual 0 1
## 0 6190 1144
## 1 784 1650
##
## Accuracy Specificity Sensitivity Precision Recall F1
## 1 0.8026 0.844 0.6779 0.5906 0.6779 0.6312
## ----------------------------------------------------------
##
## [Cutoff = 0.4]
##
## Confusion matrix:
## Predicted
## Actual 0 1
## 0 6684 650
## 1 1084 1350
##
## Accuracy Specificity Sensitivity Precision Recall F1
## 1 0.8225 0.9114 0.5546 0.675 0.5546 0.6089
## ----------------------------------------------------------
##
## [Cutoff = 0.5]
##
## Confusion matrix:
## Predicted
## Actual 0 1
## 0 6951 383
## 1 1317 1117
##
## Accuracy Specificity Sensitivity Precision Recall F1
## 1 0.826 0.9478 0.4589 0.7447 0.4589 0.5679
## ----------------------------------------------------------
##
## [Cutoff = 0.6]
##
## Confusion matrix:
## Predicted
## Actual 0 1
## 0 7134 200
## 1 1572 862
##
## Accuracy Specificity Sensitivity Precision Recall F1
## 1 0.8186 0.9727 0.3541 0.8117 0.3541 0.4931
## ----------------------------------------------------------
##
## [Cutoff = 0.7]
##
## Confusion matrix:
## Predicted
## Actual 0 1
## 0 7231 103
## 1 1802 632
##
## Accuracy Specificity Sensitivity Precision Recall F1
## 1 0.805 0.986 0.2597 0.8599 0.2597 0.3989
## ----------------------------------------------------------
다음은 ROC curve를 통해 모형의 예측능력을 평가
auc <- ROC.plot(Predicted.glm, Actual)
AUC값이 높을수록, 커브가 왼쪽 상단에 둥글게 딱 붙어있을 수록 좋은 예측 성능모형.