본문 바로가기

Study

[Book]2. 지도학습 - (1)

Book Title : Introduction to Machine Learning with Python
- 파이썬 라이브러리를 활용한 머신러닝 -

 

지은이 : 안드레아스 뮐러, 세라 가이도

옮긴이 : 박해선

출판사 : 한빛미디어

 

코드 출처

https://github.com/rickiepark/introduction_to_ml_with_python

 

GitHub - rickiepark/introduction_to_ml_with_python: 도서 "[개정판] 파이썬 라이브러리를 활용한 머신 러닝"의

도서 "[개정판] 파이썬 라이브러리를 활용한 머신 러닝"의 주피터 노트북과 코드입니다. Contribute to rickiepark/introduction_to_ml_with_python development by creating an account on GitHub.

github.com


개요

책을 읽고 줄거리를 요약

이미 알고 있는 부분은 빨리 넘어가고 모르는 부분 위주로 요약


2. 지도 학습  - (1)

서론

지도학습에 관해 더 살펴보고 인기 있는 지도 학습 알고리즘 몇 가지를 소개함

분류
  • 미리 정의된 여러 클래스 레이블(class label)중 하나를 예측하는 것
  • 두 개의 클래스로 분류하는  이진 분류(binary classification)와 셋 이상의 클래스로 분류하는 다중 분류(multiclass classification)로 나눔
  • 이진 분류에서는 한 클래스를 양성(positive) 클래스, 다른 하나를 음성(negative) 클래스라고도 함
회귀
  • 연속적인 숫자, 또는 부동소수점수(실수)를 예측하는 것
  • 예) 어떤 사람의 교육 수준, 나이등을 바탕으로 연간 소득 예측

2.2 일반화, 과대적합, 과소 적합

  • 모델이 처음 보는 데이터에 대해 정확하게 예측할 수 있으면 이를 훈련 세트에서 테스트 세트로 일반화되었다고 함
  • 과대 적합(overfitting) : 모델이 훈련 세트의 각 샘플에 너무 가깝게 맞춰져서 새로운 데이터에 일반화되기 어려울 때 일어남
  • 과소 적합(underfitting) : 너무 간단한 모델일 선택되는 것


2.2.1 모델 복잡도와 데이터셋 크기의 관계

  • 데이터셋에 다양한 특징 포인트가 많을수록 과대적합 없이 더 복잡한 모델을 만들 수 있음
  • 같은 특징을 중복하거나 비슷한 데이터를 계속 모으는 것은 도움 X

2.3 지도 학습 알고리즘

2.3.2 K-최근접 이웃

  • 사이킷런을 사용해 k-최근접 이웃 알고리즘 적용 법을 알아봄
  • 아래 코드의 모델 정확도는 85%
  • 클래스0과 클래스 1로 지정한 영역으로 나뉘는 결정 경계(decision boundary)를 볼 수 있음
  • 이웃의 수를 늘릴수록 결정 경계가 더 부드러워짐
!pip install mglearn
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import mglearn
X, y = mglearn.datasets.make_forge()

X_train, X_test, y_train, y_test = train_test_split(X, y)
clf = KNeighborsClassifier(n_neighbors=3)
clf.fit(X_train, y_train)

# 테스트 정확도
print(clf.score(X_test, y_test))
# KNeighborsClassifer 분석
import matplotlib.pyplot as plt
fix, axes = plt.subplots(1, 3, figsize = (10, 3))

for n, ax in zip([1, 3, 9], axes):
    clf = KNeighborsClassifier(n_neighbors=n).fit(X,y)
    mglearn.plots.plot_2d_separator(clf, X, fill=True, eps = 0.5, ax=ax, alpha=.4)
    mglearn.discrete_scatter(X[:,0], X[:, 1], y, ax = ax)
    ax.set_title("{}이웃".format(n))
axes[0].legend(loc=3)

  • K-최근접 이웃 알고리즘을 이용해 회귀분석 또한 가능
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import train_test_split
import mglearn
X, y = mglearn.datasets.make_wave(n_samples = 40)

# dataset split
X_train, X_test, y_train, y_test = train_test_split(X, y)

# 이웃수는 3
regressor = KNeighborsRegressor(n_neighbors = 3)

# 학습
regressor.fit(X_train, y_train)

# 결정 계수 = 회귀모델에서 예측의 적합도 = R^2
print("test set R2 : ", regressor.score(X_test, y_test))
  • 아래 그림과 같이 이웃을 하나만 사용할 때는 매우 불안정한 예측을 함
  • 이웃을 많이 사용하면 더 안정된 예측이 가능
import matplotlib.pyplot as plt
import numpy as np
# k -최근접 이웃 회귀 분석
fig,axes = plt.subplots(1, 3, figsize=(15, 4))

line = np.linspace(-3, 3, 1000).reshape(-1, 1)
for n, ax in zip([1, 3, 9], axes):
    regressor = KNeighborsRegressor(n_neighbors = n)
    regressor.fit(X_train, y_train)
    ax.plot(line, regressor.predict(line))
    ax.plot(X_train, y_train, '^', c=mglearn.cm2(0), markersize = 8)
    ax.plot(X_test, y_test, '*', c=mglearn.cm2(1), markersize = 8)

    ax.set_title("{} n test socre : {:.2f} , test score : {:.2f}".format(n , regressor.score(X_train, y_train), regressor.score(X_test, y_test)))
    ax.set_xlabel("특성")
    ax.set_ylabel("타깃")

  • K-최근접 이웃 분류기에 중요한 매개변수
    • 데이터 포인트 사이의 거리를 재는 방법    
    • 이웃 수
  • 해당 알고리즘은 이해 쉬움, 하지만 예측이 느리고 많은 특성을 처리하는 능력이 부족

2.3.3 선형 모델

  • 선형 회귀(linear regression) 또는 최소 제곱 법(ordinary least squares)은 간단하고 오래된 회귀용 선형 알고리즘

선형 모델 만들기

from sklearn.linear_model import LinearRegression
X, y = mglearn.datasets.make_wave(n_samples=50)

X_train, X_test, y_train, y_test = train_test_split(X, y)
linear_reg = LinearRegression().fit(X_train, y_train)

# 기울기 파라미터(w)는 가중치 또는 계수라고 하며 linear_reg객체의 coef_ 속성에 저장, 편향 또는 절편 파라미터(b)는 intercept_ 속성에 저장
print("linear.coef_ ", linear_reg.coef_)
print("linear_intercept_ ", linear_reg.intercept_)

print("훈련 세트 스코어",linear_reg.score(X_train, y_train))
print("테스트 세트 스코어", linear_reg.score(X_test, y_test))

  • 훈련 세트와 테스트 세트의 점수와 매우 비슷하면서 성능이 낮음 이는 과소적합 상태

리지 회귀

  • 회귀를 위한 선형 모델
  • 리지 회귀에서 가중치 선택은 추가 제약 조건을 만족시키는 목적도 있음
  • 가중치의 절댓값을 가능한 작게 만드는 것, 이런 제약을 규제라하며 규제란 과대 적합이 되지 않도록 모델을 강제로 제한하는 것
  • L2규제 사용
from sklearn.linear_model import Ridge
ridge = Ridge().fit(X_train, y_train)
print("훈련셋 스코어 : ", ridge.score(X_train, y_train))
print("테스트셋 스코어 : ",ridge.score(X_test, y_test))

# 훈련셋 스코어 :  0.5897442441759927
# 테스트셋 스코어 :  0.6068969456443714
  • alpha 매개변수로 훈련 세트의 성능 대비 모델을 얼마나 단순화할지 지정할 수 있음
  • alpha 값이 아주 작아지면 규제 제한이 매우 작은것이기때문에 LinearRegression과 동일

라소

  • Ridge 대안
  • 라소도 리지 회귀처럼 계수를 0에 가깝게 만들려고함
  • 하지만 방식이 조금 다르며 이를 L1 규제라고 함
from sklearn.linear_model import Lasso
import numpy as np

# 결과가 좋지 않으며 과소적합

lasso = Lasso().fit(X_train, y_train)
print("훈련셋 점수 : ",lasso.score(X_train, y_train))
print("테스트셋 점수 : ", lasso.score(X_test, y_test))

# 훈련셋 점수 :  0.23842476969245974
# 테스트셋 점수 :  0.2222530825106913



# 과소 적합을 줄이기 위해서 alpha 값을 줄dla
lasso001 = Lasso(alpha = 0.01, max_iter = 50000).fit(X_train, y_train)
print("훈련셋 점수 : ",lasso001.score(X_train, y_train))
print("테스트셋 점수 : ", lasso001.score(X_test, y_test))
print("사용한 특성 수 : ", np.sum(lasso001.coef_ !=0))
# 훈련셋 점수 :  0.5897586514503679
# 테스트셋 점수 :  0.606971082516783

분류용 선형 모델

  • 유명한 선형 분류 알고리즘으로 로지스틱 회귀와 선형 서포트 벡터 머신이 있음

다중 클래스 분류용 선형모델

  • 로지스틱 회귀를 제외한 많은 선형 분류 모델은 대부분 이진 분류만을 지원
  • 이진 분류 알고리즘을 다중 클래스 분류 알고리즘으로 확장하는 보편적인 기법은 일대다 방법
세 개의 클래스를 가진 간단한 데이터셋에 일대다 방식 적용
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
X, y= make_blobs()
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
plt.xlabel("att1 0")
plt.ylabel("att2 1")
plt.legend("class 0" , "class 1" "class 2")

from sklearn.svm import LinearSVC
# LinearSVC 분류기 훈련
linear_svm = LinearSVC().fit(X, y)

# 세 개의 이진 분류기가 만드는 경계 시각화
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
line = np.linspace(-15, 15)
for coef, intercept, color in zip(linear_svm.coef_, linear_svm.intercept_, mglearn.cm3.colors):
    plt.plot(line, -(line * coef[0] + intercept) / coef[1], c = color)

plt.ylim(-10, 15)
plt.xlim(-10, 8)
plt.xlabel("attr 0")
plt.ylabel("attr 1")

요약

  • 선형 모델은 학습 속도가 빠르고 예측도 빠름
  • 회귀와 분류에서 본 예측이 어떻게 만들어지는지 비교적 쉽게 이해 가능
  • 하지만 계수의 값들이 왜 그런지 명확하지 않아 분석하기가 매우 어려울 수 있음