[혼공머신] CHAPTER 03-3 특성공학과 규제
전 챕터에서 훈련세트보다 테스트세트의 점수가 높아서 이 문제를 해결하기 위해 제곱보다 더 고차항이 필요. -> 특성 공학을 이용해 특성을 많이 만들어내서 고차원에서 선형 회귀가 복잡한 모델을 표현하려고 한다.(?)
다중회귀(multiple regression)
- 여러 개의 특성을 사용한 선형 회귀
- 특성이 많으면 선형 모델이 강력한 성능을 발휘한다
>> 여기에서는 농어의 길이, 높이, 두께 사용!
특성 공학(feature engineering)
- 기존의 특성을 사용해 새로운 특성을 뽑아내는 작업
- ex) 농어 길이 x 농어 높이
- 각 특성을 서로 곱해서 또 다른 특성을 만들어낸다
판다스(pandas)
- 파이썬 데이터 처리를 위한 라이브러리
- 관례적으로 pd라는 명칭으로 임포트
- 3가지의 데이터 구조 사용: 시리즈(1차원배열), 데이터프레임(2차원배열), 패널
- CSV, 텍스트, 엑셀, SQL, HTML, JSON 등 다양한 데이터 파일을 읽고 데이터 프레임을 생성할 수 있다
*시리즈는 인덱스와 값으로 구성
데이터프레임(DataFrame)
- 2차원 리스트를 매개변수로 전달
- 행과 열을 가지는 자료구조로 열, 인덱스, 값으로 구성된다
- CSV파일을 읽어들여 데이터프레임으로 사용
csv파일을 읽을 때는 pandas.read_csv() 함수에 주소를 넣어 읽을 수 있다.
데이터프레임을 만든 다음 to_numpy() 메서드를 사용해 넘파이 배열로 바꾼다.
농어의 무게 데이터를 준비해 perch_full과 perch_weight를 훈련세트와 테스트세트로 나눈다
-> 위 데이터들을 사용해 새로운 특성을 만든다!(특성공학)
변환기(transformer)
- 사이킷런에서 특성을 만들거나 전처리하기 위해 제공하는 클래스
> PolynomialFeatures 클래스 사용법
fit() 메스드로 새롭게 만들 특성 조합을 찾고, transform() 매서드로 실제로 데이터를 변환한다.
1은 y = a * x + b * 1로 선형 방정식의 절편이 항상 값이 1인 특성과 곱해지는 계수라고 볼 수 있다.
즉, [a, b] * [x, 1]
include_bias = False로 절편을 위한 항을 제거하고 특성의 제곱과 특성끼리 곱한 항만 추가시킬 수 있다.
PolynomialFeatures를 사용해 훈련세트에 있는 각 특성을 제곱하여 새로운 특성으로 추가한 훈련데이터를 만들어보자
poly.get_feature_names()를 통해 9개의 특성이 어떻게 만들어졌는지 확인할 수 있다.
'x0'는 첫번째 특성, 'x0^2'은 첫 번째 특성의 제곱, 'x0 x1'은 첫번째특성x두번째특성 이런 식으로 나타낸다
변환된 특성을 사용하여 다중 회귀 모델 훈련
앞서 만든 train_poly를 사용해 모델을 훈련시켜보니
훈련세트에서 높은점수가 나왔다.
농어의 길이, 높이, 두께를 모두 사용했고 각 특성을 제곱하거나 특성끼리 곱해서 다항 특성을 더 추가했다.
-> 특성이 늘어나면 선형 회귀의 능력이 강해진다
테스트세트에 대한 점수는 높아지지 않았지만 농어 길이만 사용했을 때 나타난 과소적합 문제가 나타나지 않았다.
>> 그렇다면 특성을 늘려서 모델을 훈련시켜보자
만들어진 특성의 개수가 55개가 되었다
degree 매개변수를 사용해 고차항의 최대 차수를 5로 지정하여 5제곱까지 특성을 늘려보았다
훈련세트는 거의 완벽에 가까운 점수가 나왔지만
테스트세트의 점수는 음수가 나와버렸다
>> 특성의 개수를 크게 늘리면 선형 모델은 아주 강력해진다. 훈련세트에 대해 거의 완벽하게 학습할 수 있다. 하지만 이런 모델은 훈련세트에 너무 과대적합되어서 테스트세트의 점수가 형편 없어진다.
특성을 줄이고 과대적합을 줄이는 방법을 알아보자
규제(regularization)
- 머신러닝 모델이 훈련세트를 너무 과도하게 학습하지 못하도록 훼방하는 것
- 모델이 훈련세트에 과대적합되지 않도록 만드는 것
- 선형 회귀 모델의 경우 특성에 곱해지는 계수(또는 기울기)의 크기를 작게 만드는 일
왼쪽은 훈련세트를 과도하게 학습했고, 오른쪽은 기울기를 줄여서 보편적인 패턴을 학습하고 있다
55개의 특성으로 훈련한 선형 회귀 모델의 계수를 규제하여 훈련 세트의 점수를 낮추고 테스트 세트의 점수를 높여보자
사이킷런에서 제공하는 StandardScaler 클래스를 사용해 규제를 적용하기 전에 정규화를 시킨다.
StandardScaler 클래스의 객체 ss를 초기화한 후 PolynomialFeatures 클래스로 만든 train_poly를 사용해 이 객체를 훈련한다.
*훈련세트로 학습한 변환기를 사용해 테스트 세트까지 변환해야한다
선형 회귀 모델에 규제를 추가한 모델: 릿지, 라쏘
릿지(ridge)
- 계수를 제곱한 값을 기준으로 규제를 적용
- 모델 객체를 만들고 fit() 메서드에서 훈련하고 score()메서드로 평가
선형 회귀에서는 0.9999에 가깝던 훈련세트의 점수가 조금 낮아졌다
테스트 세트의 점수가 음수에서 정상으로 돌아왔다.
많은 특성(55개)을 사용했음에도 불구하고 훈련세트에 너무 과대적합되지 않아 테스트세트에서도 좋은 성능을 내고 있다.
릿지와 라쏘 모델을 사용할 때 규제의 양을 임의로 조절할 수 있는데, 모델 객체를 만들 때 alpha 매개변수로 규제의 강도를 조절한다.
- alpha 값이 크면 규제 강도가 세지므로 계수 값을 더 줄이고 조금 더 과소적합되도록 유도한다.
- alpha 값이 작으면 계수를 줄이는 역할이 줄어들고 선형회귀 모델과 유사해져서 과대적합될 가능성이 크다.
하이퍼파라미터(hyperparameter)
- alpha 값은 릿지 모델이 학습하는 값이 아니라 사전에 우리가 지정해야하는 값이다
- 사이킷런과 같은 머신러닝 라이브러리에서 하이퍼파라미터는 클래스와 메서드의 매개변수로 표현된다
>> 적절한 alpha값 찾기
여기에선 적절한 alpha 값을 찾기 위해 alpha 값에 대한 R^2값의 그래프를 그려보는 것이다.
훈련세트와 테스트세트의 점수가 가장 가까운 지점이 최적의 alpha 값이 된다.
맷플롯립을 임포트하고 alpha 값을 바꿀 때마다 score() 메서드의 결과를 저장할 리스트를 만든다.
alpha 값을 0.001에서 100까지 10배씩 늘려가며 릿지 회귀 모델을 훈련한 다음 훈련세트와 테스트세트의 점수를 리스트에 저장한다.
alpha 값을 0.001부터 10배씩 늘려서 이대로 그래프를 그리면 왼쪽이 너무 촘촘해져서 alpha_list에 있는 6개의 값을 동일한 간격으로 나타내기 위해 로그함수로 바꾸어 지수로 표현한다.
그래프의 왼쪽에는 훈련세트와 테스트세트의 점수 차이가 아주 큰 모습을 볼 수 있는데 이는 훈련세트에는 잘 맞고 테스트세트에는 형편없는 과대적합의 모습이다.
>> 적절한 alpha 값은 두 그래프가 가장 가깝고 테스트세트의 점수가 가장 높은 -1, 즉 -1 = log(1/10) => 0.1이다!
>> alpha값을 0.1로 하여 최종 모델을 훈련한다.
이 모델은 훈련세트와 테스트세트의 점수가 비슷하게 모두 높고 과대적합과 과소적합 사이에서 균형을 보인다.
라쏘(lasso)
- 계수의 절댓값을 기준으로 규제를 적용
- 계수의 크기를 아예 0으로 만들 수 있다
훈련세트와 테스트세트의 점수도 릿지만큼 괜찮다.
라쏘 모델도 alpha 매개변수로 규제의 강도를 조절해보자
>> 라쏘모델의 최적의 alpha 값 찾기
왼쪽은 과대적합을 보여주고 있고 alpha값이 커질수록 훈련세트와 테스트세트의 점수가 좁혀지고 있다. alpha값이 100일 때는 점수가 크게 떨어진다.(과소적합)
라쏘 모델에서 최적의 alpha 값은 1로 10(log10)이다.
특성을 많이 사용했지만, 릿지와 마찬가지로 라쏘 모델이 과대적합을 잘 억제하고 테스트세트의 성능을 크게 높였다.
라쏘 모델은 계수 값을 아예 0으로 만들 수 있다고 했는데 이는 coef_ 속성에 저장되어 있다. 55개의 특성 중에 15개의 특성만을 사용했음을 알 수 있다. 즉, 라쏘 모델은 중요한 특성이 무엇인지 알 수 있는 장점이 있다
특성이 많은데 그 중 일부분이 중요하다면 라쏘를, 특성의 중요도가 전체적으로 비슷하다면 릿지가 괜찮은 모델을 찾아줄 것이다!