I can do it!!

He can do! She can do! why cannot me? i can do it!

개발/sk infosec cloud ai 전문가 양성과정

[파이썬 라이브러리를 활용한 머신러닝 #2]

gogoriver 2020. 9. 13. 18:04

해당 게시글은 안드레이스 뭘러의 [Introduction to machine learning with python]을 정리한 내용입니다.

 

2. 지도학습

이 장에서는 지도학습의 유형과, 주의점 그리고 알고리즘에 대해 소개합니다.


  • 분류와 회귀
분류(classification) 회귀(regression)
이진분류(binary) : 예/아니오만 나올 수 있음
다중분류(multiclass) : 붓꽃 데이터와 같이 셋 이상의 클래스
연속적인 숫자(부동소수점수)를 예측하는 것
= 입력 값에 대한 값이 연속적이지 않고 분류되는 결과 = 결과값이 연속성을 가지고 있는 문제
구분 tip! = 출력값에 연속성이 있는가?
- 퍼셉트론
- 로지스틱 회귀
- SVM
- 신경망
- K-최근접 이웃
- 결정트리
- 랜덤 포레스트
- 경사 부스팅 결정트리(Gradient Boosting)
- 선형 회귀
- 라쏘 회귀 / 릿지 회귀 / 일래스틱넷
- 회귀 트리
- SVR
  • 주의점
    1.  일반화
      • 모델이 처음보는 데이터에 대해 정확하게 예측할 수 있으면 이를 훈련 세트에서 테스트 세트로 일반화 되었다고 한다.
    2. 과대적합
      • 가진 정보를 모두 사용해서 너무 복잡한 모델을 만드는 것
      • 복잡한 모델을 만든다면 훈련 세트에만 정확한 모델이 되어버림!
    3. 과소적합
      • 모델이 너무 간단하여 발생
      • 데이터의 면면과 다양성을 잡아내지 못할 것이고, 훈련 세트에도 잘 맞지 않다.
  • 결론 : 모델을 복잡하게 할수록 훈련 데이터에 대해서는 더 정확히 예측할 수 있다. 그러나 너무 복잡해지면 훈련 세트의 각 데이터 포인트에 너무 민감해져 새로운 데이터에 잘 일반화하지 못한다.

ppt내용

<<<< 머신러닝 알고리즘 >>>>

- 분류
: 정답이 비연속적인 클래스, 정답과 입력의 조합을 학습
-> 새로운 데이터 클래스 예측
- 회귀
: 정답이 연속적이며, 정답과 입력의 조합을 학습
-> 새로운 데이터에서 연속하는 값 예측
- 군집화
: 어떤 기준에 따라 데이터를 그룹핑
- 차원축소
: 시각화 또는 계산량 절감을 위해 고차원 데이터
-> 저차원 공간으로 매핑
- 추천
: 사용자가 선호할 만한 품목 제시
- 이상탐지
: 수상한 접근, 행동 감지
- 강화학습
: 바둑처럼 불명확한 환경에서 앞으로의 행동을 선택하는 방법 학습

  • 모델 복잡도와 데이터셋 크기의 관계 
    • 다양성
      • 데이터셋에 다양한 데이터 포인트가 많으수록 과대적합 없이 더 복잡한 모델을 만들 수 있습니다
    • 특성이 적은 데이터셋 = 저차원 데이터셋
    • 특성이 많은 데이터셋 = 고차원 데이터셋

알고리즘

  1. KNeighborsClassifier 분석
    • 방법 및 코드
from sklearn.model_selection import train_test_split

# 0. 데이터 호출
x, y = mglearn.datasets.make_forge 

# 1. 데이터를 훈련세트와 테스트 세트로 나눈다
x_train, x_test, y_train, y_test = train_test_split(x,y, random_state=0)

# 2. Knn을 임포트하고 객체를 만든다.
from sklearn.neighbors import KNeighborsClassifier

# 3. 매개변수 지정
clf = KNeighborsClassifier(n_neighbors=3)

# 4. 훈련세트를 사용하여 분류 모델을 학습
clf.fit(x_train, y_train)

# 5. predict 메서드를 호출해서 예측
print("테스트 세트 예측", clf.predict(x_test))

# 6. score 메서드에 테스트 데이터와 테스트 레이블을 넣어 호출
print("테스트 세트 정확도 : {:.2f}".format(clf.score(x_test, y_test)))
  • 분석
    • 결정경계를 통해 볼 수 있다.
      • 결정경계 : 알고리즘이 클래스 0과 클래스 1로 지정한 영역으로 나뉘는 구분자이다.
fig, axes = plt.subplots(1, 3, figsize=(10, 3))

for n_neighbors, ax in zip([1, 3, 9], axes):
    # fit 메서드는 self 객체를 반환합니다.
    # 그래서 객체 생성과 fit 메서드를 한 줄에 쓸 수 있습니다.
    clf = KNeighborsClassifier(n_neighbors=n_neighbors).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_neighbors))
    ax.set_xlabel("특성 0")
    ax.set_ylabel("특성 1")
axes[0].legend(loc=3)

위 경정경계를 보면 n_neighbors가 9일때 곡선이 부드러워진다. 이렇게 부드러운 모델은 단순한 모델을 의미한다. 따라서 이러한 경우에는 이웃의 수를 낮게 잡아야지 복잡한 모델로 구분할 수 있다는 것이다. 

from sklearn.datasets import load_breast_cancer

cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
   cancer.data, cancer.target, stratify=cancer.target, random_state=66)

training_accuracy = []
test_accuracy = []
# 1에서 10까지 n_neighbors를 적용
neighbors_settings = range(1, 11)

for n_neighbors in neighbors_settings:
    # 모델 생성
    clf = KNeighborsClassifier(n_neighbors=n_neighbors)
    clf.fit(X_train, y_train)
    # 훈련 세트 정확도 저장
    training_accuracy.append(clf.score(X_train, y_train))
    # 일반화 정확도 저장
    test_accuracy.append(clf.score(X_test, y_test))

plt.plot(neighbors_settings, training_accuracy, label="훈련 정확도")
plt.plot(neighbors_settings, test_accuracy, label="테스트 정확도")
plt.ylabel("정확도")
plt.xlabel("n_neighbors")
plt.legend()

  • 위 그래프를 통해 우리는 과대적합과 과소적합의 특징을 볼 수 있다.
    • 최근접 이웃의 수가 하나일 때는 훈련 데이터에 대한 예측이 완벽하다
    • 하지만 이웃의 수가 늘어나면 모델은 단순해지고 훈련 데이터의 정확도는 줄어든다
    • 이것은 1-최근접 이웃이 모델을 너무 복잡하게 만든다는 것을 설명한다
    • 반대로 이웃을 10개 사용했을 때는 모델이 너무 단순해서 정확도는 더 나빠진다.

(1) knn의 회귀

  • : knn은 우리가 분류라고 처음에 구분했지만 회귀 분석에도 쓰인다.
n_neighbors=1 n_neighbors=1
target : 가장 가까운 이웃 target : 이웃 간의 평균
  • KNeighborsRegressor과 KNeighborsClassifier의 코드는 비슷합니다.
from sklearn.neighbors import KNeighborsRegressor

X, y = mglearn.datasets.make_wave(n_samples=40)

# wave 데이터셋을 훈련 세트와 테스트 세트로 나눕니다.
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

# 이웃의 수를 3으로 하여 모델의 객체를 만듭니다.
reg = KNeighborsRegressor(n_neighbors=3)
# 훈련 데이터와 타깃을 사용하여 모델을 학습시킵니다.
reg.fit(X_train, y_train)

print("테스트 세트 예측:\n{}".format(reg.predict(X_test)))

# 결과값
# 테스트 세트 예측:
# [-0.054 0.357 1.137 -1.894 -1.139 -1.631 0.357 0.912 -0.447 -1.139]

print("테스트 세트 R^2: {:.2f}".format(reg.score(X_test, y_test)))

# 결과값
# 테스트 세트 R^2: 0.83
  • 위 R2는 결정계수라고한다.
    • 즉, 회귀모델에서 예측의 적합도를 0과 1사이의 값으로 계산한 것이다. 1은 예측이 완벽한 경우이고, 0은 평균으로만 예측하는 모델의 경우이다. 
    • 여기서 R2는 설명력, R squre이라고도 합니다.
  • KNN의 매개변수
    1. 데이터 포인트의 거리를 재는 방법
      • 일반적으로 유클리디안 거리 방식을 활용
        • 거리공식 : 유클리디안/ 맨하튼/ 민코프스키 / 표준화 거리 / 마할라노비스
    2. 이웃의 수
      • 실제로 이웃의 수는 3~5개 정도로 적을 때 잘 작동하지만, 이 매개변수는 잘 조정해야한다!
  • knn의 장단점
장점 단점
이해하기 매우 쉽다 & 빠르게 만들 수 있다 훈련세트가 크면 예측이 느려진다
조정(option)을 주지 않아도 대체로 좋은 성능 발휘 데이터를 전처리하는 과정이 중요하다
복잡한 알고리즘을 적용하기 전에 시도 good 특성의 수가 많으면 잘 작동 x
  특성 값 대부분이 0인 데이터셋과는 잘 작동 x
결론>
k-최근접 이웃 알고리즘이 이해하긴 쉽지만, 예측이 느리고 많은 특성을 처리하는 능력이 부족해 현업에서는 잘 쓰지 않는다. 
이러한 단점을 보완한 것이 선형 모델이다.