ML(Machine Learning)
┌───┴───┐
숫자 범주/카테고리
(회귀) (분류)
↓ ↓
사전적 의미 카테고리 맞추는 것
:평균으로 다시
돌아간다 == 회귀
머신러닝에서는
숫자 맞추는 것
🡆 예측이라는 건 동일한데 종속변수가 다를 뿐
🡆 로지스틱회귀의 경우 원래 있던 선형회귀의 '식'을 차용해 가지고 와서 로지스틱+(선형)회귀 → 로지스틱회귀라는 이름이 붙은 것이지 숫자 맞추는 알고리즘인 건 아님!
머신이는 이제 숫자를 맞추는 회귀분석에 대해서 어느 정도 감을 잡았습니다. 그러던 중 타이타닉 탑승객과 사망에 대한 데이터를 입수했습니다. 0,1을 맞추는 것도 그리 어렵지 않아 보입니다. 일단 데이터를 한번 확인해보아요.
Kaggle
- 머신러닝, AI를 위한 대회나 데이터셋 보관하는 커뮤니티 사이트
import pandas as pd
titanic_df = pd.read_csv('train.csv', encoding='utf-8')
titanic_df.head(3)
titaninc_df.head()
변수 설명
*컬럼명에 오류가 있습니다만, 추후에 위 2가지 변수는 Family로 더하여 사용할 예정입니다.
머신이는 승객의 정보로 생존을 예측하는 문제를 보니 매우 재밌는 사실을 발견했어요. 여성은 생존 확률이 높고 남성은 생존 확률이 낮다는 것이에요. 이 부분만 적용해도 기본적인 예측은 할 수 있을 것 같아요.
# 가설: 비상 상황 특성상 여성을 배려해서 여성이 많이 생존
# Pivot table을 만들어 확인
pd.pivot_table(titanic_df, index='Sex', columns='Survived', aggfunc='size')

# 그래프를 통해서 확인
import seaborn as sns
sns.countplot(titanic_df, x='Sex', hue='Survived')

정확도(Accuracy)
생존을 맞춤
(233+468)/891*100
→ 78.67564534231201


모델을 만들지 않고도 무려 80%에 가까운 정확도를 만들다니 엄청난 인사이트입니다. 하지만 이건 Data Scientific하지 않았어요.
→ Data Algorithm으로 적용한 것이 아니라 규칙(Rule-based) 기준으로 맞춘 것이기 때문
이를 위해 좀 더 쓸만한 도구가 필요할 것 같네요!
→ 0≤P≤1

X가 연속형 변수이고, Y가 특정 값이 될 확률이라고 설정한다면, 왼쪽 그림과 같이 선형으로 설명하긴 쉽지 않아 보입니다. 확률은 0과 1 사이인데, 예측 값이 확률 범위를 넘어갈 수 있는 문제가 있죠.
하지만 오른쪽 그림처럼 S자 형태의 함수를 적용하면 잘 설명한다고 할 수 있을 것 같아요!
갑자기 왠 생소한 개념이라 생각하겠지만, 승산비라 불리는 오즈비는 실패확률 대비 성공확률로, 도박사들이 자주 쓰는 개념입니다.
예를 들어 도박이 성공할 확률이 80%라면, 오즈비는 80%/20% = 4예요. 다시 해석해보면 1번 실패하면 4번은 딴다는 소리입니다.


로지스틱 함수는 시그모이드 함수 중 하나!
딥러닝에서 다시 활용되니 '값을 계산하면 확률이 도출된다'는 걸 기억해 주세요.
로짓의 장점은 어떤 값을 가져오더라도 반드시 특정 사건이 일어날 확률(Y값이 특정 값일 확률)이 0과 1 안으로 들어오게 하는 특징을 가지고 있다는 것입니다.
로지스틱함수는 가중치 값을 안다면 X값이 주어졌을 때 해당 사건이 일어날 수 있는 P의 확률을 계산할 수 있게 됩니다.
이때, 확률 0.5를 기준으로 그보다 높으면 사건이 일어남(P(Y) = 1), 그렇지 않으면 사건이 일어나지 않음(P(Y) = 0)으로 판단하여 분류 예측에 사용합니다.
→ 0.5를 '임계값'이라고 함!
x = 연속형, 성별(0, 1)
y = 이진분류(0, 1) / 다중분류(Softmax)
회귀분석이 숫자를 예측하고 실제 값과 평가했던 것처럼, 분류라는 문제를 평가하는 것도 쉽게 보입니다.
예를 들어 맞춘 정답을 전체 데이터의 개수로 나누면 될 것처럼 보여요. 하지만 과연 그럴까요?
러닝이는 끝내주는 데이터 분석가라고 소문나있어요. 이 친구는 병원에 암을 예측하는 진단 소프트웨어를 개발 해달라는 요청을 받고 납품하는 상황이에요. 그런데 너무 귀찮은 나머지 모든 환자를 정상이라고 판정하는 “암 예측 모델”을 만들었어요.
정확도는 매우 높은 것 같지만 실제로 양성(암 환자)는 하나도 못 맞췄어요. 이런 사기를 잘 걸러내기 위한 지표를 만들어봅시다.
실제 값과 예측 값에 대한 모든 경우의 수를 표현하기 위한 2x2 행렬
표기법
해석
지표
정밀도(Precision): 모델이 양성 1로 예측한 결과 중 실제 양성의 비율(모델의 관점)

재현율(Recall): 실제 값이 양성인 데이터 중 모델이 양성으로 예측한 비율(데이터의 관점)

f1-Score: 정밀도와 재현율의 조화 평균
정확도(Accuracy)
실제 적용
위처럼 정확도가 제 기능을 못하는 때는 분류에서 특히 Y값이 unbalance하지 못할 때 일어나요. 따라서 이를 위해서 Y 범주의 비율을 맞춰주거나 평가 지표를 f1 score을 사용함으로써 이를 보완한답니다.
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_score.info()
→ x 변수 1개, Y 변수(Survived) 골라서 분석
sns.scatterplot(titanic_df, x='Fare', y='Survived')

sns.histplot(titanic_df, x='Fare')

# 데이터 기술 통계를 보는 법(수치형): describe()
titanic_df.describe()

from sklearn.linear_model import LogisticRegression
# X 변수: Fare, Y 변수: Survived
X_1 = titanic_df[['Fare']]
y_true = titanic_df[['Survived']]
model_lor = LogisticRegression()
model_lor.fit(X_1, y_true)
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.01519617]]
바이어스 [-0.94129222]
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)
get_metrics(y_true, y_pred_1)
→ 실행 결과:
정확도 0.6655443322109988
f1-score 0.354978354978355
# 다중로지스틱회귀
# Y: Survived(사망)
# X(수치형): Fare
# X(범주형): Pclass(좌석 등급), Sex
def get_sex(x):
if x == 'female':
return 0
else:
return 1
titanic_df['Sex_en'] = titanic_df['Sex'].apply(get_sex)
X_2 = titanic_df[['Pclass', 'Sex_en', 'Fare']]
y_true = titanic_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)
# X 변수가 Fare
get_metrics(y_true, y_pred_1)
# X 변수가 Fare, Pclass, Sex
get_metrics(y_true, y_pred_2)
→ 실행 결과:
# X 변수가 Fare
정확도 0.6655443322109988
f1-score 0.354978354978355
# X 변수가 Fare, Pclass, Sex
정확도 0.7867564534231201
f1-score 0.7121212121212122
🡆 rule-based와 비교했을 때 정확도는 비슷하지만 f1-score에서 큰 차이가 있음!
model_lor_2.predict_proba(X_2)

sklearn.linear_model.LogisticRegresson사실상 로지스틱회귀는 선형회귀의 아이디어에서 종속 변수(Y)만 가공한 것이기 때문에 장,단점을 똑같이 가져가요.
숨 가쁘게 머신러닝의 방법론 중 회귀와 분류에 대해서 알아보았어요. 한번 정리하는 시간을 가져볼까요?
선형회귀와 로지스틱회귀의 공통점
선형회귀와 로지스틱 분류 차이점
| 선형회귀(회귀) | 로지스틱회귀(분류) | |
|---|---|---|
| Y(종속변수) | 수치형 | 범주형 |
| 평가척도 | Mean Square Error | Accuracy |
| R Square(선형 회귀만) | F1 - score | |
| sklearn 모델 클래스 | sklearn.linear_model.linearRegression | sklearn.linear_model.LogistricRegression |
| sklearn 평가 클래스 | sklearn.metrics.mean_squared_error | sklearn.metrics.accuracy_score |
skelarn.metrics.r2_score | skelearn.metrics.f1_score |
숫자를 예측하는 회귀분석, 범주를 맞추는 분류분석에 대해서 배워보았어요. 그럼 이제 세상에 있는 모든 문제를 다 해결해 볼 수 있을까요?
대답은 No. 실제로 데이터의 모델링은 데이터 사이언스 업무의 아주 일부분이며, 대부분 데이터의 수집과 전처리에 아주 많은 시간을 쏟게 된답니다.
Data science의 기대와 현실

전체 데이터 분석 프로세스

이제 머신러닝의 대표적인 예측과 분류를 배웠으니 데이터 분석 프로세스와 더 많은 알고리즘에 대해서 배워 볼게요.