archive
[교재] 3. 회귀 알고리즘과 모델 규제 (1) 본문
3-1 K-최근접 이웃 회귀
1. K-최근접 이웃 회귀
- 지도 학습 알고리즘은 크게 분류와 회귀로 나뉜다.
- 분류 : 주어진 샘플을 몇 개의 클래스 중 하나로 분류하는 문제 (출력값 : c1, c2...)
- 회귀 : 클래스 중 하나로 분류하는 것이 아니라 임의의 어떤 숫자를 예측하는 것 (출력값 : y값)
- 즉, 회귀는 정해진 클래스가 없고 임의의 수치를 출력한다.
- k-최근접 이웃 알고리즘을 적용
- k-최근접 이웃 분류 알고리즘 : 예측하려는 샘플에서 가까운 샘플 k개를 선택하고, 이 샘플들의 클래스를 확인하여 다수 클래스를 새로운 샘플의 클래스로 예측하는 방법
- k-최근접 이웃 회귀 알고리즘 : 예측하려는 샘플에 가장 가까운 샘플 k개를 선택하고, 수치들의 평균을 구하여 임의의 수치인 평균을 반환한다.
2. 데이터 준비
- 주어진 데이터를 시각화하여 산점도를 파악 -> 농어의 길이가 커짐에 따라 무게도 늘어남
- 사이킷런에서 사용할 훈련 세트는 2차원 배열이어야 함, 따라서 1차원 배열을 2차원 배열로 변환해야한다
-2장에서는 2개의 특성을 사용했기 때문에 자연스럽게 열이 2개인 2차원 배열을 사용하였으나, 이번 예제에서는 특성을 1개만 사용하므로 수동으로 2차원 배열을 만들어야 한다.
-넘파이 배열에서 크기를 바꿀 수 있는 reshape() 메서드를 지원한다.
3. 결정계수 (R^2)
- 사이킷런에서 k-최근접 이웃 회귀 알고리즘을 구현한 클래스는 KNeighborsRegressor이다
- 객체를 생성하고 fit() 메서드로 회귀 모델을 훈련한다
from sklearn.neighbors import KNeighborsRegressor
knr = KNeighborsRegressor()
knr.fit(train_input, train_target)
print(knr.score(test_input, test_target))
>> 0.992809406101064
- 분류의 경우 score() 메소드를 출력되는 숫자는 테스트 세트에 있는 샘플을 정확하게 분류한 개수의 비율이다 (정확도)
- 반면 회귀에서는 정확한 숫자를 맞춘다는 것은 거의 불가능하다
- 따라서 회귀는 조금 다른 값으로 평가하는데, 이 점수를 결정계수 (coefficient of determination, R^2)이라고 부른다
- 각 샘플의 타깃과 예측한 값의 차이를 제곱하여 더한다. (LSE)
- 그 다음, 타깃과 타깃 평균의 차이를 제곱하여 더한 값으로 나눈다
-타깃의 평균정도를 예측하는 수준이라면 R^2는 0에 가까워지고, 예측이 타깃에 아주 가까워지면 1에 가까운 값이 된다
- 좋은 지표이나, 정확도와 같이 직관적으로 얼마나 성능이 좋은지 이해하기는 어렵다.
- 사이킷런은 sklearn.metrics 패키지 아래 여러 가지 측정 도구를 제공하는데, 이 중에서 mean_absolute_error는 타깃과 예측의 절댓값 오차를 평균하여 반환한다.
from sklearn.metrics import mean_absolute_error
test_prediction = knr.predict(test_input)
mae = mean_absolute_error(test_target, test_prediction)
print(mae)
>> 19.157142857142862
- 결과에서 예측이 평균적으로 19g정도 타깃값과 다르다는 것을 알 수 있다
4. 과대적합과 과소적합
- 과대적합 (Overfitting) : 훈련세트에만 잘 맞는 모델이라 테스트세트와 나중에 실전에 투입되어 새로운 샘플에 대한 예측을 만들 때 잘 동작하지 않는 경우
- 과소적합 (Underfitting) : 모델이 너무 단순하여 훈련 세트에 적절히 훈련되지 않은 경우로, 훈련세트가 전체 데이터를 대표한다고 가정하기 때문에 훈련세트를 잘 학습하는 것이 중요하다
-훈련세트와 테스트세트를 비교하였을 때, 훈련세트가 너무 높으면 과대적합, 그 반대이거나 두 점수가 모두 낮으면 과소적합이라고 판단이 가능하다.
-이웃의 개수를 줄이면 과소적합 해결이 가능하다
- 이웃의 개수를 줄이면 훈련 세트에 있는 국지적인 패터엔 민감해
- k-최근접 아웃 클래스는 이웃의 개수를 바꾸기 위해 객체를 다시 만들 필요가 없음 -> n_neighbors 속성값을 바꾸면 된다
knr.n_neighbors = 3
knr.fit(train_input, train_target)
print(knr.score(test_input, test_target))
** 실습 파일
3-2 선형회귀
1.선형회귀
- 선형회귀 (Linear Regression) : 대표적인 회귀 알고리즘으로, 훈련 데이터의 특성을 가장 잘 나타내는 어떤 직선을 학습하는 알고리즘이다.
- 사이킷런은 sklearn.linear_model 패키지 아래에 LinearRegression 클래스로 선형회귀 알고리즘을 구현해두었다.
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_input, train_target)
# Predict for a new data point
print(lr.predict([[50]]))
- 하나의 직선을 그리려면 기울기와 절편이 있어야 함 -> Linear Regression 클래스는 주어진 데이터에 가장 잘 맞는 기울기와 절편을 구하여 lr 객체의 coef_ 와 intercept_ 속성에 저장한다.
-선형회귀가 찾은 이러한 특성과 타깃 사이의 관계는 선형 방정식의 계수 또는 가중치에 저장
-머신러닝에서 종종 "가중치"는 방정식의 기울기와 절편을 모두 의미하는 경우가 많음
print(lr.coef_, lr.intercept_)
>>> [39.01714496] -709.0186449535477
- 이 둘을, 머신러닝 알고리즘이 찾은 값이라는 의미로 모델 파라미터라고 부른다.
- 머신러닝 알고리즘의 훈련 과정은 최적의 모델 파라미터를 찾는 것과 같은데, 이를 모델 기반 학습이라고 한다.
- k-최근접 이웃 모델과 같이 모델 파라미터가 없는 것을 사례 기반 학습이라고 한다.
import matplotlib.pyplot as plt
plt.scatter(train_input, train_target)
plt.plot([15,50], [15*lr.coef_+lr.intercept_, 50*lr.coef_+lr.intercept_])
plt.scatter(50, 1241.8, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show
- 바로 위의 직선이 선형 회귀 알고리즘이 이 데이터셋에서 찾은 최적의 직선이다.
-이를 기반으로 R^2 점수를 확인하면 다음과 같다
print(lr.score(train_input, train_target))
print(lr.score(test_input, test_target))
>> 0.939846333997604
>> 0.8247503123313558
- 훈련 세트와 테스트 세트의 점수가 조금 차이가 난다, 이 모델이 훈련세트에 과적합되었다고 판단하기에도 훈련 세트의 점수가 그리 높지 않음
- 전체적으로 과소적합되었다고 할 수 있음
- 그러나 더 특이점은 왼쪽 아래이다. 직선대로 예측한다면 농어의 무게가 0그램 이하로 내려가게 됨 -> 현실에서는 있을 수 없는 일
2. 다항회귀
- 농어의 길이와 무게에 대한 산점도를 자세히 보면 일적선이라기보다는 왼쪽 위로 조금 구부러진 곡선에 가까움
- 최적의 직선 (X), 최적의 곡선을 찾아보자! (O)
- 위와 같은 이차 방정식의 그래프를 그리려면 길이를 제곱한 항이 훈련 세트에 추가되어야 함
- 이는 **2 연산을 통해서 간단하게 수행할 수 있으며, column_stack() 함수를 활용해 간단히 계수가 1인 기존의 데이터 옆에 붙이는 연산을 수행할 수 있다.
train_poly = np.column_stack((train_input**2, train_input))
test_poly = np.column_stack((test_input**2, test_input))
* train_input**2 의 식에서는 브로드캐스팅이 진행되고 있음
- train_poly를 활용해 선형 회귀 모델을 다시 훈련, 계수 세 개 (a, b, c)를 찾을 것으로 기대
- 여기서 주목할 점은 훈련세트
는 제곱항이 추가되었으나 타깃값은 변화가 없음, 목표하는 값은 어떤 그래프를 훈련하든 바꿀 필요가 X
lr = LinearRegression()
lr.fit(train_poly, train_target)
print(lr.predict([[50**2, 50]]))
print(lr.coef_, lr.intercept_)
>> [1573.98423528]
>> [ 1.01433211 -21.55792498] 116.0502107827827
- 이와 같은 방정식을 다항식이라 부르며, 다항식을 사용한 선형 회귀를 다항 회귀 (polynominal regression)이라고 함
-산점도와 찾은 선형 곡선은 다음과 같다
print(lr.score(train_poly, train_target))
print(lr.score(test_poly, test_target))
>> 0.9706807451768623
>> 0.9775935108325122
- 위와 같이 구성된 훈련세트와 테스트세트의 R^2 점수가 출력도는데, 점수가 1차 방정식의 직선을 적용하였을 때보다 크게 높아졌다.
-그러나 테스트세트의 점수가 조금 더 높은 것을 보아 과소적합이 남아있음 -> 더 복잡한 모델이 필요
**실습 파일
**핵심 패키지와 함수
패키지 | 함수 | 설명 |
numpy | reshape() | 배열의 크기를 바꿀 수 있는 메소드, array.reshape(2,3) 의 형태로 활용 크기가 바뀐 새로운 배열을 반환할 때 지정한 크기가 원본 배열에 있는 원소의 개수와 다르면 에러를 발생시킨다. 크기에 -1을 지정하면 나머지 원소 개수로 모두 채우라는 의미이다. |
sklearn.metrics | mean_absolute_error | 타깃과 예측의 절댓값 오차를 평균하여 반환 |
sklearn.linear_model | LinearRegression | 선형회귀 알고리즘 클래스 |
'ML_AI > 24_여름방학 인공지능 스터디' 카테고리의 다른 글
[교재] 5. 트리 알고리즘 (1) (0) | 2024.07.09 |
---|---|
[교재] 3. 회귀 알고리즘과 모델 규제 (2) (0) | 2024.07.09 |
[교재] 2. 데이터 다루기 (0) | 2024.07.04 |
[실험] Predibase의 LoRA Land 사이트를 참고하여 LoRA의 기본 개념과 활용 방법 이해하기 (0) | 2024.07.04 |
[실험] Prompt 조사 및 Prompt에 따른 Chatbot 답변 변화 (0) | 2024.07.03 |