👨🏫 정규화 대해 배우기.
지난 시간에 이어서 계속 정확도를 높이기 위한 방법에 대해서 공부하는 중.
그중 하나로 정규화를 생각해 볼수 있다.
저저번 시간에 배운 정규분포화랑은 다른 개념이다.
규제, 제약으로서의 정규화를 말함
우리가 model 이라는 어떤 모델을 구축했다고 가정하겠습니다. score 함수는 x 데이터와 y 데이터를 넣으면 정확도를 자동으로 계산해주는 함수입니다.
👨🏫 지금까지는 오차 일부로 함수 만들어서 계산했지만 사실은
.score라고 편하게, 좀더 직관적인 정확도를 계산할 수 있다.
테스트 데이터에 대한 정확도, 훈련 데이터에 대한 정확도를 각각 계산하였다고 가정해보겠습니다.
print(model.score(x_test, y_test))
print(model.score(x_train, y_train))
>>>>>>>>>>>>>>>> 실행>>>>>>>>>>>>>
0.8669201520912547
0.9841571609632446
👨🏫 여기서 그런데 훈련데이터는 정확도 100%나와야 하는 거 아닌지 의문이 들수 있는데, 왜냐하면 기계한테 학습하라고 x와 y_data를 다 알려줬으니깐. 그런데 인간이랑 똑같다고 생각하면 된다. 우리도 공부한거 까먹기도 하니깐.
그래서 이렇게 기계한테 학습시키는 과정에서 처음에는 그 값에 맞게 학습하다가 나중에는 너무 많이 학습하면서 이전에 넣었던 data들에 대해서는 조금 오차가 더 발생하게 되기도 하고 그런 식으로 좀 달라지기도 함.
- 우리가 실제 값이라고 알려줬다 하더라도 기계는 예측을 다르게 할 수도 있을 것이라는 것.
98%는 높은 편에 속함.
그런데 정확도를 보았더니, 테스트 데이터에 대한 예측 성능은 86%, 훈련 데이터에 대한 예측 성능은 98%가 나왔습니다.
이는 모델이 훈련 데이터에 대해서 너무 과하게 적합되었다는 것을 의미합니다. 이를 과적합 이라고 합니다.
👨🏫 훈련 데이터에 너무 집착한 나머지 새로운 데이터가 들어왔을때 거기에 대해서는 예측을 정확하게 못함.
과적합이라는 개념을 사람에 비유해보겠습니다. 어떤 사람이 평생동안 빨간 사과만 봐왔다고 가정해봅시다. 그러면 그 사람은 또 다른 빨간 사과를 보고, '이것은 사과다' 라고 판단해낼 수 있을 것입니다.
그런데 만약 그 사람에게 초록 사과를 보여준다면, '이것은 사과다' 라고 판단해낼 수 있을까요? 지금까지 학습했던 것은 사과는 빨간색이라는 사실인데, 이러한 사실과는 다르게 초록 사과라는 새로운 데이터가 들어온다면 올바르게 판단해낼 수 없을 것입니다.
즉, 훈련 데이터 (학습 데이터) 를 너무 과하게 학습을 해서, 훈련 데이터에 대해서는 정확하게 판단을 하는 반면, 훈련 데이터와 별개의 데이터가 들어왔을 때는 올바르지 못하게 판단을 하게 되는 것을 과적합 이라고 합니다!
머신 러닝의 궁극적인 목표는 아직 학습하지 않은 데이터, 테스트 데이터에 대한 정확도를 높이는 것입니다. 그런데 학습 데이터에 대한 정확도가 테스트 데이터에 비해 지나치게 높다면, 과적합 상태를 해결하여 학습 데이터에 대한 정확도는 다소 낮추고, 테스트 데이터에 대한 정확도를 올리는 방향으로 모델을 수정해야 합니다. -> 정규화의 목표
정규화는 모델의 파라미터 (가중치) 에 대한 제약을 통해서 과적합을 해결하는 방식입니다. 우리가 위에서 봤던 정규분포화 (로그 변환) 랑은 다른 개념이라는 사실에 주의해주세요!
가중치에 대한 제약이라는 것이 무슨 말일까요?
여기서 w 를 가중치라고 한다는 건 기억나시죠? 위 식에서 x1 이 집의 층수라면, w1 는 집의 층수에 대한 가중치인 것입니다.
위와 같은 식이 있을 때, 모델에 큰 영향을 주지 않는 특성들에 대해서는 가중치를 작게 만드는 것을 정규화 (규제, 제약) 라고 말을 합니다. 특성들의 영향력을 줄여서, 특정한 특성만 보고 결과를 판단하지 않도록 예방하는 것이죠!
그러니까 아까 위의 빨간 사과를 예로 들면, 빨간색이라는 특성만 보고 결과를 판단하지 않도록, 빨간색에 대한 가중치를 줄여서 초록 사과에 대해서도 사과라고 판단할 수 있도록 하는 것입니다!
규제의 방식에는 L1 규제, L2 규제가 있는데, 각 방식은 규제를 하는 기준이 조금 다릅니다.
L1 규제의 경우, 각 가중치들의 절대값 합계를 고려해서 최적화를 진행하고,L2 규제의 경우, 각 가중치들의 제곱수의 합계를 고려해서 최적화를 진행합니다.최적화는 실제값과 오차를 줄이기 위한 과정을 지칭하는 말이라는 것 기억하시나요?
L1 규제는 각 가중치들의 절대값 합계를 최대한 줄여가면서 실제값과 오차를 줄여나가는 방식인 것이고, L2 규제는 각 가중치들의 제곱수의 합계를 최대한 줄여가면서 실제값과 오차를 줄여나가는 방식인 것입니다!
👨🏫 엄청나게 줄어드는 것은 아님. 특성이 없어질 정도로 줄어들지는 않지만 그 규제의 정도는 우리가 판단해야 함. 이만큼 규제해줘, 조금만 규제해줘 라고 우리가 입력해야 함. 진짜 많이 규제해버리면 정확도가 아예 안나옴. 가중치가 없어져버리니깐.
적당한 선. 규제를 해서 정확도가 올라갈만한 그 선을 찾는 것이 굉장히 중요하다.
릿지 회귀 (Ridge Regression) 은 L2 규제를 사용해서 과적합을 예방하면서 예측 모델을 만들어나가는 회귀 방식입니다.
위에서 진행했던 선형 회귀 모델 구축을 위한 과정을 한번 요약해보고, 릿지 회귀를 적용해서 테스트 데이터와 훈련 데이터에 대한 정확도 값이 선형 회귀와 비교했을 때 어떻게 달라지는지를 한번 보겠습니다.
위에서 진행했던 선형 회귀 모델 구축을 위한 과정을 한번 요약해보고, 릿지 회귀를 적용해서 테스트 데이터와 훈련 데이터에 대한 정확도 값이 선형 회귀와 비교했을 때 어떻게 달라지는지를 한번 보겠습니다.
코드스니펫] 앞서 진행했던 데이터 불러오기 ~ 선형회귀 과정 요약
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
# 데이터 불러오기
train = pd.read_csv('https://raw.githubusercontent.com/jesford/bike-sharing/master/train.csv', parse_dates=["datetime"])
# year, month, day, hour 생성
train["year"] = train["datetime"].dt.year
train["month"] = train["datetime"].dt.month
train["day"] = train["datetime"].dt.day
train["hour"] = train["datetime"].dt.hour
# 필요없는 열 삭제
drop_columns = ['datetime', 'casual', 'registered']
train.drop(drop_columns, axis=1, inplace=True)
# x, y 분리하기
y_target = train['count']
x_features = train.drop(['count'], axis=1, inplace=False)
# 범주형 변수 활용
x_features_dummy = pd.get_dummies(x_features,
columns = ['year', 'month', 'day', 'hour', 'holiday', 'workingday', 'season', 'weather'])
# 훈련, 테스트 데이터 분리
x_train, x_test, y_train, y_test = train_test_split(x_features_dummy, y_target, test_size = .3, random_state=777)
------------------------------------------------
# 선형회귀 모델에 학습
lr = LinearRegression()
lr.fit(x_train, y_train)
# 정확도 출력
print(lr.score(x_test, y_test))
print(lr.score(x_train, y_train))
>>>>>>>>>>>>>>>>>>실행 >>>>>>>>>>>>>>>>>>>>..
0.6835371635628911
0.6982715399999174
👨🏫 이렇게 마지막에 학습한 후에 정확도 출력하는 부분만 좀 바뀌었다.
----------- 규제 하기 전에는 저렇게 나왔다.---------------------------
현재 데이터의 경우, 훈련 데이터 정확도와 테스트 데이터 정확도 간의 차이가 크지 않기 때문에, 애초에 과적합이 일어났다고 볼 수 없습니다.
그래서 규제를 적용해도 큰 변화가 없을 수도 있습니다. 그럼에도 규제라는 개념에 대한 이해는 매우 중요하기 때문에, 어떻게 사용할 수 있는지에 대해서 같이 실습을 진행해보겠습니다!
릿지 회귀의 경우, 아래처럼 사용할 수 있습니다. 여기서 alpha는 규제의 강도를 말합니다. 값이 커지면 커질수록, 가중치에 대한 규제가 심해지는 것입니다!
# 릿지회귀 함수 임포트, 학습 진행
from sklearn.linear_model import Ridge
rg = Ridge(alpha=2.5)
rg.fit(x_train, y_train)
print(rg.score(x_test, y_test))
print(rg.score(x_train, y_train))
>>>>>>>>>>>>>>>>>>>>> 정확도 계산 실행 >>>>>>>>>>>>
0.6835790109552676
0.698191927089896
👨🏫 아주 미세하게 상승함. 왜냐하면 선형 회귀 모델에서부터 사실 과적합이 없었다. 그래서 차이가 크지는 않음. 그래서 여기서 규제를 하더라도 정확도가 막 많이 올라가지는 않는다.
테스트 데이터의 정확도가 미세하게 상승했고, 훈련 데이터의 정확도가 미세하게 줄어든 것을 확인할 수 있습니다.
[참고] - alpha=10 했을 경우,
# 릿지회귀 함수 임포트, 학습 진행
from sklearn.linear_model import Ridge
rg = Ridge(alpha=10)
rg.fit(x_train, y_train)
print(rg.score(x_test, y_test))
print(rg.score(x_train, y_train))
>>>>>>>>>>>>>>>>>>>>> 정확도 계산 실행 >>>>>>>>>>>>
0.6832738935878208
0.6976319366978145
[참고] - alpha=100 했을 경우,
# 릿지회귀 함수 임포트, 학습 진행
from sklearn.linear_model import Ridge
rg = Ridge(alpha=100)
rg.fit(x_train, y_train)
print(rg.score(x_test, y_test))
print(rg.score(x_train, y_train))
>>>>>>>>>>>>>>>>>>>>> 정확도 계산 실행 >>>>>>>>>>>>
0.6572638754116629
0.6691073733036487
👨🏫 정확도가 두개 다 내려간다. 규제가 적당하게 이루어져야만 정확도가 올라가지 너무 과해버리거나 너무 적어버리면 오히려 정확도가 감소하는 그런 현상이 생긴다. 그래서 제가 찾았던 값은 2.5라는 값이구요.
라쏘 회귀 (Lasso Regression) 은 L1 규제를 사용해서 과적합을 예방하면서 예측 모델을 만들어나가는 회귀 방식입니다.
라쏘 회귀는 아래처럼 사용할 수 있습니다. 여기서 alpha는 릿지 회귀 때와 마찬가지로 규제의 강도를 말합니다. 값이 커지면 커질수록, 가중치에 대한 규제가 심해지는 것입니다!
# 라쏘회귀 함수 임포트, 학습 진행
from sklearn.linear_model import Lasso
ls = Lasso(alpha=0.1)
ls.fit(x_train, y_train)
이제 정확도를 출력해보겠습니다.
print(ls.score(x_test, y_test))
print(ls.score(x_train, y_train))
>>>>>>>>>>>>결과 >>>>>>>>>>>>>>>>>>>
0.683608634543128
0.6977614136007022
👨🏫 가장 테스트 정확도가 높다. 진짜 미세하기는 하지만 이것도 어떻게 보면 성과이니깐. 68.35% 였다가 68.36% 까지 올랐습니다. 어쨌든 규제에 대한 효과라고 볼수 있다.
릿지 회귀 때와 마찬가지로, 테스트 데이터의 정확도가 미세하게 상승했고, 훈련 데이터의 정확도가 미세하게 줄어든 것을 확인할 수 있습니다.
💡 현재 데이터의 경우, 훈련 데이터 정확도와 테스트 데이터 정확도 간의 차이가 크지 않기 때문에, 애초에 과적합이 일어났다고 볼 수 없습니다. 그래서 규제를 적용했을 때 아주 미세하게 정확도가 달라지고 있습니다.
5주차에는 과적합이 일어난 데이터에 대해서 또 다른 방식으로 규제를 적용해볼 예정이니, 그때 한번 더 정확도를 비교해보시면 좋을 것 같습니다.