[Python]로지스틱회귀분석 실습

2020. 6. 20. 18:57ML in Python/Python

실습에 사용될 데이터 : 개인대출 데이터

Personal Loan.csv
0.10MB

-----target 

Personal Loan  ( 0 or 1 의 값을 갖는 변수이다. )

-----feature  

Experience 경력
Income 수입
Famliy 가족단위
CCAvg 월 카드사용량 
Education 교육수준 (1: undergrad; 2, Graduate; 3; Advance )
Mortgage 가계대출
Securities account 유가증권계좌유무
CD account 양도예금증서 계좌 유무
Online 온라인계좌유무
CreidtCard 신용카드유무 

 여태 단순/다중회귀분석과 다중공선성을 해결하기 위한 방법을 Python코드로 알아보았다. 

이제 sigmoid function을 이용한 분류/예측을 하는 로지스틱 회귀분석을 실습하려고 한다. 

로지스틱 회귀분석에 대한 상세한 정의와 원리를 알고 싶다면, 내가 봤을 때 상세하게 보았던 블로그의 링크를 남겨놓겠다

https://nittaku.tistory.com/478

 

5-6. 로지스틱 회귀분석(Logistic Regression)

로지스틱 회귀분석 지금까지 학습한 선형 회귀분석 단순/다중은 모두 종속변수Y가 연속형 이었다. 로지스틱회귀분석 은 종속변수가 범주형이면서 0 or 1 인 경우 사용하는 회귀분석이다. 로지스�

nittaku.tistory.com

 

< 간단한 설명 >

 간단하게 로지스틱모델을 요약하자면 sigmoid function을 사용하는 분류/예측 모델이다. 보통 임계값(cut-off)를 설정하여 0 or 1(이진형)로 값을 변환시킨다. 이는 말로 풀어설명하자면 발생할 확률/발생하지 않을 확률을 구하는 것이다. 이를 사용하여 나타낸 지표 중 하나가 승산비(Odds - 발생할 확률/발생하지 않을 확률)이다. 

 여기서는 Python을 통한 로지스틱회귀분석의 실습을 위해, 

1. 데이터를 로드/간단한 전처리

2. 로지스틱 회귀모델을 사용하여 예측

3. ROC Curve를 통해 모델의 성능확인

을 하는 과정을 진행할 것이다.

 

로지스틱 회귀분석

# 필요한 Library
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score, roc_auc_score, roc_curve
import statsmodels.api as sm
import matplotlib.pyplot as plt
import time 

# Personal Loan 데이터 불러오기

ploan = pd.read_csv("./Personal Loan.csv")

# 사용하지 않을 변수 제거 ID, zip code 

ploan_processed = ploan.dropna().drop["ID","ZIP code"], axis=1, inplace = False)

# 회귀모델에서 b0를 위한 상수항 추가

ploan_processed = sm.add_constant(ploan_processed,has_constant = "add")
ploan_processed.head()

ploan_processed.head()

설명변수 X와 타겟변수 Y/학습과 평가 데이터를 분리 

# 대출여부는 1 or 0으로 결정된다. 즉 target이 1/0의 값을 갖기에
# 로지스틱 회귀모형이 적합하다.

feature_columns = ploan_processed.columns.difference(["Personal Loan"])
X = ploan_processed[feature_columns]
y = ploan_processed["Personal Loan"]

train_x, test_X ,train_y, test_y = train_test_split(X, y, stratify=y,train_size=0.7,test_size=0.3,random_state=1)
print(train_x.shape, test_x.shape, train_y.shape, test_y.shape)

로지스틱 회귀모형 모델링 y = F(x)

# 로지스틱 모형 적합

model = sm.Logit(train_y, train_x)
results = model.fit(method = "newton")    # 다변수함수에 뉴턴방법을 적용한 로지스틱 회귀모형

모델적합이 완료되었다는 결과

results.summary()

로지스틱 회귀모델 summary, 제목에 logit regression이라고 명시된다.

results.params

 

results.params

 모델적합으로 인해 위의 회귀계수가 출력되었다. 이는 아직 로지스틱의 log형태가 취해진 결과이기에 바로 확률로 해석하는 오류를 범해서는 안된다. 그렇기에 np.exp(results.params)의 결과를 확인할 필요가 있다.

np.exp(results.params)

np.exp(results.params)

- 나이가 한 살 많을수록 대출할 확률이 1.024배 높다.

- 수입이 1단위 높을수록 대출할 확률이  1.05배 높다. 

- 가족 구성원수가 1명 많을수록 대출할 확률이 2.13배 높다. 

이와 같은 방법을 통해서 직관적인 해석을 진행할 수 있다. 다음 y_hat을 예측해보자.

pred_y = results.predict(test_x)
pred_y

pred_y 결과

 위의 결과는 0~1사이의 logit을 나타낸 결과이다. Target 데이터는 0 또는 1의 이진형 변수인데 예측값은 다르게 나왔다. 이는 1이될 확률을 나타내는 결과이다. 그렇기에 우리는 이 logit에 임계값을 설정하여 임계값 이상은 =1 / 임계값 이하는 0으로 분류해줄 필요가 있다.

# 임계값 함수

def cut_off(y, threshold) :
    Y = y.copy()  # 대문자 Y를 새로운 변수로 하여 기존의 y값에 영향이 가지 않도록 한다.
    Y[Y>threshold] = 1
    Y[Y<threshold] = 0
    return Y.astype(int)
    
pred_Y = cut_off(pred_y, 0.5)
pred_Y

임계값설정을 통해 logit을 변환한 결과

 위의 코드는 임계값을 0.5로 설정했다. 불량품을 선별하고 유통되는 것을 줄이고자 한다면 임계값을 더 높게 설정할 수 있다. 보통은 0.5로 진행하지만, 상황과 용도에 따라 다르다. 

 그리고 결과를 보면 0 또는 1의 이진형 변수로 분류된 것을 볼 수 있다. "1"의 경우 대출을 한다고 예측한 것이고 "0"의 경우 대출을 하지 않는다고 예측한 것이다.

 이제 이 예측의 정확성을 확인하기 위한 Confusion Matrix를 만들고 ROC curve를 확인해보자. 정확도 및 ROC curve의 정의는 지난 게시물의 링크를 공유하겠다.

https://todayisbetterthanyesterday.tistory.com/5

 

헷갈리는 통계기본 - 정확도/정밀도/재현율/특이도/G-mean/F1 measure/ROC curve/AUC

정확도, 정밀도, 재현율, 특이도는 모두 머신러닝 및 분류 모형의 성능지표로 사용된다. 이 네 가지 단어의 정의는 아래와 같다. 정확도(Accuracy) - 전체 데이터 중에서 모형으로 판단한 값이 실제

todayisbetterthanyesterday.tistory.com

# confusion matrix (분류 표를 나타낸 행렬)

cfmat = confusion matrix(test_y,pred_Y)
print(cfmat)

분류 표-행렬

# confusion matrix accuracy(정확도) 계산함수

def acc(cfmat):
	return (cfmat[0,0] + cf[1,1])/(cfmat[0,0] + cfmat[1,1] + cfmat[0,1] + cfmat[1,0])
acc(cfmat)

정확도

 confusion matrix를 활용한 정확도는 예측한 것들 중에 옳게 분류한 것들의 비율을 나타낸다. 

즉, ( 예측-T,실제-T + 예측-F,실제-F / 전체 예측데이터 수 ) 이다.

# 임계값 0~1에 따른 정확도 확인

threshold = np.arange(0,1,0.1)
table = pd.DataFrame(columns = ['ACC'])
for i in threshold :
	pred_Y = cut_off(pred_y,i)
	cfmat = confusion_matrix(test_y,pred_Y)
	table.loc[i] = acc(cfmat)
table.index.name = "threshold"
table.columns.name = "performance"
table

임계값에 따른 정확도

# sklearn에서 ROC 패키지 활용
fpr, tpr, thresholds = metrics.roc_curve(test_y,pred_y,pos_label = 1)

# ROC curve
plt.plot(fpr,tpr)

# AUC
auc = np.trapz(tpr,fpr)
print("AUC:",auc)

AUC와 ROC curve

 이렇게하여 AUC와 ROC curve도 나타냈다. AUC와 ROC curve에 대한 설명도 위의 정확도를 설명하는 링크에 같이 존재한다. AUC는 1에 가까울수록 모델의 성능이 좋은 것이며, ROC curve는 (0,1)로 그래프가 가까이 갈 수록 정확도가 좋은 것이다. 

 이렇게 오늘은 로지스틱 회귀모델을 학습하고 예측하는 모형을 만들었다. 범주형변수(이진형 변수)에 사용하기 좋은 모델로 회귀분석과 머신러닝의 기본이며, 나중에 나올 신경망 학습에 사용되는 sigmoid가 로지스틱 회귀모델에 사용되는 logit함수와 같은 함수이다. 그렇기에 잘 알아두면 좋을 것이다.