반응형

지도 학습 알고리즘

지도 학습 알고리즘은 크게 분류와 회귀로 나뉨

분류 : 샘플을 몇 개의 클래스 중 하나로 분류하는 문제

회귀 : 클래스 중 하나로 분류하는 것이 아니라 임의의 어떤 숫자를 예측하는 문제

 

예) 내년도 경제 성장률을 예측하거나 배달이 도착하는 시간을 예측하는 것이 회귀 문제

 

# K-최근접 이웃 회귀

K-최근접 이웃 알고리즘이 회귀에도 작동한다.

K-최근접 이웃 알고리즘은 어떻게 숫자를 예측할 수 있는가?

- K-최근접 이웃 분류 알고리즘 : 

--> 예측하려는 샘플에 가장 가까운 샘플 k개를 선택 -> 샘플들의 클래스를 확인하여 다수 클래스를 새로운 샘플의 클래스로 예측

 

- K-최근접 이웃 회귀 알고리즘 : 

--> 예측하려는 샘플에 가장 가까운 샘플 k개를 선택 -> 이웃한 샘플의 타깃이 어떤 클래스가 아닌 임의의 수치 -> 이웃 샘플의 수치를 사용해 새로운 샘플 x의 타깃을 예측 ( 이웃 수치들의 평균을 구함)

 

실습

데이터 준비

넘파이 배열을 사용한 농어의 길이와 무게 데이터 준비

perch_length = np.array([8.4, 13.7, 15.0, 16.2, 17.4, 18.0, 18.7, 19.0, 19.6, 20.0, 21.0,
       21.0, 21.0, 21.3, 22.0, 22.0, 22.0, 22.0, 22.0, 22.5, 22.5, 22.7,
       23.0, 23.5, 24.0, 24.0, 24.6, 25.0, 25.6, 26.5, 27.3, 27.5, 27.5,
       27.5, 28.0, 28.7, 30.0, 32.8, 34.5, 35.0, 36.5, 36.0, 37.0, 37.0,
       39.0, 39.0, 39.0, 40.0, 40.0, 40.0, 40.0, 42.0, 43.0, 43.0, 43.5,
       44.0])
perch_weight = np.array([5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0, 110.0,
       115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0, 130.0,
       150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0, 197.0,
       218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0, 514.0,
       556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0, 820.0,
       850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 1000.0,
       1000.0])

 

특성 데이터를 x축에 놓고 타깃 데이터를 y축에 놓아 데이터가 어떤 형태를 띠고 있는지 산점도로 표시

 

 

데이터를 머신러닝 모델에 사용하기 전에 훈련 세트와 테스트 세트로 나누기

사이킷런의 train_test_split() 함수를 사용해 훈련 세트와 테스트 세트로 나누기

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)

 

 

reshape() 메서드를 사용해 train_input과  test_input을 2차원 배열로 변경

train_input = train_input.reshape(-1,1)
test_input = test_input.reshape(-1,1)
print(train_input.shape, test_input.shape)

 

사이킷런에서 k-최근접 이웃 회귀 알고리즘을 구현한 KNeighborsRegressor 클래스를 사용

해당 클래스의 객체를 생성하고 fit() 메서드로 회귀 모델을 훈련

from sklearn.neighbors import KNeighborsRegressor
knr = KNeighborsRegressor();
knr.fit(train_input, train_target)
print(knr.score(test_input, test_target))

 

프린트 된 값은 결정계수 또는 R^2이라고 한다. 

이 값은 다음의 식으로 계산 된다.

R^2 = 1- ((타깃 - 예측)^2의 합 / (타킷 - 평균)^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)

 

훈련 세트에서 점수가 좋았는데 테스트 세트에서는 점수가 굉장히 나쁘다면 모델이 훈련세트에 과대적합 되었다고 한다. 훈련세트에만 잘 맞는 모델이라 테스트 세트와 나중에 실전에 투입하여 새로운 샘플에 대한 예측을 만들 때 잘 동작하지 않을 것이다. 

반대로 훈련 세트보다 테스트 세트의 점수가 높거나 두점수가 모두 낮은 경우는 과소적합이라고 한다. 모델이 너무 단하여 훈련 세트에 적절히 훈련되지 않은 경우이다. 훈련 세트가 전체 데이터를 대표한다고 가정하기 때문에 훈련 세트를 잘 학습하는 것이 중요하다.

 

 

위 샘플 데이터의 훈련 세트와 테스트 세트의 점수를 비교해보면 과소적합이라고 할 수 있다. 이것을 해결하기 위해 모델을 조금 더 복잡하게 만들어서 해결하면 된다. 훈련 세트에 더 잘 맞게 만들면 테스트 세트의 점수는 조금 나아질것이다. 

k-최근접 이웃 알고리즘으로 모델을 더 복잡하게 만드는 방법은 이웃의 개수를 줄이는 것이다. 이웃의 개수를 줄이면 훈련 세트에 있는 국지적인 패턴에 민감해지고, 이웃의 개수를 늘리면 데이터 전반에 있는 일반적인 패턴을 따를 것이다. 

 

 

[미션]  과대적합 과소적합 예측 그래프

knr = KNeighborsRegressor()
x = np.arange(5,45).reshape(-1, 1)
for n in [1,5,10]:
  knr.n_neighbors = n
  knr.fit(train_input, train_target)
  prediction = knr.predict(x)

  plt.scatter(train_input, train_target)
  plt.plot(x, prediction)
  plt.title('n_neibors = {}'.format(n))
  plt.xlabel('length')
  plt.ylabel('weight')
  plt.show()

결과

[선택 미션] 모델 파라미터

선형 회귀가 찾은 가중치처럼 머신러닝 모델이 특성에서 학습한 파라미터를 말한다.

모델에 적용할 하나 이상의 파라미터를 사용하여 새로운 샘플에 대한 예측을 하기 위해 사용

머신러닝 훈련 모델에 의해 요구되는 변수.

 

특징 

- 머신 러닝 훈련 모델의 성능은 파라미터에 의해 결정된다.

- 파라미터는 데이터로부터 추정 또는 학습 된다.

- 파라미터는 개발자에 의해 수동으로 설정하지 않는다. (임의 조정 불가)

- 학습된 모델의 일부로 저장

 

모델 파라미터의 예

- 인공신경망의 가중치

- 서포트 벡터 머신의 서포트 벡터

- 선형 회귀 또는 로지스틱 회귀에서의 결정계수

반응형

+ Recent posts