통계기반 데이터분석

[ R ] 로지스틱 회귀분석

yul_S2 2022. 11. 28. 08:46
반응형

 로지스틱 회귀분석 

종속변수와 독립변수 간의 관계를 나타내어 예측 모델을 생성한다는 점에서 선형 회귀분석 방법과 유사

 

로지스틱 회귀분석의 특징 

분석 목적: 종속변수와 독립변수 간의 관계를 통해서 예측 모델 생성 

회귀분석과 차이점: 종속변수는 반드시 범주형 변수(예, Yes/No, iris데이터의 species) 

정규성: 정규분포 대신에 이항분포를 따른다. 

로짓 변환: 종속변수의 출력범위를 0과 1로 조정하는 과정 (예, 혈액형 A → [1, 0, 0, 0]

활용분야: 의료, 통신, 날씨 등 다양한 분야

 

ex) 날씨 관련 요인 변수로 비(rain) 유무 예측

weather.csv
0.02MB

 

install.packages("ROCR")
library(car)
library(lmtest)
library(ROCR)

 

#1 데이터 가져오기

weather = read.csv("C:/weather.csv", stringsAsFactors = F)

dim(weather)
# 366  15

head(weather)
#             Date      MinTemp  MaxTemp   Rainfall   Sunshine  WindGustDir    WindGustSpeed
# 1 2014-11-01     8.0           24.3            0.0         6.3             NW                  30
# 2 2014-11-02    14.0          26.9            3.6         9.7             ENE                 39
# 3 2014-11-03    13.7          23.4            3.6         3.3             NW                  85
# 4 2014-11-04    13.3          15.5           39.8         9.1            NW                  54
# 5 2014-11-05     7.6          16.1            2.8         10.6            SSE                 50
# 6 2014-11-06     6.2          16.9            0.0         8.2              SE                   44
#         WindDir   WindSpeed Humidity   Pressure   Cloud   Temp     RainToday   RainTomorrow
# 1      NW          20                29            1015.0              7   23.6              No              Yes
# 2      W            17                36            1008.4              3    25.7             Yes             Yes
# 3      NNE         6                69             1007.2              7    20.2             Yes             Yes
# 4      W            24                56            1007.0              7    14.1             Yes             Yes
# 5      ESE        28                49            1018.5              7    15.4             Yes              No
# 6      E             24                57            1021.7              5    14.8              No              No

str(weather)
# 'data.frame': 366 obs. of  15 variables:
# $ Date         : chr  "2014-11-01" "2014-11-02" "2014-11-03" "2014-11-04" ...
# $ MinTemp      : num  8 14 13.7 13.3 7.6 6.2 6.1 8.3 8.8 8.4 ...
# $ MaxTemp      : num  24.3 26.9 23.4 15.5 16.1 16.9 18.2 17 19.5 22.8 ...
# $ Rainfall     : num  0 3.6 3.6 39.8 2.8 0 0.2 0 0 16.2 ...
# $ Sunshine     : num  6.3 9.7 3.3 9.1 10.6 8.2 8.4 4.6 4.1 7.7 ...
# $ WindGustDir  : chr  "NW" "ENE" "NW" "NW" ...
# $ WindGustSpeed: int  30 39 85 54 50 44 43 41 48 31 ...
# $ WindDir      : chr  "NW" "W" "NNE" "W" ...
# $ WindSpeed    : int  20 17 6 24 28 24 26 24 17 6 ...
# $ Humidity     : int  29 36 69 56 49 57 47 57 48 32 ...
# $ Pressure     : num  1015 1008 1007 1007 1018 ...
# $ Cloud        : int  7 3 7 7 7 5 6 7 7 1 ...
# $ Temp         : num  23.6 25.7 20.2 14.1 15.4 14.8 17.3 15.5 18.9 21.7 ...
# $ RainToday    : chr  "No" "Yes" "Yes" "Yes" ...
# $ RainTomorrow : chr  "Yes" "Yes" "Yes" "Yes" ...

stringsAsFactors = F

 

 

 

#2 변수 선택과 더미 변수 생성

weather_df <- weather[ , c(-1, -6, -8, -14)]
str(weather_df)
# 'data.frame': 366 obs. of  11 variables:
# $ MinTemp      : num  8 14 13.7 13.3 7.6 6.2 6.1 8.3 8.8 8.4 ...
# $ MaxTemp      : num  24.3 26.9 23.4 15.5 16.1 16.9 18.2 17 19.5 22.8 ...
# $ Rainfall     : num  0 3.6 3.6 39.8 2.8 0 0.2 0 0 16.2 ...
# $ Sunshine     : num  6.3 9.7 3.3 9.1 10.6 8.2 8.4 4.6 4.1 7.7 ...
# $ WindGustSpeed: int  30 39 85 54 50 44 43 41 48 31 ...
# $ WindSpeed    : int  20 17 6 24 28 24 26 24 17 6 ...
# $ Humidity     : int  29 36 69 56 49 57 47 57 48 32 ...
# $ Pressure     : num  1015 1008 1007 1007 1018 ...
# $ Cloud        : int  7 3 7 7 7 5 6 7 7 1 ...
# $ Temp         : num  23.6 25.7 20.2 14.1 15.4 14.8 17.3 15.5 18.9 21.7 ...
# $ RainTomorrow : chr  "Yes" "Yes" "Yes" "Yes" ...


예측 이므로 RainToday 데이터는 필요가 없어 제거 후 새로운 데이터 프레임 생성

 

weather_df$RainTomorrow[weather_df$RainTomorrow == 'Yes'] <- 1
weather_df$RainTomorrow[weather_df$RainTomorrow == 'No'] <- 0
weather_df$RainTomorrow <- as.numeric(weather_df$RainTomorrow)

X, Y변수 설정

Y변수를 대상으로 더미 변수를 생성하여 로지스틱 회귀분석 환경 설정

 

 

 

#3 학습데이터와 검정데이터 생성(7:3비율)

idx <- sample(1:nrow(weather_df ), nrow(weather_df) * 0.7)
train <- weather_df[idx, ]
test <- weather_df[-idx, ]

학습데이터 : 70%   =>  회귀모델 생성할때 쓰일 데이터

검증데이터 : 30%

 

 

#4 로지스틱 회귀모델 생성

weather_model <- glm(RainTomorrow ~ ., data = train, family = 'binomial', na.action=na.omit)

weather_model
# Call:  glm(formula = RainTomorrow ~ ., family = "binomial", data = train, 
#            na.action = na.omit)

# Coefficients:
#   (Intercept)        MinTemp        MaxTemp       Rainfall       Sunshine  WindGustSpeed  
# 161.36505       -0.21320        0.04284       -0.12185       -0.26896        0.07539  
# WindSpeed       Humidity       Pressure          Cloud           Temp  
# -0.05259        0.09996       -0.17059        0.15810        0.27543  

# Degrees of Freedom: 250 Total (i.e. Null);  240 Residual
# (5 observations deleted due to missingness)
# Null Deviance:     229.9 
# Residual Deviance: 130  AIC: 152


summary(weather_model)

# Call:
#   glm(formula = RainTomorrow ~ ., family = "binomial", data = train, 
#       na.action = na.omit)

# Deviance Residuals: 
#   Min       1Q   Median       3Q      Max  
# -2.1271  -0.4254  -0.2166  -0.0849   2.5727  

# Coefficients:
#                                Estimate   Std. Error  z value  Pr(>|z|)    
# (Intercept)            161.36505   50.42530   3.200 0.001374 ** 
#   MinTemp             -0.21320    0.09222  -2.312 0.020792 *  
#   MaxTemp             0.04284    0.25604   0.167 0.867107    
#   Rainfall                -0.12185    0.06260  -1.947 0.051583 .  
#   Sunshine            -0.26896    0.11986  -2.244 0.024832 *  
#   WindGustSpeed   0.07539    0.02904   2.596 0.009444 ** 
#   WindSpeed         -0.05259    0.04025  -1.306 0.191414    
#   Humidity              0.09996    0.03364   2.971 0.002968 ** 
#   Pressure             -0.17059    0.04927  -3.463 0.000535 ***
#   Cloud                   0.15810    0.12740   1.241 0.214626    
#   Temp                   0.27543    0.27743   0.993 0.320802    
# ---
#   Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

# (Dispersion parameter for binomial family taken to be 1)

# Null deviance: 229.90  on 250  degrees of freedom
# Residual deviance: 130.05  on 240  degrees of freedom
# (5 observations deleted due to missingness)
# AIC: 152.05

# Number of Fisher Scoring iterations: 6

glm()함수 : glm(y~x, data, family)

family = ‘binomial’ 속성: y변수가 이항형

 

 

#5 로지스틱 회귀모델 예측치 생성

pred <- predict(weather_model, newdata = test, type = "response")
pred

result_pred <- ifelse(pred >= 0.5, 1, 0)
result_pred

table(result_pred)
# result_pred
#   0  1 
# 88 22

type=”response”속성: 에측 결과를 0-1사이의 확률값으로 예측치를 얻기 위해서 지정

모델 평가를 위해서 예측치가 확률값으로 제공되기 때문에 이를 이항형으로 변환하는 과정이 필요

Ifelse()함수를 이용하여 예측치의 벡터변수(pred)를 입력으로 이항형의 벡터 변수(result_pred)를 생성

 

 

#6 모델평가 – 분류정확도 계산

table(result_pred, test$RainTomorrow)
# result_pred  0  1
#                0 80  8
#                1  8 14

 

 

#7 ROC(Receiver Operating Characteristic) Curve를 이용한 모델 평가

pr <- prediction(pred, test$RainTomorrow)
prf <- performance(pr, measure = "tpr", x.maeasure = "fpr")
plot(prf )

ROC curve에서 왼쪽 상단의 계단 모양의 빈 공백만큼이 분류정확도에서 오분류(missing)를 나타낸다.

반응형