contents
summary
여성은 모두 생존, 남성은 모두 사망으로 판별한다면?
- 정확도: 78.6% (여성 생존 233 + 남성 사망 468) / 전체 인원 891
->모델을 만들지 않고도 무려 80%에 가까운 정확도를 만들다니 엄청난 인사이트! 그러나 추가적 도구를 활용해 정확도의 수치를 높힐 수 있다!
로지스틱회귀 이론
☑️ 범주형 Y에서 선형함수의 한계
X가 연속형 변수이고, Y가 특정 값이 될 확률이라고 설정한다면, 선형으로 설명하긴 쉽지 않다. 확률은 0과 1사이 인데, 예측 값이 확률 범위를 넘어갈 수 있는 문제가 발생!
그래서 S자 형태의 함수를 적용하면 잘 설명한다고 할 수 있을 것이다.
-Y가 0,1 범주형인 경우 함수 적합
☑️ 로짓의 개념의 등장
📌위 S형태의 함수를 만들기 위해서 오즈비(Odds ratio)의 개념을 적용.
승산비
라 불리는 오즈비는 실패확률 대비 성공확률로, 도박사들이 자주 쓰는 개념.
예를 들어 도박이 성공할 확률이 80% 라면, 오즈비는 80%/20% = 4 예요. 다시 해석해보면 1번 실패하면 4번은 딴다는 말.
하지만 오즈비는 바로 쓸 수 없다. P는 확률 값으로 0,1사이 값인데, P가 증가할수록 오즈비가 급격하게 증가하기 때문에 너무 확률이 급격하게 증가하고 선형성을 따르지 않게 된다. 따라서 로그를 씌워 이 부분을 좀 완화하기로 한다.
이때, 확률 0.5를 기준으로 그보다 높으면 사건이 일어남(P(Y) = 1), 그렇지 않으면 사건이 일어나지 않음(P(Y) = 0)으로 판단하여 분류 예측에 사용.
sklearn.linear_model.LogisticRegression
: 로지스틱회귀 모델 클래스classes_
: 클래스(Y)의 종류n_features_in_
: 들어간 독립변수(X) 개수feature_names_in_
: 들어간 독립변수(X)의 이름coef_
: 가중치intercept_
: 바이어스fit
: 데이터 학습predict
: 데이터 예측predict_proba
: 데이터가 Y = 1일 확률을 예측sklearn.metrics.accuracy
: 정확도sklearn.metrics.f1_socre
: f1_scoretitaninc_df.head(3)
# info(): 데이터에 대한 결측치, 데이터전체 갯수 등을
titaninc_df.info()
숫자
범주형
X변수 1개, Y변수(Survived)
# X변수: Fare, Y변수: Survived
X_1 = titaninc_df[['Fare']]
y_true = titaninc_df[['Survived']]
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.linear_model import LogisticRegression
model_lor = LogisticRegression()
model_lor.fit(X_1, y_true)
2) 변수
- 1차 모델: Fare
sns.scatterplot(titaninc_df, x = 'Fare', y = 'Survived')
산점도보다 히스토 그램으로 분산을 확인하는 것이 더 좋을 듯 싶다
sns.histplot(titaninc_df, x = 'Fare')
# 데이터 기술통계를 보는법(수치형) describe()
titaninc_df.describe()
def get_att(x):
#x모델을 넣기
print('클래스 종류', x.classes_)
print('독립변수 갯수', x.n_features_in_)
print('들어간 독립변수(x)의 이름',x.feature_names_in_)
print('가중치',x.coef_)
print('바이어스', x.intercept_)
get_att(model_lor)
클래스 종류 [0 1]
독립변수 갯수 1
들어간 독립변수(x)의 이름 ['Fare']
가중치 [[0.01519666]]
바이어스 [-0.94131796]
from sklearn.metrics import accuracy_score, f1_score
def get_metrics(true, pred):
print('정확도', accuracy_score(true, pred))
print('f1-score', f1_score(true, pred))
y_pred_1 = model_lor.predict(X_1)
y_pred_1[:10]
len(y_pred_1)
891
get_metrics(y_true, y_pred_1)
정확도 0.6655443322109988
f1-score 0.35497835497835495
숫자
범주형
X변수 개, Y변수(Survived)
#Y(Surivved): 사망
#X(수치형): Fare
#X(범주형): Plcass(좌석등급), Sex
def get_sex(x):
if x == 'female':
return 0
else:
return 1
titaninc_df['Sex_en'] = titaninc_df['Sex'].apply(get_sex)
titaninc_df.head(3)
X_2 = titaninc_df[['Pclass','Sex_en','Fare']]
y_true = titaninc_df[['Survived']]
model_lor_2 = LogisticRegression()
model_lor_2.fit(X_2,y_true)
get_att(model_lor_2)
클래스 종류 [0 1]
독립변수 갯수 3
들어간 독립변수(x)의 이름 ['Pclass' 'Sex_en' 'Fare']
가중치 [[-8.88331324e-01 -2.53993425e+00 1.64019087e-03]]
바이어스 [3.02004403]
y_pred_2 = model_lor_2.predict(X_2)
y_pred_2[:10]
y_pred_2 = model_lor_2.predict(X_2)
y_pred_2[:10]
y_pred_1[:10]
array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int64)
3) 평가하기
1. accuracy
2. f1_score
# X변수가 Fare
get_metrics(y_true, y_pred_1)
# X변수가 Fare, Pclass, Sex
get_metrics(y_true, y_pred_2)
정확도 0.6655443322109988
f1-score 0.35497835497835495
정확도 0.7867564534231201
f1-score 0.7121212121212122
# 각 데이터별 Y=1인 확률 뽑아내기(생존할 확률)
model_lor_2.predict_proba(X_2)
array([[0.8977979 , 0.1022021 ],
[0.09546762, 0.90453238],
[0.40901264, 0.59098736],
...,
[0.40287202, 0.59712798],
[0.58880217, 0.41119783],
[0.89772263, 0.10227737]])
y_pred_2[:10]
array([0, 1, 1, 1, 0, 0, 0, 0, 1, 1], dtype=int64)
로지스틱회귀
- 장점: 역시 직관적이며 이해하기 쉽다.
- 단점: 복잡한 비선형 관계를 모델링 하기 어려울 수 있음
- Python 패키지
- sklearn.linear_model.LogisticRegresson
insight
F1 스코어와 변수 중요도
F1 스코어는 모델의 예측 성능(정밀도와 재현율의 조화)을 나타낸다.
특정 변수가 F1 스코어에 얼마나 기여하는지는 변수 간의 상관관계, 데이터 분포, 모델의 학습 방법에 따라 다르다.
따라서, 단순히 회귀 계수의 크기로 F1 스코어에 어떤 변수가 가장 큰 영향을 미치는지 직접적으로 판단할 수는 없다.
그리고 추가적으로 f1score를 높이고 싶다면 GridSearchCV를 사용해 로지스틱 회귀의 하이퍼파라미터(C 값)를 최적화하면 F1 스코어를 높일 수 있다!
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import f1_score
# 하이퍼파라미터 튜닝
param_grid = {'C': [0.01, 0.1, 1, 10, 100]}
grid = GridSearchCV(LogisticRegression(max_iter=1000), param_grid, scoring='f1', cv=5)
grid.fit(X_train, y_train)
# 최적의 모델로 예측
best_model = grid.best_estimator_
y_pred = best_model.predict(X_test)
# F1 스코어 출력
f1 = f1_score(y_test, y_pred)
print(f"Best F1 Score: {f1:.4f}")
+교차 검증과 특성 선택
:변수 선택을 자동화하려면 RFE (Recursive Feature Elimination) 같은 기법을 사용할 수 있다.
from sklearn.feature_selection import RFE
# 로지스틱 회귀 모델과 RFE
model = LogisticRegression(max_iter=1000)
rfe = RFE(model, n_features_to_select=5) # 중요 변수 5개 선택
rfe.fit(X_train, y_train)
# 선택된 변수
print("Selected Features:", X_train.columns[rfe.support_])