반응형

1. 인공 신경망

  • 생물학적 뉴런에서 영감을 받아 만든 머신러닝 알고리즘
  • 신경망은 기존의 머신러닝 알고리즘으로 다루기 어려웠던 이미지, 음성, 텍스트 분야에서 뛰어난 성능을 발휘
  • 인공 신경망 알고리즘을 종종 딥러닝이라고도 부름
  • 텐서플로
    • 구글이 만든 딥러닝 라이브러리
    • CPU와 GPU를 사용해 인공 신경망 모델을 효율적으로 훈련하며 모델 구축과 서비스에 필용한 다양한 도구를 제공
    • 텐서플로 2.0부터는 신경망 모델을 빠르게 구성할 수 있는 케라스를 핵심 API로 채택
    • 케라스를 사용하면 간단한 모델에서 아주 복잡한 모델까지 손쉽게 만들 수 있음
  • 밀집층
    • 가장 간단한 인공 신경망의 층
    • 뉴런들이 모두 연결되어 있기 때문에 완전 연결 층이라고도 부름
    • 출력층에 밀집층을 사용할 때는 분류하려는 클래스와 동일한 개수의 뉴런을 사용
  • 원-핫 인코딩
    • 정숫값을 배열에서 해당 정수 위칭의 원소만 1이고 나머지는 모두 0으로 변환
    • 다중 분류에서 출력층에서 만든 확률과 크로스 엔트로피 손실을 계산하기 위해서 변환이 필요
    • 텐서플로에서는 'sparse_categorical_entropy' 손실을 지정하면 이런 변환을 수행할 필요가 없음
  • 확인 문제
    1. 밀집층에 있는 뉴런 개수가 10개일 때 100개의 입력층과 연결된다. 1000개의 가중치가 발생 함. 뉴런마다 1개의 절편이 있으니 1010개의 모델 파라미터가 필요.
    2. sigmoid의 non-linear curver를 적용
    3. compile()
      1. loss 매개변수에 손실 함수를 지정
      2. 이진 부류일 경우 'binary_crossentropy', 다중 분류일 경우 'categorical_crossentropy'를 지정
      3. 정수일 경우 'sparse_categorical_crossentropy'로 지정
      4. 회귀 모델일 경우 'mean_square_error' 등으로 지정
      5. metrics 매개변수에 훈련 과정에서 측정하고 싶은 지표를 지정할 수 있음
      6. 측정 지표가 1개 이상일 경우 리스트로 전달
    4. 정수 레이블을 타겟으로 가지는 다중 분류 모델일 경우 compile() 메서드의 categorical_crossentropy를 지정

2. 심층 신경망

  • 2개 이상의 층을 포함한 신경망
  • 다층 인공 신경망, 심층 신경망, 딥러닝을 같은 의미로 사용
  • 렐루 함수
    • 이미지 분류 모델의 은닉층에 많이 사용하는 활성화 함수
    • 시그모이드 함수는 층이 많을수록 활성화 함수의 양쪽 끝에서 변화가 작기 때문에 학습이 어려워짐
    • 렐루 함수는 이런 문제가 없으며 계산도 간단함
  • 옵티마이저
    • 신경망의 가중치와 절편을 학습하기 위한 알고리즘 또는 방법
    • 케라스에는 다양한 경사 하강법 알고리즘이 구현되어 있음
    • 대표적으로 SGD, 네스테로프 모멘텀, RMSprop, Adam 등이 있음.
  • 확인 문제
    1. add()
      1. 케라스 모델에 층을 추가하는 메서드
      2. keras.layers 패키지 아래에 있는 층의 객체를 입력받아 신경망 모델에 추가
      3. add() 메서드를 호출하여 전달한 순서대로 층이 차례대로 늘어남
    2. Flatten - 
    3. relu 함수는 이미지 분류 모델의 은닉층에 많이 사용하는 활성화 함수
    4. SDG - 모멘텀, 네스테로프 모멘텀 알고리즘을 구현하는 클래스, 일정한 학습률을 사용함.

3. 신경망 모델 훈련

  • 드롭아웃
    • 은닉층에 있는 뉴런의 출력을 랜덤하게 꺼서 과대적합을 막는 기법
    • 훈련 중에 적용되며 평가나 예측에서는 적용하지 않음
    • 텐서플로는 이를 자동으로 처리
  • 콜백
    • 케라스 모델을 훈련하는 도중에 어떤 작업을 수행할 수 있도록 도와주는 도구
    • 대표적으로 최상의 모델을 자동으로 저장해 주거나 검증 점수가 더 이상 향상되지 않으면 일
      찍 종료할 수 있음
    • 조기종료
      • 검증 점수가 더 이상 감소하지 않고 상승하여 과대적합이 일어나면 훈련을 계속 진행하지 않고 멈추는 기법
      • 계산 비용과 시간을 절약할 수 있음
반응형
반응형

비지도 학습

머신러닝의 한 종류로 훈련 데이터에 타깃이 없음.

타깃이 없기 때문에 외부의 도움 없이 스스로 유용한 무언가를 학습해야 함.

대표적인 비지도 학습 작업은 군집, 차원 축소등이 있음

 

군집 알고리즘

히스토그램 : 값이 발생한 빈도를 그래프로 표시한 것. 보통 x축이 값의 구간(계급), y축은 발생 빈도(도수).

군집 : 비슷한 샘플끼리 그룹으로 모으는 작업

클러스터 : 군집 알고리즘에서 만든 그룹

실제 비지도 학습에서는 타깃값을 모르기 때문에 이처럼 샘플의 평균값을 미리 구할 수 없음

타깃값을 모르면서 어떻게 평균값을 찾을 수 있을까?

K-평균 알고리즘

k-평균 군집 알고리즘이 평균값을 자동으로 찾아 줌.

이 평균값이 클러스터의 중심에 위치하기 때문에 클러스터 중심 또는 센트로이드라고 부름.

k-평균 알고리즘 동작방식

1. 무작위로 k개의 클러스터 중심으로 정합니다.

2. 각 샘플에서 가장 가까운 클러스터 중심을 찾아 해당 클러스터의 샘플로 지정합니다.

3. 클러스터에 속한 샘플의 평균값으로 클러스터 중심을 변경합니다.

4. 클러스터 중심에 변화가 없을 때까지 2번으로 돌아가 반복합니다.

 

k-평균 알고리즘은 처음에는 랜덤하게 클러스터 중심을 선택하고 점차 가장 가까운 샘플의 중심으로 이동하는 비교적 간단한 알고리즘

 

k-평균 알고리즘의 단점 중 하나는 클러스터 개수를 사전에 지정해야 한다는 것. 실전에서는 몇개의 클러스터가 있는지 알 수 없습니다. 어떻게 하면 적절한 k 값을 찾을 수 있을까?

 

군집 알고리즘에서 적절한 k 값을 찾기 위한 완벽한 방법은 없다. 적절한 클러스터 개수를 찾기 위한 대표적인 방법인 엘보우 방법

주성분 분석

 

반응형

'IT > 머신러닝&딥러닝' 카테고리의 다른 글

06. 딥러닝  (0) 2023.02.19
04. 교차 검증 및 앙상블 학습  (0) 2023.02.05
03. 로지스틱 회귀  (0) 2023.01.24
02. 회귀 알고리즘과 모델 규제  (0) 2023.01.15
01. 머신러닝, 딥러닝 정리 및 개발 환경  (0) 2023.01.08
반응형

교차 검증

지금까지는 훈련 세트에서 모델을 훈련하고 테스트 세트에서 모델을 평가

테스트 세트에서 얻은 점수를 보고 일반화 성능을 가능

그런데 테스트 세트를 사용해 자꾸 성능을 확인하다 보면 점점 테스트 세트에 맞추게 되는 셈

 

테스트 세트로 일반화 성능을 올바르게 예측하려면 가능한 한 테스트 세트를 사용하지 말아야 함.

모델을 만들고 나서 마지막에 딱 한번만 사용하는 것이 좋음

 

테스트 세트를 사용하지 않으면 모델이 과대적합인지 과소적합인지 판단하기 어렵다.

테스트 세트를 사용하지 않고 이를 측정하는 간단한 방법은 훈련 세트를 또 나누는 것.

해당 데이터를 검증 세트라고 부른다.

 

전체 데이터 중 20%를 테스트 세트로 만들고 나머지 80%를 훈련 세트로 만들고, 이 훈련 세트 중에서 다시 20%를 떼어 검증 세트로 만듬.훈련세트에서 모델을 훈련하고 검증 세트로 모델을 평가. 이런식으로 테스트하고 싶은 매개변수를 바꿔가며 가장 좋은 모델을 고름.

 

k-fold 교차 검증

 

교차 검증 장,단점

장점 

  • 모든 데이터셋을 훈련에 활용할 수 있음
    • 정확도 향상
    • 데이터 부족으로 인한 underfitting을 방지
  • 모든 데이터셋을 평가에 활용할 수 있음
    • 평가에 사용되는 데이터 편중을 막을 수 있음
    • 평가 결과에 따라 좀 더 일반화된 모델을 만들 수 있음

단점

  • 반복 횟수가 많아서 훈련 평가 시간이 오래 걸림

 

앙상블 학습

정형 데이터를 다루는 데 가장 뛰어난 성과를 내는 알고리즘.

하나의 데이터를 여러개의 분류기를 통해 다수의 학습 모델을 만들어 학습시키고 학습 결과를 결합함으로써 과적합을 방지하고 정확도를 높이는 학습 기법.

 

종류

  • 보팅 : 앙상블 학습의 기본, 하위 모든 기법들이 보팅 사용
  • 배깅 : 하나의 데이터를 여러개로 나누어 학습하는 앙상블 학습법
    • 일반적으로 보팅은 하나의 데이터에 여러 알고리즘 적용
    • 배깅은 여러개로 나우어진 데이터에 하나의 알고리즘을 적용하는 것으로 구분
    • 여러개로 나누어진 데이터를 이용하는 배깅에서도 최종 예측값을 선택하는 행위 '보팅'이라고 함
  • 부스팅 : 병렬로 수행되는 배깅과 달리 각 결과값을 이용하여 순차적으로 결합
  • 랜덤 포레스트 : 배깅 + 결정 트리

랜덤 포레스트

앙상블 학습의 대표 주자 중 하나로 안정적인 성능 덕분에 널리 사용

결정 트리를 랜덤하게 만들어 결정트리의 숲을 만듬. 

각 결정 트리의 예측을 사용해 최종 예측을 만듬.

 

 

각 노드를 분할할 때 전체 특성 중에서 일부 특성을 무작위로 고른 다음 이 중에서 최선의 분할을 찾는다.

분류 모델인 RandomForestClassifier는 기본적으로 전체 특성 개수의 제곱근만큼의 특성을 선택하여 사용. 다만 회귀 모델인 RandomForestRegressor는 전체 특성을 사용.

 

RandomForest 학습 코드

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split

wine = pd.read_csv('https://bit.ly/wine_csv_data')

data = wine[['alcohol', 'sugar', 'pH']].to_numpy()
target = wine['class'].to_numpy()

train_input, test_input, train_target, test_target = train_test_split(data, target, test_size=0.2, random_state=42)

from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(rf, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))

rf.fit(train_input, train_target)
print(rf.feature_importances_)

rf = RandomForestClassifier(oob_score=True, n_jobs=-1, random_state=42)

rf.fit(train_input, train_target)
print(rf.oob_score_)


result :
0.9973541965122431 0.8905151032797809
[0.23167441 0.50039841 0.26792718]
0.8934000384837406

 

엑스트라 트리 ( Extra Trees)

랜덤 포레스트와 매우 비슷하게 동작. 기본적으로 100개의 결정 트리를 훈련.

전체 특성 중 일부 특성을 랜덤하게 선택하여 노드를 분할하는 데 사용.

 

랜덤 포레스트와 엑스트라 트리의 차이점은 부트스트랩 샘플을 사용하지 않는다는 점.

각 결정 트리를 만들 때 전체 훈련 세트를 사용. 대신 노드를 분할할 때 가장 좋은 분할을 찾는 것이 아니라 무작위로 분할.

하나의 결정 트리에서 특성을 무작위로 분할한다면 성능이 낮아지겠지만 많은 트리를 앙상블 하기 때문에 과대적합을 막고 검증 세트의 점수를 높이는 효과가 있다.

 

엑스트라 트리 ( Extra Trees ) 학습 코드

from sklearn.ensemble import ExtraTreesClassifier

et = ExtraTreesClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(et, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))

et.fit(train_input, train_target)
print(et.feature_importances_)


result:
0.9974503966084433 0.8887848893166506
[0.20183568 0.52242907 0.27573525]

 

그레이디언트 부스팅 ( Gradient boosting )

깊이가 얕은 결정 트리를 사용하여 이전 트리의 오차를 보완하는 방식으로 앙상블 하는 방법

사이킷런의 GradientBoostingClassifier는 기본적으로 깊이가 3인 결정 트리를 100개 사용. 깊이가 얕은 결정 트리를 사용하기 때문에 과대적합에 강하고 일반적으로 높은 일반화 성능을 기대할 수 있다.

 

경사 하강법을 사용하여 트리를 앙상블에 추가한다. 분류에서는 로지스틱 손실 함수를 사용하고 회귀에서는 평균 제곱 오차 함수를 사용한다. 

 

그레이디언트 부스팅은 결정 트리는 결정 트리를 계속 추가하면서 가장 낮은 곳을 찾아 이동한다. 

 

그레이디언트 부스팅 ( Gradient boosting ) 학습 코드

from sklearn.ensemble import GradientBoostingClassifier

gb = GradientBoostingClassifier(random_state=42)
scores = cross_validate(gb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))

gb = GradientBoostingClassifier(n_estimators=500, learning_rate=0.2, random_state=42)
scores = cross_validate(gb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))

gb.fit(train_input, train_target)
print(gb.feature_importances_)


result : 
0.8881086892152563 0.8720430147331015
0.9464595437171814 0.8780082549788999
[0.15872278 0.68010884 0.16116839]

 

 

히스토그램 기반 그레이디언트 부스팅 ( Histogram-based gradient boosting )

정형 데이터를 다루는 머신러닝 알고리즘 중에 가장 인기가 높은 알고리즘

입력 특성을 256개의 구간으로 나눕니다. 따라서 노드를 분할할 때 최적의 분할을 매우 빠르게 찾을 수 있다.

256개의 구간 중에서 하나를 떼어 놓고 누락된 값을 위해서 사용한다. 따라서 입력에 누락된 특성이 있더라도 이를 따로 전처리할 필요가 없다. 

과대적합을 잘 억제하면서 그레이디언트 부스팅보다 조금 더 높은 성능을 제공한다. 

 

히스토그램 기반 그레이디언트 부스팅 ( Histogram-based gradient boosting) 학습 코드

from sklearn.ensemble import HistGradientBoostingClassifier

hgb = HistGradientBoostingClassifier(random_state=42)
scores = cross_validate(hgb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))

from sklearn.inspection import permutation_importance

hgb.fit(train_input, train_target)
result = permutation_importance(hgb, train_input, train_target, n_repeats=10,
                                random_state=42, n_jobs=-1)
print(result.importances_mean)

result = permutation_importance(hgb, test_input, test_target, n_repeats=10,
                                random_state=42, n_jobs=-1)
print(result.importances_mean)

hgb.score(test_input, test_target)

from xgboost import XGBClassifier

xgb = XGBClassifier(tree_method='hist', random_state=42)
scores = cross_validate(xgb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))

from lightgbm import LGBMClassifier

lgb = LGBMClassifier(random_state=42)
scores = cross_validate(lgb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))


result : 
0.9321723946453317 0.8801241948619236
[0.08876275 0.23438522 0.08027708]
[0.05969231 0.20238462 0.049     ]
0.8824322471423747 0.8726214185237284
0.9338079582727165 0.8789710890649293

 

 

Colab 실행 화면

반응형

'IT > 머신러닝&딥러닝' 카테고리의 다른 글

06. 딥러닝  (0) 2023.02.19
05. 비지도 학습  (0) 2023.02.12
03. 로지스틱 회귀  (0) 2023.01.24
02. 회귀 알고리즘과 모델 규제  (0) 2023.01.15
01. 머신러닝, 딥러닝 정리 및 개발 환경  (0) 2023.01.08
반응형

로지스틱 회귀 ( Logistic Regression)

* 선형 방적식을 사용한 분류 알고리즘

* 선형 회귀와 달리 시그모이드 함수나 소프트 맥스 함수를 사용하여 클래스 확률을 출력

* 로지스틱 회귀는 다중 분류를 위해 소프트맥스 함수를 사용하여 클래스를 예측

 

로지스틱 회귀에서 이진 분류 확률을 출력하기

로지스틱 회귀에서 이진 분류 확률을 출력하기 위해서는 시그모이드 함수(Sigmoid function)을 사용해야한다.

 

샘플 데이터를 사용하여 로지스틱 회귀를 위한 시그모이드 함수를 사용해보겠습니다.

 

 

"""# 데이터 준비 """

import pandas as pd

fish = pd.read_csv('https://bit.ly/fish_csv_data')
fish.head()

 

샘플 csv 파일을 불러와서 데이터 프레임으로 변환 후 처음 5개 행을 출력

 

시그 모이드 함수 식

시그모이드 함수 그래프

 

시그모이드 선형 방정식의 출력 z의 음수를 사용해 자연상수  e를 거듭제곱하고 1을 더한 값의 역수를 취함

시그모이드 함수가 이렇게 복잡하게 계산한 이유는 아래 시그 모이드 함수 그래프를 만들 수 있기 때문이다.

 

z가 무한하게 큰 음수일 경우 이 함수는 0에 가까워지고, z가 무한하게 큰 양수가 될 때는 1에 가까워진다. z가 0일 경우 0.5이다. z가 어떤 값이 되더라도 결과는 전대로 0~1 사이의 범위를 벗어날수 없다. 그렇다면 0~100%까지 확률로 해석할 수 있다. 

import numpy as np
import matplotlib.pyplot as plt

z = np.arange(-5, 5, 0.1)
phi = 1 / (1 + np.exp(-z))

plt.plot(z, phi)
plt.xlabel('z')
plt.ylabel('phi')
plt.show()

 

준비한 샘플 데이터를 가지고 로지스틱 회귀로 이진 분류를 수행

 

불리언 인덱싱을 적용해서 훈련 세트에서 도미와 빙어의 행만 골라내기

bream_smelt_indexes = (train_target == 'Bream') | (train_target == 'Smelt')
train_bream_smelt = train_scaled[bream_smelt_indexes]
target_bream_smelt = train_target[bream_smelt_indexes]

 

분리한 도미와 빙어 데이터로 로지스틱 회귀 모델을 훈련

from sklearn.linear_model import LogisticRegression

lr = LogisticRegression()
lr.fit(train_bream_smelt, target_bream_smelt)

 

훈련한 모델을 사용해서 train_bream_smelt에 있는 처음 5개의 샘플을 예측

print(lr.predict(train_bream_smelt[:5]))
==> result : ['Bream' 'Smelt' 'Bream' 'Bream' 'Bream']

predict_proba() 메서드를 사용하여 처음 5개 샘플의 예측 확률을 출력

print(lr.predict_proba(train_bream_smelt[:5]))
==> result : 
[[0.99759855 0.00240145]
 [0.02735183 0.97264817]
 [0.99486072 0.00513928]
 [0.98584202 0.01415798]
 [0.99767269 0.00232731]]

첫번째 열이 음성 클래스에 대한 확률이고, 두번째 열이 양성 클래스에 대한 확률

 

어떤것이 음성 클래스이고 어떤것이 양성 클래스인지 확인

print(lr.classes_)
==> result : 
['Bream' 'Smelt']

도미가 음성, 빙어가 양성 클래스

 

 

에포크와 과대/과소적합

확률적 경사 하강법을 사용한 모델은 에포크 횟수에 따라 과소적합이나 과대적합이 될 수 있다.

 

* 이런 현상이 발생하는 이유

** 적은 에포크 횟수 동안에 훈련한 모델은 훈련 세트와 테스트 세트에 잘 맞지 않는 과소적합된 모델일 가능성이 높음

** 많은 에포크 횟수 동안에 훈련한 모델은 훈련 세트에 너무 잘 맞아 테스트 세트에는 오히려 점수가 나쁜 과대적합된 모델일 가능성이 높음

 

과대 / 과소 적합을 위한 데이터 준비

import pandas as pd

fish = pd.read_csv('https://bit.ly/fish_csv_data')

fish_input = fish[['Weight','Length','Diagonal','Height','Width']].to_numpy()
fish_target = fish['Species'].to_numpy()

from sklearn.model_selection import train_test_split

train_input, test_input, train_target, test_target = train_test_split(
    fish_input, fish_target, random_state=42)

from sklearn.preprocessing import StandardScaler

ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)

 

 

* 훈련이 진행되는 동안 fit() 메서드가 아닌 partial_fit() 메서드만 사용

* np.unique() 함수로 train_target에 있는 7개의 생선의 목록을 생성

* 에포크마다 훈련 세트와 테스트 세트에 대한 점수를 기록하기 위해 2개의 리스트를 준비

from sklearn.linear_model import SGDClassifier
import numpy as np

sc = SGDClassifier(loss='log', random_state=42)

train_score = []
test_score = []

classes = np.unique(train_target)

 

 

* 300번의 에포크 동안 훈련을 반복 진행

* 매 반복마다 훈련 세트와 테스트 세트의 점수를 계산하여 train_score, test_score에 추가

* 300번의 에포크 동안 기록한 훈련 세트와 테스트 세트의 점수를 그래프로 표시

for _ in range(0, 300):
    sc.partial_fit(train_scaled, train_target, classes=classes)
    train_score.append(sc.score(train_scaled, train_target))
    test_score.append(sc.score(test_scaled, test_target))

import matplotlib.pyplot as plt

plt.plot(train_score)
plt.plot(test_score)
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.show()

 

백번째 에포크 이후에 훈련 세트와 테스트 세트의 점수가 조금씩 벌어짐

에포크 초기에는 과소적합되어 훈련세트와 테스트 세트의 점수가 낮음

해당 모델의 경우 백번째 에포크가 적절한 반복횟수로 보임

 

* SGDClassifier의 반복 횟수를 100에 맞추고 모델을 다시 훈련

* 최종적으로 테스트 세트와 훈련세트에서 점수를 출력

sc = SGDClassifier(loss='log', max_iter=100, tol=None, random_state=42)
sc.fit(train_scaled, train_target)

print(sc.score(train_scaled, train_target))
print(sc.score(test_scaled, test_target))

==> result : 
0.957983193277311
0.925

SGDClassifier는 일정 에포크 동안 성능이 향상되지 않으면 더 훈련하지 않고 자동으로 멈춤

 

tol 매개변수에서 향상될 최소값을 지정. None으로 지정하여 자동으로 멈추지 않고 max_iter=100 만큼 무조건 반복

 

 

** 추가 **

SGDClassifier의 loss 매개변수의 기본값은 hinge이다.

힌지 손실은 서포트 벡터 머신이라 불리는 또 다른 머신러닝 알고리즘을 위한 손실 함수

 

반응형
반응형

지도 학습 알고리즘

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

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

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

 

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

 

# 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()

결과

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

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

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

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

 

특징 

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

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

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

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

 

모델 파라미터의 예

- 인공신경망의 가중치

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

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

반응형
반응형
 
혼자 공부하는 머신러닝+딥러닝
이 책은 수식과 이론으로 중무장한 머신러닝, 딥러닝 책에 지친 ‘독학하는 입문자’가 ‘꼭 필요한 내용을 제대로’ 학습할 수 있도록 구성했다. 구글 머신러닝 전문가(Google ML expert)로 활동하고 있는 저자는 여러 차례의 입문자들과 함께한 머신러닝&딥러닝 스터디와 번역ㆍ집필 경험을 통해 ‘무엇을’ ‘어떻게’ 학습해야 할지 모르는 입문자의 막연함을 이해하고, 과외 선생님이 알려주듯 친절하게 핵심적인 내용을 콕콕 집어준다. 컴퓨터 앞에서 〈손코딩〉을 따라하고, 확인 문제를 풀다 보면 그간 어렵기만 했던 머신러닝과 딥러닝을 개념을 스스로 익힐 수 있을 것이다! - 베타리더가 함께 만든 입문서 베타리딩 과정을 통해 입문자에게 적절한 난이도, 분량, 학습 요소 등을 고민하고 반영했다. 어려운 용어와 개념은 한 번 더 풀어 쓰고, 복잡한 설명은 눈에 잘 들어오는 그림으로 풀어 냈다. ‘혼자 공부해본’ 여러 입문자의 마음과 눈높이가 책 곳곳에 반영된 것이 이 책의 가장 큰 장점이다.
저자
박해선
출판
한빛미디어
출판일
2020.12.21

[기본]

인공지능, 머신러닝, 딥러닝 간단 정리

인공지능 : 사람처럼 학습하고 추론할 수 있는 지능을 가진 시스템을 만드는 기술. 강인공지능과 약인공지능으로 나뉜다.

머신러닝 : 규칙을 프로그래밍하지 않아도 자동으로 데이터에서 규칙을 학습하는 알고리즘 연구분야. 사이킷런이 대표적인 라이브러리

딥러닝 : 인공 신경망. 텐서플로와 파이토치가 대표적인 라이브러리

 

 


구글 코랩

로컬 환경에 별도의 개발 환경을 구축하지 않아도 구글에서 지원해주는 웹브라우저 기반 파이선 프로그램의 테스트 및 저장할 수 있는 서비스.

 

요약 : 클라우드 기반의 주피터 노트북 개발 환경

 

구글 계정만 있다면 누구나 무료로 사용할 수 있다. 

 

로그인 및 코랩 접속은 (https://colab.research.google.com) 에서 할 수 있다.

구글 계정으로 로그인 하지 않아도 코랩에 접속할 순 있지만 코드 실행 및 저장을 위해서는 로그인하는 것을 권장.

 


1차 코랩 실습 

- k-최근접이웃 알고리즘을 사용하여 2개의 종류를 분류하는 머신러닝 모델 훈련

- #특성 #훈련 #k-최근접이웃알고리즘 #모델 #정확도

 

- 특성 : 데이터의 특징. 예) 도미의 특징을 길이와 무게로 표현한 것

아래 사용하는 생선 데이터셋은 캐글에 공개된 데이터셋을 사용.(https://www.kaggle.com/aungpyaeap/fish-market)

* 도미 데이터셋

bream_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0, 
                31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0, 
                35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0]
bream_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0, 
                500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0, 
                700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0]

 

- 산점도 : x, y축으로 이뤄진 좌표계에 두 변수(x, y)의 관계를 표현하는 방법

- 맷플롯립(matplotlib)의 scatter() 함수를 사용하여 산점도 그래프를 사용

- 도미 데이터셋의 길이를 x축, 무게를 y축으로 산점도를 표시

import matplotlib.pyplot as plt

bream_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0, 
                31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0, 
                35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0]
bream_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0, 
                500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0, 
                700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0]

plt.scatter(bream_length, bream_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

 

- 코랩 실행 결과

도미데이터를 기준으로 산점도를 표시한 결과

 

* 빙어 데이터셋

smelt_length = [9.8, 10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]
smelt_weight = [6.7, 7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]

 - 기존 scatter() 함수에 빙어 데이터셋 추가

import matplotlib.pyplot as plt

bream_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0, 
                31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0, 
                35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0]
bream_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0, 
                500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0, 
                700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0]

smelt_length = [9.8, 10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]
smelt_weight = [6.7, 7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]

plt.scatter(bream_length, bream_weight)
plt.scatter(smelt_length, smelt_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

 

- 코랩 실행 결과

빙어 데이터를 추가하여 산점도를 표시

 


k-최근접 이웃 알고리즘 적용

- k-최근접 이웃 알고리즘을 적용하여 도미와 빙어 데이터를 구분

- 사이킷런을 사용하여 머신러닝을 진행

- 사이킷런을 사용하기 위해서는 각 특성의 리스트를 세로 방향으로 늘어뜨린 2차원 리스트가 필요

- 파이썬의 zip() 함수와 리스트 내포(list comprehension) 구문을 사용하여 2차원 리스트를 생성

 

* 도미와 빙어의 데이터를 하나의 데이터로 만들기

length = bream_length + smelt_length
weight = bream_weight + smelt_weight

fish_data = [[l,w] for l, w in zip(length, weight)]
print(fish_data)

- 코랩 실행 결과

도미와 빙어의 데이터를 합쳐서 2차원 리스트로 만든 결과

 

- 머신 러닝을 하기 전에 준비할 정답 데이터셋.

- 머신 러닝 알고리즘이 생선의 길이와 무게를 보고 도미와 빙어를 구분하는 규칙을 찾기 원하기 때문

- 기존 데이터에서 어떤 것이 도미이고 어떤 것이 빙어인지 알려주어야 함

 

* 정답 데이터셋 만들기

fish_target = [1] * 35 + [0] * 14
print(fish_target)

 

- 코랩 실행 결과

정답 데이터셋

 

- 사이킷런의 k-최근접 이웃 알고리즘을 구현한 KNeighborsClassifier 클래스를 사용

- 훈련 : 기준 데이터를 사이킷런에 전달하여 학습시키는 과정

- 사이킷런에서는 fit() 메서드를 사용한다.

- fit() 메서드로 주어진 데이터로 알고리즘 훈련 후 얼마나 잘 훈련되었는지 score() 메서드를 사용하여 모델을 평가

- score() 메서드는 0~1 사이의 값을 반환. 1은 모든 데이터를 정확히 맞혔다는 것

 

* 데이터 알고리즘 학습

from sklearn.neighbors import KNeighborsClassifier

kn = KNeighborsClassifier()
kn.fit(fish_data, fish_target)
kn.score(fish_data, fish_target)

- 코랩 실행 결과

알고리즘 학습 결과


[선택] 간단히 사이킷런을 사용하여 알고리즘 학습을 진행해 보았고, 책에 나온 문제 내용을 정리

 

1. 머신 러닝 알고리즘의 한종류. 샘플 입력과 타깃을 알고 있을 때 사용할 수 있는 학습 방법 - 지도학습 

- 지도학습 : 훈련하기 위한 데이터와 정답이 필요. 정답(타깃)이 있으니 알고리즘 정답을 맞히는 것을 학습

- 비지도학습 : 타깃 없이 입력 ㅔ이터만 사용. 정답을 사요하지 않으므로 무언가를 맞힐 순 없으나 데이터를 잘 파악하거나 변형하는 데 도움을 줌

- 차원축소 : 비지도 학습의 큰 축. 고차원의 원본 데이터를 저 차원의 부분공간으로 투영하여 데이터를 축소하는 기법. 예) 10차원 이상의 데이터가 주어졌을 때 2~3차원의 데이터로 부분공간으로 투영하여 데이터를 축소. 차원이 증가할수록 데이터 포인트 간 거리가 기하급수적으로 멀어져 희소한 구조를 가지게 됨. 피처가 많아지게 되면 개별 피처 간 상관관계가 높아 다중공선성의 문제 과적합이나 예측 성능이 저하될 우려가 있음.

- 강화학습 : 현재의 상태(state)에서 어떤 행동(action)을 취하는 것이 최적인지를 학습하는 것. 행동을 취할 때마다 외부 환경에서 보상(reward)이 주어지고, 보상을 최대화하는 방향으로 학습이 진행

 

2. 훈련 세트와 테스트 세트가 잘못 만들어져 전체 데이터를 대표하지 못하는 현상 - 샘플링 편향

- 샘플링 오류 : sampling error는 랜덤 표본의 통계와 실제 모집단 값 사이의 불일치를 의미. 자연적인 우연인자를 말하는 것이지, 설계가 부실하고 실행이 잘 안되어 있는 실험에 의한 측정 오류는 아니다.

- 샘플링 실수 : 아직 답을 찾는 중입니다. 향후 업데이트

- 샘플링 편차 : 아직 답을 찾는 중입니다. 향후 업데이트

- 샘플링 편향 : 일반적으로 훈련 세트와 테스트 세트에 샘플이 골고루 섞여 있지 않으면 샘플링 한쪽으로 치우쳤다는 의미

 

3. 사이킷런은 입력 데이터(배열)가 어떻게 구성되어 있을 것으로 기대하는가

- 테이블의 행은 수많은 샘플들로 구성되고, 열은 샘플의 특성들로 구성.

- 샘플이 특성에 비해 너무 적으면 overfit이 발생하거나 예측이 안될 수 있음.

 

반응형

'IT > 머신러닝&딥러닝' 카테고리의 다른 글

05. 비지도 학습  (0) 2023.02.12
04. 교차 검증 및 앙상블 학습  (0) 2023.02.05
03. 로지스틱 회귀  (0) 2023.01.24
02. 회귀 알고리즘과 모델 규제  (0) 2023.01.15
00. 혼자 공부하는 머신러닝 & 딥러닝  (0) 2023.01.08

+ Recent posts