지금, 나는 

Art is anything you can get away with.

Programming/혼공머신 8기.py

혼자 공부하는 머신러닝 + 딥러닝 [2주차]

hyuckee 2022. 7. 13. 21:46
반응형

Chapter 03은 회귀 알고리즘과 모델 규제이다.

지도 알고리즘은 크게 분류와 회귀로 나뉜다.

 

회귀는 통계의 꽃받침이라 할 수 있을 정도로 중요한 토대가 되는 개념이다.

간단히 말하면 변수 사이의 상관관계를 분석하고 예측하는 방법이다.

 

모든 데이터들이 하나의 함수에 적용될 수 없기 때문에

모델 규제를 통해 함수(상관관계)가 보편적인 패턴을 따르도록 제어할 수 있다.


03-1   k-최근접 이웃 회귀

왜인지 모르겠지만 이번에는 농어의 길이, 높이, 두께 데이터로 무게를 예측한다고 한다.

만약 예측의 정확도가 높고 신뢰할만하다면 일의 효율이 엄청나게 좋아질 것 같긴 하다.

 

주인공은 간단히 해결책을 생각해냈다.

이전 단원에서 사용한 k-최근접 이웃 분류 알고리즘을 응용해

주변 데이터의 평균을 내서 무게를 예측한다고 한다.

 

이전에 했던 것처럼 사이킷런을 이용해 훈련 세트와 테스트 세트로 나눈다.

from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(perch_length, perch_weight, random_state=42)

하지만 사이킷런에 사용할 훈련 세트는 2차원 배열이어야 한다.

이전에는 빙어와 도미로 각 열을 맡았지만 이번에는 각 데이터가 1열로 특성 1개만 사용한다.

따라서 .reshape() 메서드로 배열의 크기를 바꿔줘야 한다.

 

단, reshape() 메서드는 지정한 크기가 원본 배열에 있는 원소의 개수와 다르면 에러가 발생한다.

크기에 -1을 지정해 나머지 원소 개수로 편하게 첫 번째 크기를 채울 수 있다.

reshape(-1, 1)

 

이후 과정은 이전에 분류 알고리즘을 사용했던 것과 비슷하다.

사이킷런에서 k-최근접 이웃 회귀 알고리즘 클래스를 사용해 객체를 생성하고

fit() 메서드로 훈련한 후 얼마나 잘 예측하는지 score()로 점수를 확인한다.

 

하지만 여기서 분류와 회귀의 차이가 나타난다.

분류의 경우 해당 점수는 샘플을 정확하게 분류한 개수의 비율 즉, 정확도이다.

회귀에서는 이 점수를 결정계수(R2)라고 부르며 성능을 측정하는 도구로 쓰인다.

 

coefficient of determination

 

타깃이 평균을 따른다면 결정계수는 0에 가까워지고

예측이 타깃에 가까울수록 결정계수는 1에 가까워진다.

1과 가까울수록 좋다.

 

하지만 정확도처럼 R2이 직감적으로 얼마나 좋은지 이해하기는 어렵다.

그래서 타깃과 예측한 값 사이의 절댓값 오차를 평균하여 반환하면

예측이 타깃과 평균적으로 얼마나 다른 지 알 수 있다.

여기서는 결과에서 예측이 평균적으로 19g 정도 타깃값과 다르다는 것을 알 수 있다.

 

모델을 훈련하게 되면 훈련 세트에 잘 맞는 모델이 만들어진다.

 

하지만 만약 테스트 세트에서는 점수가 굉장히 나쁘다면

모델이 훈련 세트에 과대적합되었다고 말한다.

 

반대로 훈련 세트보다 테스트 세트의 점수가 높거나

두 점수가 모두 낮은 경우 훈련 세트에 과소적합되었다고 말한다.

즉, 대표적으로 모델이 너무 단순하거나 각 세트의 크기가 매우 작아 특징을 따르지 못한 경우이다.

 

과소적합인 경우 모델을 조금 더 복잡하게 만들면 된다.

훈련 세트에 더 잘 맞게 만들면 점수가 낮아진다.

k-최근접 이웃 알고리즘에서는 이웃의 개수를 조절하는데 이웃의 개수를 줄이면 훈련 세트에 있는 국지적인 패턴에 민감해지고, 이웃의 개수를 늘리면 데이터 전반에 있는 일반적인 패턴을 따를 것이다.

모델을 규제하면 훈련과 테스트 점수 차이를 줄일 수 있다.

 

모델이 이웃의 개수가 클수록 일반적인 패턴을 따른다는 것을 다음과 같이 시각적으로 볼 수 있다. #03-1의 2번 문제

산점도에 모델이 만든 추세선을 넣는 코드


03-2   선형 회귀

k-최근접 이웃은 한계가 있었다.

가지고 있는 데이터가 충분하지 않다면 모델은 샘플들의 무게를 평균하기에 이상한 결과가 나올 수 있다.

(농어가 아무리 커도 무게가 더 늘어나지 않는다)

시간과 환경이 변화하면서 데이터도 바뀌기 때문에 주기적으로 새로운 훈련 데이터로 모델을 다시 훈련해야 하지만 이 모델은 동떨어진 데이터에 대해 추세를 제대로 예측할 수 없으므로 다른 알고리즘이 필요하다.

 

여기서는 비교적 간단하고 성능이 뛰어나 널리 사용되는 대표적인 회귀 알고리즘인 선형 회귀를 이용한다.

사이킷런의 skleanr.linear_model 패키지 아래에 LinearRegression 클래스로 선형 회귀 알고리즘을 구현할 수 있다.

다음은 가장 간단한 직선의 방정식으로 구현한 모델이다.

 

기울기(계수)와 절편이 직선을 결정하듯 LinearRegression 클래스를 사용하면 알아서 계수와 가중치(절편)를 학습한다.

여기서 계수(coef_)와 가중치(intercept_)를 머신러닝 알고리즘이 찾은 값이라는 의미로 모델 파라미터라고 부른다.

 

그래프를 보면 느껴지듯 뭔가 애매하게 맞지 않는 느낌이 있다.

(자칫 잘못하면 무게가 음수로 나올지도..?)

실제로 상관계수를 구해보면 과소적합되어 있음을 알 수 있다. 따라서 모델을 복잡하게 만들어야 한다.


다항 회귀

산점도를 보면 알 수 있듯 일직선이 아니라 조금 구부러진 곡선처럼 분포되어 있다는 것을 알 수 있다.

따라서 최적의 직선이 아닌 최적의 곡선을 찾아보려 한다.

길이 요소를 제곱한 요소를 추가하면 2차 방정식을 만들 수 있다.

 

이런 식으로 요소를 추가하면 비선형(non-linear)이지만 이를 다른 변수로 치환하게 된다면 역시 선형 관계로 표현할 수 있다. 이런 방정식을 다항식이라 부르며 다항식을 사용한 선형 회귀를 다항 회귀라고 부른다.

 

LinearRegression 클래스에서는 항에 대한 요소가 추가되면 그것에 대한 가중치 역시 리스트 형식으로 추가된다.

이렇게 만든 2차 방정식을 각 구간으로 짧은 직선을 이어서 그리면 마치 곡선처럼 표현할 수 있다.

 

상관계수

훈련 세트와 테스트 세트의 R2 점수를 평가했을 때 많이 비슷하지만 아직 과소적합이 남아 있는 것 같다.


03-3   특성 공학과 규제

여전히 테스트 세트의 점수가 높기에 찜찜한 나머지 주인공은 선배에게 도움을 청한다.
이 문제를 해결하기 위해 제곱보다 더 고차항을 넣어야 할 것 같은데
얼마나 더 고차항을 넣어야 할지 모르고 수동으로 이렇게 고차항을 넣기도 힘들기 때문이다.

선배는 '선형회귀는 특성이 많을수록 엄청난 효과를 낸다'
받은 데이터를 모두 사용해 다항 회귀에 함께 적용해 보라고 했다.

 

2절에서는 하나의 특성을 사용하여 선형 회귀 모델을 훈련시켰다.

여러 개의 특성을 사용한 선형 회귀를 다중 회귀라고 부른다.

(특성이 1개이면 2차원 평면 상에서의 직선을, 2개이면 3차원 공간 상에서 평면을 나타낸다.)

 

이 예제에서는 길이, 높이, 두께를 사용하며 이전 절에서처럼 3개의 특성을 각각 제곱하여 추가하고

거기다가 각 특성을 서로 곱해서 또 다른 특성을 만들어 사용할 것이다.

이렇게 기존의 특성을 사용해 새로운 특성을 뽑아내는 작업을 특성 공학이라고 부른다.


특성이 3개로 늘어나 데이터의 양이 많아졌고 복사해 붙여 넣는 것도 번거롭다.

그래서 유명한 데이터 분석 라이브러리인 판다스를 이용해 데이터를 바로 다운로드하여 사용할 것이다.

판다스는 데이터프레임이라는 데이터 구조를 사용하는데 이를 만들기 위해 보통 CSV 파일을 많이 사용한다.

 

다음과 같이 pd.read_csv() 메서드로 데이터프레임을 만들고 to_numpy() 메서드로 넘파이 배열로 바꿀 수 있다.

pandas

 

사이킷런은 특성을 만들거나 전처리하기 위한 다양한 클래스를 제공한다. 이런 클래스를 변환기라고 부른다.

여기서 각 특성들을 쉽게 만들기 위해 PolynomialFeatures 클래스를 사용할 것이다.

예시로 2개의 특성 2와 3으로 이루어진 샘플을 적용하면 다음과 같이 2, 3, 22, 2 x 3, 32이 나온다.

특성 만들기

1은 절편항을 위해서 만들어진 것이며 절편을 안 쓴다면 include_bias=False 매개변수로 없앨 수 있다.

 

우리는 다음과 같이 9개의 특성을 만들어서 사용할 것이다. 각 특성과, 각 특성의 제곱, 두 특성끼리의 곱이다.

특성 조합 출력

 

다중 회귀 모델을 훈련하는 것은 선형 회귀 모델을 훈련하는 것과 같다.

차이점은 그저 여러 개의 특성을 사용하여 선형 회귀를 수행하는 것뿐이다.

 

훈련 및 테스트

훈련 점수도 높고 테스트 점수도 양호하며 과소적합이 해소됐다.

이로써 특성이 늘어나면 선형 회귀의 능력은 매우 강하다는 것을 알 수 있다.


만약 특성을 더 추가하면 어떻게 될까? 더 정교한 모델이 나오지 않을까?

PolynomialFeatures 클래스의 degree 매개변수를 설정하면 고차항의 최대 차수를 지정할 수 있고

이를 통해 만들 특성의 개수를 조작할 수 있다.

고차 함수

 

샘플은 42개인데 반면, 특성이 55개가 되었고 훈련 점수는 매우 높다.

반면 테스트 점수는 음수가 나왔다. 이는 훈련 세트에 과대적합되었기 때문이다.

 

이번에는 과대적합을 해결해보자!

선형 회귀 모델의 경우 특성에 곱해지는 계수의 크기를 조절(규제)해 과대적합을 해소할 수 있다.

그것보다 더 근본적으로, 2장에서 보았듯 특성의 스케일이 정규화되지 않으면 곱해지는 계수 값도 차이 난다.

따라서 공정히 제어하기 위해 정규화를 진행하고 규제를 적용해야 한다.

 

2장에서는 평균과 표준편차를 직접 구해 표준점수로 반환했지만, 여기서는 사이킷런의 StandardScaler 클래스(변환기)를 이용한다.

(StandardScaler 클래스를 이용하면 손쉽게 55개의 특성에 맞춰 각각의 평균과 표준편차를 만들어 mean_, scale_ 속성에 저장된다.)


선형 회귀 모델에 규제를 추가한 모델을 릿지와 라쏘라고 부른다.

두 모델은 규제를 가하는 방식이 다른데,

릿지는 계수를 제곱한 값을 기준으로 규제를 적용하고,

라쏘는 계수의 절댓값을 기준으로 규제를 적용한다.

일반적으로 릿지를 더 선호한다고 하며, 두 알고리즘 모두 계수의 크기를 줄이지만 라쏘는 아예 0으로도 만들 수 있다고 한다.

 

 

Ridge & Lasso

릿지와 라쏘 모두 sklearn.linear_model 패키지 안에 있고 지금까지 해왔듯 이 모델들도 훈련하고 평가까지 모든 과정이 동일하게 진행된다.

그냥 사용해도 되지만 이 모델들 역시 손수 규제의 양을 임의로 조절할 수 있다.

 

모델 객체를 만들 때 alpha 매개변수의 값을 조절해 값이 크면 규제 강도가 세져 계수값을 더 줄이고 과소적합을 유도한다.

(alpha 값처럼 머신러닝 모델이 학습할 수 없고 사전에 사람이 알려줘야 하는 파라미터를 하이퍼파라미터라고 부른다)

 

적절한 alpha 값을 찾는 한 방법은 alpha 값에 대한 R2 값을 이용해 훈련 세트와 테스트 세트의 점수가 가장 가까운 지점을 찾는 것이다.

 

여기까지는 릿지와 라쏘 모두 절차가 동일하다.

차이점은 라쏘의 경우, 최적의 계수를 찾기 위해 반복적인 계산을 수행한다는 점이다.

또, 라쏘는 앞서 설명했듯이 계수를 0으로 만들 수 있다.

이런 특징 때문에 라쏘 모델을 유용한 특성을 골라내는 용도로도 사용할 수 있다.


Chapter 03 정리

03-1
농어 무게를 예측하기 위해 k-최근접 이웃 회귀 알고리즘을 사용했다.
그 과정에서 결정계수 R2가 무엇인지 알게 되고 그에 따라 과대적합/과소적합을 규정했다.
03-2
k-최근접 이웃 회귀 알고리즘이 일정 범위 외의 예측에서 허점을 보였고 선형 회귀를 도입하게 된다.
1차 방정식은 너무나 직선적이라 과소적합을 보였다.
이를 보완하기 위해 제곱 요소를 추가해 곡선 형태인 다항 회귀를 사용했지만 아직 과소적합..
03-3
모든 데이터를 사용하는 다중 회귀를 이용하기로 하며 이를 위해 특성 공학 작업을 시행한다.
과소적합을 해소했는데, 왜인지 모르게 특성을 더 추가해보고 과대적합을 경험한다.
이를 해소하기 위해 정규화와 규제 작업을 거치게 된다.
그 과정에서 규제 모델에 릿지와 라쏘가 있음을 알게 되고 각각의 차이점을 이해하게 된다.
그리고 이 모델들을 이용해 과대적합을 제어할 수 있었다.

1주차에는 분명 할 만했는데 왜 벌써부터 힘겹지..?

간단하고 필수적인 내용을 시작으로 점점 딥하게 들어가니까

이제 정신 안 잡고 있으면 활자 속에서 미아가 될 지도..

물론 이정도는 수심 2미터 정도겠지?

어디까지 이해하고 받아들여서 활용할 수 있을지 기대된다.

728x90