비즈니스 데이터를 활용한 로지스틱 회귀 분석 (Logistic Regression)
로지스틱 회귀 분석은 분류 문제에서 널리 활용되는 통계적 기법으로, 특히 비즈니스 데이터에서 고객 행동을 예측하거나 중요 결과를 분류하는 데 많이 사용됩니다. 이번 포스팅에서는 중급 수준의 학습자를 대상으로 로지스틱 회귀의 개념부터 Python 실습 코드까지 단계별로 설명합니다. 이진 분류와 다중 분류 개념, 시그모이드 함수와 오즈비 개념을 다루고, 비즈니스 사례로 고객 이탈 예측과 마케팅 캠페인 반응 예측을 살펴봅니다. 또한 Kaggle의 실제 데이터셋을 활용한 실습을 통해 모델 학습과 성능 평가 방법을 익히고, 모델 개선을 위한 기법들과 로지스틱 회귀의 한계점까지 함께 알아보겠습니다.
1. 로지스틱 회귀 분석 개념
이진 분류(Binary Classification)와 다중 분류(Multinomial Classification)
로지스틱 회귀는 기본적으로 이진 분류에 활용됩니다. 예를 들어 고객이 이탈할지 여부(Yes/No), 이메일이 스팸인지 아닌지와 같이 두 가지 범주 중 하나를 예측합니다. 로지스틱 회귀 모델은 이러한 둘 중 하나의 결과를 확률 형태로 예측하며, 일반적으로 0.5를 기준으로 두 클래스로 분류합니다. 로지스틱 회귀를 여러 범주의 분류 문제로 확장한 것이 **다중 분류 (Multinomial Logistic Regression)**입니다. 이 경우 결과가 셋 이상의 카테고리를 가질 수 있으며, 이를 위해 소프트맥스(Softmax) 함수를 사용하거나 이진 로지스틱 회귀 분류기를 일대다(One-vs-Rest) 방식으로 여러 개 구성합니다. 다중 로지스틱 회귀는 여러 범주를 가지는 범주형 종속변수의 각 클래스에 속할 확률을 예측하는 모델로 일반화될 수 있습니다 (Multinomial logistic regression - Wikipedia ). 즉, 각 클래스에 대한 **로그 오즈(log-odds)**를 추정하여 가장 가능성 높은 클래스를 선택합니다.
로지스틱 함수와 시그모이드(Sigmoid) 함수
로지스틱 회귀의 핵심은 **로지스틱 함수(logistic function)**를 사용해 확률값을 산출한다는 점입니다. 로지스틱 함수는 시그모이드 함수의 한 종류로 S자 형태의 곡선을 가지며, 어떤 실수 입력값에 대해서도 0과 1 사이의 값을 출력합니다 (Logistic regression - Wikipedia ). 함수 식은 아래와 같습니다:
여기서 t=β0+β1x1+β2x2+⋯+βnxnt = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \dots + \beta_n x_n 는 선형 결합으로, 입력 특성들의 가중합입니다. 시그모이드 함수를 이 선형 결합에 적용하면 결과를 0~1 범위의 확률로 변환해줍니다. 예를 들어 σ(t)=0.8\sigma(t) = 0.8이라면 해당 분류 대상이 **양성 클래스(예: churn=Yes)**일 확률이 80%라는 뜻입니다. 시그모이드 출력이 0.5보다 크면 양성(1), 작으면 음성(0)으로 분류하는 것이 일반적입니다. 이러한 방식으로 로지스틱 회귀는 선형 회귀로는 직접 다룰 수 없는 분류 문제를 확률적 예측으로 풀어냅니다. 또, 확률 값 사이의 손실 함수로는 로그 손실(log loss, 또는 이진 교차엔트로피)을 사용하여 모델 파라미터를 최적화합니다.
오즈비(Odds Ratio)와 로그 오즈(Log Odds)
로지스틱 회귀에서 결과 확률 pp를 표현하는 또 다른 방식은 **오즈(odds)**입니다. 오즈는 “성공 확률 대 실패 확률의 비”로 정의됩니다. 수식으로는 odds=p1−p\text{odds} = \frac{p}{1-p} 형태입니다 (GraphPad Prism 10 Curve Fitting Guide - What are Log Odds and why does logistic regression use them? ). 예를 들어 어떤 이벤트가 발생할 확률 p=0.8p=0.8 (80%)라면 발생하지 않을 확률은 1−p=0.21-p=0.2이며, 이때 오즈는 0.8/0.2=40.8/0.2 = 4로 계산됩니다. 흔히 “4 대 1의 오즈”라고 표현하며, 이는 발생할 확률이 발생하지 않을 확률의 4배라는 의미입니다 (GraphPad Prism 10 Curve Fitting Guide - What are Log Odds and why does logistic regression use them? ).
- *로그 오즈(log odds)**는 이 오즈에 자연 로그를 취한 값입니다. 다시 말해, **로그 오즈 = *로 정의됩니다 (GraphPad Prism 10 Curve Fitting Guide - What are Log Odds and why does logistic regression use them? ). 로지스틱 회귀의 선형 방정식은 바로 이 로그 오즈의 값을 예측한다고 볼 수 있습니다. 로지스틱 회귀 모델을 수식으로 나타내면 다음과 같습니다: ln(p1−p)\ln(\frac{p}{1-p}) lnp1−p=β0+β1x1+β2x2+⋯+βnxn\ln\frac{p}{1-p} = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \dots + \beta_n x_n 위 식에서 좌변 lnp1−p\ln\frac{p}{1-p}가 바로 log-odds (로그 오즈)이며, 우변은 특성들의 선형 결합입니다 (GraphPad Prism 10 Curve Fitting Guide - What are Log Odds and why does logistic regression use them? ). 이 식을 풀어서 생각하면, 로지스틱 회귀 모델의 계수 βi\beta_i는 각 특성이 로그 오즈에 미치는 영향력을 나타냅니다. 계수의 해석을 위해 오즈비(Odds Ratio) 개념을 살펴보겠습니다. 양 변에 지수를 취하면 p1−p=eβ0+β1x1+⋯+βnxn\frac{p}{1-p} = e^{\beta_0 + \beta_1 x_1 + \dots + \beta_n x_n}가 되고, 이를 이용해 특성 xix_i의 한 단위 증가가 오즈에 미치는 영향은 eβie^{\beta_i}로 나타낼 수 있습니다. 즉, βi\beta_i의 지수 함수 값을 보면 해당 변수가 한 단위 증가할 때 오즈가 몇 배로 변하는지 해석할 수 있습니다 (Logistic regression - Wikipedia ). 예를 들어 β1=0.693\beta_1 = 0.693이라면 e0.693≈2.0e^{0.693} \approx 2.0이므로, x1x_1이 한 단위 증가할 때 오즈가 2배로 증가함을 의미합니다 (결과적으로 성공 확률이 2배 높아진다는 해석). 반대로 음수 계수라면 eβi<1e^{\beta_i} < 1이 되어, 해당 특성의 증가가 오즈를 그 만큼 감소시키는 효과가 있습니다. 이처럼 로지스틱 회귀의 계수는 선형 회귀의 계수와 달리 **곱셈적 효과(기하학적 효과)**로 해석됩니다.
2. 비즈니스 활용 사례
로지스틱 회귀는 해석력이 뛰어나고 구현이 용이하여 다양한 비즈니스 분야에서 분류 예측 모델로 애용됩니다. 그 중에서도 특히 고객 이탈 예측과 마케팅 캠페인 반응 예측은 기업의 의사결정에 큰 가치를 주는 대표적인 활용 사례입니다.
고객 이탈 예측 (Customer Churn Prediction)
- *고객 이탈(churn)**이란 고객이 서비스를 해지하거나 떠나는 것을 의미합니다. 통신사, 은행, 보험, SaaS 등 구독 기반 비즈니스에서는 고객 이탈률을 낮추는 것이 매우 중요합니다. 왜냐하면 기존 고객을 유지하는 것이 신규 고객을 유치하는 것보다 비용 효율적인 경우가 많기 때문입니다. 따라서 현업에서는 어떤 고객이 이탈할지를 미리 예측하여 선제적으로 대응하려는 노력이 이루어집니다. 이러한 고객 유지 전략의 핵심 도구로 로지스틱 회귀 모델이 자주 사용됩니다 (Logistic Regression Customer Churn Prediction: Example ).
예를 들어 텔레콤 분야를 생각해보면, 통신사는 로지스틱 회귀를 활용해 다음 달에 서비스를 해지할 가능성이 높은 고객을 예측할 수 있습니다. Kaggle의 Telco Customer Churn 데이터셋은 이러한 목적에 자주 쓰이는 공개 데이터로, 약 7천여 명의 고객에 대한 인구통계, 계정 정보, 사용 서비스, 요금 등이 포함되어 있습니다 (Logistic Regression Customer Churn Prediction: Example ). 이 데이터셋의 목표 변수인
Churn은 각 고객이 최근 한달 내 이탈했는지를 나타내며 (Yes 또는 No), 모델은 이 값을 다른 특성들로부터 예측하게 됩니다. 로지스틱 회귀를 통해 이탈 확률이 산출되면, 회사는 확률이 높은 고객에게 프로모션 제공이나 서비스 개선 등의 맞춤 대응을 함으로써 실제 이탈을 방지할 수 있습니다.
마케팅 캠페인 반응 예측 (Marketing Campaign Response)
또 다른 비즈니스 사례로, 마케팅 캠페인에 대한 고객 반응 예측이 있습니다. 기업은 종종 이메일, 전화, 우편 등을 통해 마케팅 캠페인을 진행하며, 어떤 고객이 캠페인에 긍정적으로 반응할지 (예: 상품 구매나 서비스 신청) 예측하면 타겟 마케팅에 큰 도움이 됩니다. 로지스틱 회귀는 각 고객이 캠페인에 응답할 확률을 예측함으로써, 마케팅 효율을 높이는 데 활용될 수 있습니다.
대표적인 공개 데이터로 은행 마케팅 (Bank Marketing) 데이터셋이 있는데, 포르투갈 은행의 텔레마케팅 캠페인 데이터를 기반으로 **전화 캠페인을 받는 고객이 정기 예금 상품에 가입할지 여부(yes/no)**를 예측하는 문제입니다 (UCI Machine Learning Repository ). 이 데이터에는 고객의 연령, 직업, 과거 캠페인 응답 이력, 경제 지표 등 다양한 변수가 포함되어 있으며, **종속변수 y**가 해당 캠페인 후 정기 예금을 신청했으면 ‘yes’, 아니면 ‘no’로 기록되어 있습니다. 기업은 이러한 모델을 통해 잠재 고객을 선별하고, 높은 확률의 고객에게 자원을 집중함으로써 마케팅 ROI를 높일 수 있습니다.
이 밖에도 신용 카드 연체 예측, 사기 거래 탐지, 직원 이직 예측 등도 로지스틱 회귀가 활용되는 비즈니스 사례입니다. 핵심은 이 알고리즘이 결과를 확률로 설명해주기 때문에, 단순히 분류 결과뿐 아니라 예측에 대한 신뢰도를 함께 고려할 수 있다는 점입니다. 이는 업무 현장에서 의사결정자들이 모델을 신뢰하고 활용하도록 도와줍니다.
3. Python 실습 코드
이제 실제 데이터를 가지고 로지스틱 회귀 모델을 만들어보겠습니다. Kaggle의 Telco Customer Churn 데이터셋을 예시로, 고객 이탈 예측 모델을 구축하는 과정을 단계별로 살펴보겠습니다. 데이터 전처리부터 모델 학습, 성능 평가까지 Python 코드로 구현하며, 실습할 수 있도록 상세한 설명을 덧붙입니다. (이 실습을 따라하기 위해서는 pandas, scikit-learn 등이 설치되어 있어야 합니다.)
데이터 준비: 우선 Kaggle에서 Telco Customer Churn 데이터 (WA_Fn-UseC_-Telco-Customer-Churn.csv)을 다운로드해 작업 디렉토리에 준비합니다. 이 데이터를 DataFrame으로 불러와 사용하겠습니다.
데이터 불러오기 및 전처리
먼저 pandas를 사용해 데이터를 불러오고, 기본적인 구조를 확인해보겠습니다.
import pandas as pd
# 데이터셋 불러오기 (로컬 경로를 사용자 환경에 맞게 설정)
data = pd.read_csv("WA_Fn-UseC_-Telco-Customer-Churn.csv")
# 처음 5행과 데이터 정보 출력
print(data.head(5))
print(data.info())
위 코드로 데이터 프레임을 생성하면, 컬럼으로는 customerID, gender, SeniorCitizen, Partner, Dependents, tenure, PhoneService, MultipleLines, InternetService, OnlineSecurity 등 다양한 고객 정보가 있고, 끝부분에 TotalCharges(총 이용 금액)와 목표 변수 Churn(이탈 여부)이 있습니다 (Logistic Regression Customer Churn Prediction: Example ). Churn 컬럼이 우리가 예측하고자 하는 값으로, “Yes” 또는 “No”로 표기되어 있습니다.
이제 전처리를 진행해보겠습니다. 전처리 내용:
- 사용하지 않을 식별자 컬럼
customerID는 예측에 의미가 없으므로 제거합니다. - 범주형 변수 인코딩:
Yes/No나 기타 문자열로 된 범주형 변수들을 숫자로 변환합니다. (gender,Partner,Dependents등은 “Yes”/“No” 또는 “Male”/“Female”로 되어 있으므로 0/1로, 인터넷 서비스 종류 등은 여러 카테고리이므로 원-핫 인코딩) TotalCharges는 숫자형이어야 하는데, 일부 공백 또는 결측이 있을 수 있으므로 문자열을 숫자로 변환하고, 필요시 결측값을 처리합니다.- 특성 스케일 조정: 로지스틱 회귀에서는 필수는 아니지만, 수렴 속도를 높이고 해석을 돕기 위해 연속형 변수 (
tenure,MonthlyCharges,TotalCharges등)를 스케일링(표준화)할 수 있습니다. 여기서는 간단히 진행하기 위해 스케일링은 생략하고 그대로 사용하겠습니다.
# 1. 불필요한 컬럼 제거
data = data.drop("customerID", axis=1)
# 2. 대상 변수 변환 ("Yes"->1, "No"->0)
data['Churn'] = data['Churn'].map({'Yes': 1, 'No': 0})
# 3. TotalCharges를 수치형으로 변환하고 결측 처리
data['TotalCharges'] = pd.to_numeric(data['TotalCharges'], errors='coerce')
# 결측값 존재 여부 확인
print("TotalCharges null count:", data['TotalCharges'].isna().sum())
# 결측값이 있다면 해당 행 제거 (또는 0으로 채울 수도 있음)
data = data.dropna(subset=['TotalCharges'])
# 4. 범주형 변수 원-핫 인코딩 (더미 변수로 변환)
# 먼저 범주형 컬럼 목록을 식별 (object 타입인 컬럼들)
cat_cols = [col for col in data.columns if data[col].dtype == 'O' and col != 'Churn']
print("Categorical columns:", cat_cols)
data = pd.get_dummies(data, columns=cat_cols, drop_first=True)
위 전처리 과정에서는 pd.get_dummies를 사용하여 문자열 범주형 변수들을 0/1의 더미(dummy) 변수로 바꿨습니다. drop_first=True 옵션은 각 범주형 변수에 대해 첫 번째 범주를 드롭하여 **다중 공선성(dummy trap)**을 피하는 역할을 합니다. 예를 들어 InternetService가 “DSL”, “Fiber optic”, “No” 세 가지 범주였다면, 두 개의 dummy 변수 (InternetService_Fiber optic, InternetService_No)를 만들고 DSL 여부는 이 두 변수 모두 0인 경우로 표현됩니다.
전처리 완료 후 data 데이터프레임은 모두 숫자형 컬럼으로 구성되어 있으며, 이제 모델 학습에 바로 활용할 수 있는 형태가 되었습니다.
로지스틱 회귀 모델 학습
이제 데이터를 훈련 세트와 테스트 세트로 분할하고, 로지스틱 회귀 모델을 학습시켜보겠습니다. 보통 70~80%를 훈련(train), 나머지를 테스트(test)용으로 사용합니다. 여기서는 scikit-learn의 train_test_split 함수를 이용해 80%는 훈련, 20%는 테스트 세트로 나누겠습니다. 또한 분류 문제에서 데이터가 불균형한 경우(Churn=1과 0 비율 차이)에는 Stratify 옵션을 사용하면 편리합니다. 이 데이터셋에서는 대략 이탈율이 26% 정도로 불균형성이 있기 때문에, stratify=y 옵션으로 분할 시 클래스 비율이 유지되도록 합니다.
그 다음 scikit-learn의 LogisticRegression 클래스를 이용해 모델을 정의하고 훈련합니다. 여기서는 기본 매개변수를 사용하지만, solver를 liblinear로 지정하여 수렴을 확실히 하고자 합니다 (작은 데이터셋이나 L1 규제를 사용할 때 liblinear가 적합).
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
# 특성과 대상 변수 분리
X = data.drop('Churn', axis=1)
y = data['Churn']
# 데이터 분할 (80% train, 20% test)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42)
# 로지스틱 회귀 모델 정의 및 학습
model = LogisticRegression(solver='liblinear', random_state=42)
model.fit(X_train, y_train)
모델이 학습되면서, 내부적으로 **최대우도 추정(MLE)**을 통해 각 특성의 계수 β\beta들이 최적화됩니다. 학습 완료 후 model.coef_ 속성에서 학습된 계수 값을 확인할 수 있고, model.intercept_에서 절편 β0\beta_0을 확인할 수 있습니다. 필요하다면 이 값들을 출력해서 어떤 변수가 양수 계수(이탈을 촉진)인지, 음수 계수(이탈을 억제)인지 살펴볼 수 있습니다. 예를 들어 tenure(이용 기간)의 계수가 음수라면 이용 기간이 길수록 이탈 확률이 낮아지는 경향을 의미합니다. 반대로 MonthlyCharges(월요금)의 계수가 양수라면 월요금이 높을수록 이탈 확률이 증가한다는 해석이 가능합니다. 이처럼 모델은 학습된 계수를 통해 비즈니스 인사이트를 제공하기도 합니다.
모델 평가 및 결과 해석
모델 평가는 테스트 세트에 대해 예측을 수행하여 실제 값과 비교함으로써 이루어집니다. 분류 모델의 성능을 평가하는 대표적인 지표로 정확도(accuracy), 정밀도(precision), 재현율(recall), F1-스코어, 그리고 ROC-AUC 등이 있습니다. 각 지표의 의미는 다음과 같습니다:
- 정확도(Accuracy): 전체 샘플 중 맞게 예측한 비율.
- 정밀도(Precision): 모델이 positive(여기서는 이탈) 예측을 한 것들 중 실제로 positive인 비율. (예측의 정확도 관점)
- 재현율(Recall): 실제 positive 샘플 중 모델이 positive로 맞게 예측한 비율. (실제 커버리지 관점, 민감도라고도 함)
- F1-score: 정밀도와 재현율의 조화평균. 두 지표의 균형을 고려한 점수.
- ROC-AUC: ROC곡선 아래 면적. 1에 가까울수록 분류를 잘함을 의미. (0.5는 랜덤 추측 수준)
이제 우리 모델의 성능을 평가해보겠습니다. 우선 테스트 세트에 대한 예측값과 예측확률을 얻은 뒤, 혼동행렬(Confusion Matrix)과 위 지표들을 계산합니다. scikit-learn의
metrics모듈에 다양한 함수를 사용할 수 있는데, 편의상classification_report를 이용하면 정밀도, 재현율, F1, 정확도를 한꺼번에 볼 수 있고,roc_auc_score로 AUC 값을 구할 수 있습니다.
from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score
# 테스트 세트 예측
y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1] # positive 클래스(Churn=1) 확률
# 혼동행렬 출력
cm = confusion_matrix(y_test, y_pred)
print("Confusion Matrix:\n", cm)
# 정밀도, 재현율 등 분류 성능 지표 출력
print("Classification Report:\n", classification_report(y_test, y_pred, digits=3))
# ROC-AUC 계산
auc = roc_auc_score(y_test, y_prob)
print(f"ROC-AUC: {auc:.3f}")
위 코드의 실행 결과로 얻은 혼동행렬과 분류 보고서를 해석해봅시다. 혼동행렬은 예측값과 실제값의 교차 표로, 예를 들어 아래와 같은 형태일 수 있습니다 (여기서는 가상의 결과 수치입니다):
Confusion Matrix:
[[950 50]
[120 180]]
- [[TN, FP], [FN, TP]] 순서로,
- TN(True Negative) = 950 : 실제 No 이탈을 No로 잘 예측한 수
- FP(False Positive) = 50 : 실제 No 이탈인데 잘못 예측한 수 (False alarm)
- FN(False Negative) = 120 : 실제 Yes 이탈을 놓친 수
- TP(True Positive) = 180 : 실제 Yes 이탈을 Yes로 맞힌 수
분류 보고서(
classification_report)는 클래스별 정밀도, 재현율, F1을 보여줍니다. 예를 들어 **클래스 1 (Churn=Yes)**에 대해 정밀도 0.78, 재현율 0.60, F1-score 0.68 등의 수치가 나왔다면, 이는 이탈이라고 예측한 경우의 78%는 실제 이탈이었고, 실제 이탈 고객의 60%를 잡아냈음을 의미합니다. Accuracy는 전체의 몇 %를 맞췄는지인데, 위 예시 혼동행렬 기준으로는 (950+180)/(950+50+120+180)≈0.88(950+180)/(950+50+120+180) \approx 0.88, 즉 88% 정확도입니다. 그러나 정확도 하나만으로는 불균형 데이터의 성능을 평가하기에 충분하지 않을 수 있으므로, 정밀도와 재현율을 함께 고려하는 것이 중요합니다. 우리 모델의 목표는 이탈 고객을 잘 잡아내는 것이므로 재현율(Recall)을 특히 신경써야 하지만, 동시에 엉뚱한 경보(FP)를 너무 많이 울리지 않도록 정밀도도 살펴봐야 합니다. 마지막으로 ROC-AUC 값은 모델의 전체적인 판별 능력을 나타냅니다. AUC가 0.5이면 무작위 수준, 1.0이면 완벽 분류입니다. 실습한 모델에서 ROC-AUC가 예를 들어 0.85 정도 나왔다면, 비교적 양호하게 이탈 고객과 비이탈 고객을 구분하는 모델이라고 볼 수 있습니다.
결과 해석: 로지스틱 회귀 모델의 강점은 결과를 해석하기 쉽다는 점입니다. 각 독립 변수의 회귀계수 β\beta를 살펴보면, 어떤 요인이 이탈 확률에 큰 영향을 주는지 알 수 있습니다. 예를 들어 모델에서 Contract_Two year (2년 약정 여부) 변수가 매우 큰 음수 계수를 가진다면, 2년 약정을 맺은 고객은 이탈 가능성이 현저히 낮다는 인사이트를 얻을 수 있습니다. 반대로 Fiber optic 인터넷 서비스 여부가 양의 계수라면, 광케이블 인터넷을 쓰는 고객들이 다른 서비스 대비 이탈 확률이 높음을 시사합니다. 이러한 해석을 토대로, 비즈니스 담당자들은 이탈 위험이 높은 군집에 대한 원인 분석이나 대응 전략을 수립할 수 있습니다.
4. 실전 응용 및 개선 방법
로지스틱 회귀 모델의 성능을 향상시키거나 실전에 적합하게 만들기 위해 고려할 수 있는 여러 가지 기법들이 있습니다. 특성 선택, 정규화 및 하이퍼파라미터 튜닝, 비선형 관계 반영 등이 그것입니다. 하나씩 살펴보겠습니다.
특성 선택 및 중요도 분석
모델에投入된 모든 변수가 실제로 예측에 도움이 되는 것은 아닙니다. 관련 없는 특성을 포함하면 오히려 노이즈가 증가하고 모델 일반화 성능이 낮아질 수 있습니다. 따라서 데이터를 잘 이해하고, 필요한 경우 **특성 선택(feature selection)**을 수행하는 것이 좋습니다. 특성 선택 방법으로는 도메인 지식에 기반한 선택이 우선 될 수 있고, 통계적으로는 Recursive Feature Elimination (RFE) 같은 기법이나 **Regularization(정규화)**을 활용한 방법 (L1 규제는 가중치 일부를 0으로 만들어 자동으로 특성 선택 효과를 냄)을 고려할 수 있습니다. 예를 들어, L1 정규화 로지스틱 회귀(Lasso 회귀와 유사)를 적용하면 영향력이 약한 변수의 계수가 0으로 수축되어 모델이 보다 중요한 변수만 활용하게 됩니다. 또한 **피처 중요도(feature importance)**를 판단하기 위해 학습된 로지스틱 회귀의 계수 절댓값을 살펴볼 수 있습니다. 계수의 절댓값이 큰 변수가 상대적으로 예측에 중요한 변수라고 볼 수 있지만, 주의할 점은 변수의 스케일에 따라 계수 크기가 달라질 수 있다는 것입니다. 따라서 표준화한 데이터에서 계수를 비교하거나, **변수의 오즈비(이전 섹션에서 설명)**를 통해 중요도를 해석하는 것이 좋습니다. 오즈비가 1에서 크게 벗어날수록 (예: 2나 0.5 등) 해당 변수의 영향력이 크다고 할 수 있습니다. 이렇게 주요 변수를 파악하면, 비즈니스적으로 중요 요인을 설명하는 데에도 도움을 줍니다.
정규화(Regularization)와 하이퍼파라미터 튜닝
정규화는 모델의 복잡도를 적절히 제어하여 **과적합(overfitting)**을 방지하는 기법입니다. 로지스틱 회귀에서는 보통 L2 정규화(릿지)가 기본으로 적용되며, 규제 강도는 하이퍼파라미터 CC로 제어됩니다 (sklearn.linear_model.LogisticRegression에서 C는 규제 강도의 역수로, 작을수록 강한 정규화). L2 정규화는 매우 큰 계수 값을 억제하여 모델을 더 보수적으로 만들어주고, 다소 성능을 양보하더라도 변동이 적고 일반화가 잘 되도록 돕습니다. L1 정규화는 앞서 언급한 대로 일부 특성의 계수를 0으로 만들어 변수 선택 효과를 주기도 합니다.
하이퍼파라미터 튜닝은 모델의 최적 파라미터를 찾는 과정입니다. 로지스틱 회귀의 주요 하이퍼파라미터는 정규화 강도(C), 정규화 유형(penalty=‘l1’ or ‘l2’), solver 종류 등입니다. 일반적으로 **교차 검증(cross-validation)**을 통해 여러 후보 파라미터를 시험한 뒤 최적 조합을 선택합니다. scikit-learn의 GridSearchCV나 RandomizedSearchCV를 활용하면 편리합니다. 예를 들어 CC 값을 [0.01, 0.1, 1, 10] 등으로 바꿔가며 교차검증을 수행해 가장 높은 평균 정확도를 주는 값을 고를 수 있습니다.
정규화를 적절히 사용하면 모델의 일반화 성능이 향상되고, 너무 복잡한 모델이 만들어지는 것을 막아줍니다. 특히 다중공선성 문제가 있는 경우 정규화가 일부 완화 효과를 주기도 합니다 (계수를 작게 만들어 불안정성을 줄임).
비선형 관계 처리 (다항 특성, 상호작용 항 등)
로지스틱 회귀는 기본적으로 선형 결정 경계를 학습합니다. 즉, 특성과 log-odds 사이를 직선(또는 평면) 관계로 가정하기 때문에, 실제 데이터의 관계가 비선형이면 모델이 이를 충분히 포착하지 못할 수 있습니다. 이런 경우 몇 가지 대처 방안이 있습니다:
- 다항 특성 추가: 원 변수 xx로 x2,x3x^2, x^3 등의 다항식 특징을 생성하면 모델에 다소 비선형 효과를 줄 수 있습니다. 예를 들어 고객의 사용 기간
tenure와 이탈 확률이 단순 선형이 아니라 어느 시점 이후 급증하는 형태라면, tenure2tenure^2 항을 추가해 곡선 형태의 관계를 학습할 수 있습니다. scikit-learn의PolynomialFeatures를 사용하면 편리하게 다항 특성을 생성할 수 있습니다. - 상호작용 항: 두 변수의 곱을 새로운 특성으로 넣어 변수 간 상호작용 효과를 반영할 수 있습니다. 예를 들어
SeniorCitizen과InternetService_Fiber optic의 곱을 특성으로 추가하면 “고령 사용자이면서 광랜 사용자”라는 교차 특성을 모델이 따로 고려하게 할 수 있습니다. 이러한 상호작용이 의미 있을 경우 모델 성능이 향상될 수 있습니다. - 복잡한 모델로 전환: 만약 데이터에 복잡한 비선형 패턴이 많다면, 로지스틱 회귀로 이를 모두 캡처하기는 어려울 수 있습니다. 이럴 때는 의사결정나무, 랜덤포레스트, 그라디언트 부스팅, 신경망 등 비선형 모델을 사용하거나, 로지스틱 회귀 전에 커널 변환 등을 고려할 수도 있습니다. 그러나 모델이 복잡해지면 해석력은 떨어질 수 있으므로, 비즈니스 요구사항에 맞게 해석 vs 성능의 균형을 고려해야 합니다.
5. 주의사항 및 한계
마지막으로, 로지스틱 회귀를 실무에 적용할 때 유의해야 할 점들과 이 알고리즘의 한계를 정리합니다.
데이터 불균형 처리
비즈니스 문제에서는 종종 Positive 클래스가 드문 불균형(Imbalanced) 데이터셋이 나타납니다. 예를 들어 전체 고객 중 이탈 고객은 10% 미만인 경우가 많습니다. 이런 불균형 상태에서 단순히 정확도를 최대화하면 소수 클래스(이탈 고객)를 놓치기 쉽습니다. 모델이 대부분을 No churn으로 예측하더라도 정확도는 높게 나올 수 있기 때문입니다 (Accuracy Paradox 문제). 이를 극복하기 위해 데이터 리샘플링 기법을 활용할 수 있습니다. 언더샘플링은 다수 클래스 데이터를 줄이는 방법이고, 오버샘플링은 소수 클래스를 늘리는 방법입니다. 특히 SMOTE(Synthetic Minority Oversampling Technique)는 자주 쓰이는 오버샘플링 기법으로, 소수 클래스의 새로운 합성 샘플을 생성하여 데이터를 증강합니다 (Smote for Imbalanced Classification with Python, Technique ). 예를 들어 이탈 고객 데이터 포인트들 사이에 가상 포인트를 만들어 데이터 균형을 맞추는 것입니다. 이러한 방법을 통해 모델이 소수 클래스 패턴도 충분히 학습하도록 도울 수 있습니다. 다만, 리샘플링은 훈련 데이터에만 적용하고, 테스트 데이터에는 원본 분포를 유지해야 올바른 평가가 가능함을 기억해야 합니다. 또한 불균형 문제에서는 앞서 언급한 정밀도 vs 재현율의 균형을 조절하는 것이 중요합니다. **분류 임곗값(threshold)**을 조정하여 민감도를 높이거나 (재현율↑, 정밀도↓) 혹은 경보 오탐률을 낮추는 (정밀도↑, 재현율↓) 식으로 비즈니스 상황에 맞게 튜닝할 수 있습니다. 예컨대 이탈 예측에서는 재현율을 높여 이탈 가능성 있는 고객을 최대한 포착하는 쪽이 중요할 수 있습니다.
다중 공선성(Multicollinearity) 문제
로지스틱 회귀를 비롯한 선형 모델에서는 다중 공선성(독립변수 간 강한 상관관계)이 있을 경우 문제가 될 수 있습니다. 서로 상관관계가 높은 변수가 여러 개 있으면, 모델의 계수 추정이 불안정해지고 표준 오차가 커져서 통계적 유의성이 낮아질 수 있습니다 (Diagnosing Multicollinearity of Logistic Regression Model ). 예를 들어 MonthlyCharges와 TotalCharges는 상당한 상관관계가 있을 텐데 (총 이용금액은 월요금과 이용개월 수의 함수이므로), 이 둘을 동시에 모델에 넣으면 하나의 효과를 다른 변수가 일부 대변하게 되어 계수 해석이 어려워집니다.
다중 공선성을 진단하는 방법으로 **VIF(Variance Inflation Factor)**를 계산하거나, 변수 간 상관행렬을 보는 방법이 있습니다. 일반적으로 VIF 값이 10 이상이면 강한 다중공선성이 있다고 판단합니다. 해결 방법으로는 상관된 변수 중 하나를 제거하거나, PCA와 같은 차원 축소 기법을 사용하는 것이 있습니다. 혹은 앞서 말한 정규화 기법을 적용하면 계수를 어느 정도 안정화시켜 공선성의 영향을 줄일 수 있습니다. 필요하다면 변수 간 상관관계를 고려하여 변수 선택/변환을 신중히 해야 합니다.
해석 가능성과 모델 성능 간의 균형
로지스틱 회귀의 큰 장점은 **모델의 해석 가능성(interpretability)**입니다. 어떤 변수가 결과에 얼마나 영향을 주는지 직접적으로 파악할 수 있고, 예측 확률을 출력하므로 의사결정 근거를 설명하기 용이합니다. 이런 이유로 금융권이나 의료 분야처럼 설명이 필요한 영역에서 선호되죠. 다만 해석이 쉬운 모델은 대체로 구조가 단순하기 마련이며, 이는 때때로 예측 성능의 한계로 이어질 수 있습니다 (Interpretability vs. explainability in AI and machine learning | TechTarget ) (Interpretability vs. explainability in AI and machine learning | TechTarget ). 예를 들어 딥러닝이나 앙상블 모델(XGBoost 등)은 복잡한 패턴을 포착하여 더 높은 정확도를 낼 수 있지만, 로지스틱 회귀보다 블랙박스에 가깝습니다. 실제 비즈니스 적용에서는 해석력 vs 성능 사이에서 균형을 찾아야 합니다. 모델의 예측을 신뢰하고 actionable insight를 얻는 것이 중요하다면 로지스틱 회귀처럼 해석 가능한 모델이 적합합니다. 반면, 몇 퍼센트의 성능 향상이 큰 비즈니스 가치로 이어지고 모델 설명 필요성이 낮다면 더 복잡한 모델을 고려할 수 있습니다. 한가지 절충안으로, 복잡한 모델을 쓰더라도 사후 해석 기법(예: SHAP 값, LIME 등을 통한 feature contribution 설명)을 활용하여 일부 설명력을 확보하는 방법도 있습니다. 하지만 일반적으로, 모델이 단순할수록 투명성이 높고, 복잡할수록 성능 잠재력이 높다는 트레이드오프가 존재함을 기억해야 합니다 (Interpretability vs. explainability in AI and machine learning | TechTarget ) (Interpretability vs. explainability in AI and machine learning | TechTarget ).
이상으로 비즈니스 데이터를 활용한 로지스틱 회귀 분석에 대해 살펴보았습니다. 로지스틱 회귀는 중급 데이터 과학자라면 반드시 익혀야 할 기본 알고리즘이며, 실제 현업에서도 활용도가 높습니다. 개념적으로 탄탄히 이해하고 Python으로 직접 실습해본다면, 어떤 문제에 어떻게 적용해야 할지 감이 잡히실 것입니다. 마지막으로 요약하자면:
- 로지스틱 회귀는 확률 기반 이진 분류 모델로, sigmoid 함수를 통해 0-1 사이 확률을 예측하고 분류합니다.
- 오즈비와 로그 오즈 개념을 알면 로지스틱 회귀의 계수를 해석하기 쉽습니다 (β 계수의 지수값이 오즈비).
- 비즈니스 사례로 고객 이탈, 마케팅 응답 예측 등에 활용되며, 적절한 특성 공학과 불균형 처리를 통해 성능을 높일 수 있습니다.
- Python의 scikit-learn으로 손쉽게 구현 가능하며, 정확도, 정밀도, 재현율, AUC 등의 지표로 성능을 평가합니다.
- 모델을 개선하기 위해 불필요한 특성 제거, 정규화 및 하이퍼파라미터 튜닝, 비선형 특성 추가 등을 시도해볼 수 있습니다.
- 로지스틱 회귀는 해석이 용이하지만 복잡한 패턴을 잡는 데 한계가 있으므로, 경우에 따라 더 복잡한 모델과의 트레이드오프를 고려해야 합니다. 이를 통해 로지스틱 회귀에 대한 전반적인 이해와 실무 감각을 향상시키길 바랍니다. 실제 데이터에 적용하고 꾸준히 연습하면서 자신의 것으로 만들어보세요. Happy analyzing!