KT AIVLE School/[TIL] AIVLE School 당일 복습

[TIL] [KT AIVLE School] KT 에이블스쿨 6기(DX 트랙) 7주차 2일. 머신러닝 - 지도학습(2). 분류 평가지표 심화, Linear 모델

guoyee94 2024. 10. 15. 23:58

 

머신러닝 2일차.

 

대충 그런게 있다-라고 알고 애써 멀리해 왔던 모델링 수학이 본격적으로 시작되었다.

 

그야말로 하늘은 높고 공부할 건 늘어나는 가을이다.

 

 

 

 

 

 


 

 

 

 

 

 

 

모델 평가지표

 

지난 포스팅(https://guoyee94.tistory.com/40)에서 다룬 모델들의 평가지표.

 

아무래도 좀 모자란 부분이 보이니까 한번만 더 짚는다.

 

다시 한 번 머신러닝의 평가지표를 살펴 보자.

 

 

  • 회귀 문제
회귀 MAE(Mean Absolute Error) 평균절대오차
Σ(오차의 절댓값) ÷ 데이터 수
MSE보다 직관적, 이상치에 민감하지 않음
MSE(Mean Squared Error) 평균제곱오차
Σ(오차의 제곱) ÷ 데이터 수
MAE보다 비직관적, 이상치에 민감함
RMSE(Root Mean Squared Error)   MSE (= MSE ^ 0.5)
MAE보다 비교적 이상치에 민감함
MSE보다 비교적 직관적
MAPE(Mean Absolute Percentage Error) MAE를 %로 나타낸 것
R² Score(결정 계수) MSE의 표준화된 버전
오차 자체는 작을수록 성능이 좋으므로(= 직관성이 떨어지므로),
성능 자체를 점수화한 것.
높을수록 성능이 좋다.

 

<추가 개념>

 

SST
(Sum Squared Total)
실젯값과 평균의 오차
모델은 평균보다 나아야 하므로, 허용되는 오차의 최대치
SSR
(Sum Squared Regression)
평균과 회귀식의 차이
회귀식이 평균에 비해 실제값과 얼마나 더 가까운지
 = 클수록 성능이 높다.
SSE
(Sum Squared Error)
실젯값과 회귀식의 오차
모델링 이후에도 잡아내지 못한 오차.
 = 작을수록 성능이 높다.

 

 

따라서, R² 스코어는 다음과 같이 구한다.

R² 스코어 : 회귀선이 얼마나 실젯값 쪽으로 붙어 있는지를 나타낸다..

 

 

SSR은 클수록 평균보다 실젯값에 더 가깝다는 뜻이므로 클수록 좋고,

SSE는 회귀선이 실젯값에서 떨어진 정도이므로 작을수록 좋다.

 

따라서 R² 스코어는 클수록 좋다.

 


 

  • 분류 문제

분류 Accuracy
정확도
TP + TN / TP + TN + FP + FN
양성을 양성으로 판단한 정도 + 음성을 음성으로 판단한 정도
판단이 맞은 정도를 복합적으로 나타내는 대표적 지표
불균형한 데이터에서는 '정확도=성능'을 보장할 수 없음
Precision
정밀도
TP / TP + FP
예측 관점
양성으로 예측한 것 중에 진짜 양성인 것의 비율
음성을 양성으로 오해하면 안되는 모델에서 중요한 지표
Recall
재현율
민감도
TP / TP + FN
실제 관점
진짜 양성 중에서 양성이라고 예측한 것의 비율
양성을 놓치면 안되는 모델에서 중요한 지표
Specificity
특이도
TN / TN + FP
 
실제 음성 중에서 음성이라고 예측한 것의 비율
F1 Score 정밀도와 민감도의 조화평균
 = {(2 * 정밀도 * 민감도) / (정밀도 + 민감도)}
정밀도와 민감도의 절충

 

<추가 개념>

혼동행렬에서의 Precision 계산(좌)와 Recall 계산(우)의 차이. 예측 관점은 세로고, 현실 관점은 가로다.

 

Accuracy는 그냥 전체 중에 예측이 맞은 데이터의 수를 세면 되기에 상관 없지만,

 

PrecisionRecall, 그리고 이 둘을 기반으로 하는 F1-Score는 위 그림처럼 이진 분류에 기초한다.

 

다중 분류라면,

분모(Presicion : 양성으로 예측한 값 전부, Recall : 실제 양성인 값 전부)를 구할 때

더하는 항의 개수가 더 많겠지?

 

따라서 코딩 시 파라미터를 조절해 줘야 한다.

# 다중 분류 문제일 때 average=None 파라미터 추가
precision_score(y_test, y_pred, average=None)
recall_score(y_test, y_pred, average=None)
f1_score(y_test, y_pred, average=None)

 

average 파라미터는 기본적으로 이진 분류인 'binary'로 되어 있다.

 

그래서 이진 분류 문제에서는 안 넣어도 상관 없지만,

다중 분류 문제에서는 에러를 뱉어낸다.

 

 

 

 

 


 

 

 

 

 

 

 

기본 알고리즘(1). Linear Regression

 

이제 기초적인 머신러닝 flow는 다 배웠다.

 

그러나 아직 알고리즘의 원리는 하나도 모르는 상태.

 

지금부터는 각 알고리즘들의 원리를 톺아 나간다.

 

첫번째로 알아볼 알고리즘은 Linear Regression(선형 회귀, 線形回歸)이다.

 

선형 관계를 보이는 자료의 회귀선(y = ax + b)을 그리기 위한 기울기(a)와 절편(b)을 구한다.

 

회귀선은 y = b + ax에서 b를 일반적으로  w0 (y절편 / 편향)이라고 표기하며

a는 w1(기울기 / 가중치)로 표기한다.

 

Linear Regression 알고리즘의 목적은 적절한 편향과 가중치를 찾아

오차의 합(일반적으로 MAE나 MSE)이 최소가 되는 직선을 그리는 것을 목표로 한다.

 

이때 회귀선은 결국 feature(x)와 target(y)의 관계를 나타내는 셈인데...

 

그말인즉슨 feature의 수만큼 회귀선을 긋는 차원이 늘어난다.

 

인간은 대체로 3차원까지만 고려 가능하므로

상상력이라는 그래픽카드로는 고작 feature 두 개밖에 설정하지 못한다.

당신이 틀렸어 셸든 쿠퍼

 

그래서, 위처럼 2차원 그래프로 나타낼 수 있는,

다시말해 독립변수(feature) 개수가 하나인 회귀분석을 단순 회귀,

그 이상이면 다중 회귀라고 부른다.

 

컴퓨터는 인간과 달리 아무리 차원이 늘어나도 연산가능하다.

 

다중회귀의 회귀식은 각 독립변수의 가중치와, 하나의 편향을 찾는 과정이다.

※ 가중치(기울기)는 독립변수마다 다르지만,
편향(절편)은 애초에 종속변수(target)의 기본값을 나타내는 지표이다.
따라서 다중회귀에서도 편향은 하나다.

 

따라서 다중 회귀의 회귀식은 아래와 같다.

 

여하튼 간에, 데이터 분석을 하는 우리에게 중요한 것은 이 알고리즘의 성능이 어떤가 하는 것이다.

 

따라서 지금까지 그랬듯, 아래와 같은 방법으로 알고리즘 성능을 평가할 수 있다.

 

# fit - predict가 완료된 이후
# 공통
from sklearn.metrics import mean_absolute_error

print("MAE: ", mean_absolute_error(y_test, y_pred))
print("R2: ", model.score(x_test, y_test))

# 단순회귀분석에서 회귀계수 확인
print(model.coef_)
print(model.intercept_)

# 다중회귀분석에서 회귀계수 확인
print(list(x_train))
print(model.coef_)
print(model.intercept_)

 

평가지표 써서 보는 건 뭐... 회귀 문제니까 당연히 MAE, MSE, R2 등을 이용한다.

 

Linear Regrssion의 핵심은 회귀식이므로 회귀계수(가중치와 편향)을 보아야 하는데,

아까 말했듯 편향은 늘 하나지만 가중치는 다중회귀분석에서 여러개다.

 

따라서 편향을 나타내는 intercept_는 값을 하나만 반환하고,

가중치를 나타내는 coef_는 리스트 형태로 값을 반환한다.

 

다중회귀분석 시 이 가중치들에 대응되는 feature들을 알기 위해 x_train의 원소들을 함께 출력한다.

 

x_train과 coef_가 1대 1 대응되는 것을 활용해 pd.DataFrame()으로 만들어 시각화에도 쓸 수 있다.

# 가중치 시각화
tmp = pd.DataFrame()
tmp['feature'] = list(x)
tmp['weight'] = model.coef_

# 정렬
tmp.sort_values(by='weight', ascending=True, inplace=True)
tmp.reset_index()

# 시각화
plt.figure(figsize=(3, 5))
plt.barh(tmp['feature'], tmp['weight'])
plt.show()

 

그럼 아래와 같이, 가중치의 크기별로 feature들을 시각화할 수 있다.

 

가중치가 크다는건, 일반적으로는 target과 관계가 깊다는 것을 의미하니 좋은 방법.