ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 지도학습 | 알고리즘 - KNN KNeighborsClassifier 분석
    Machine Learning/ML with Python Library 2024. 2. 7. 00:01

    2D 데이터셋같은 경우, 모든 테스트 포인트들의 예측을 xy 평면에 그려볼 수 있다. 어떤지점을 어떤 Class로 예측하는지 한눈에 보기 좋다. 그렇게 색을 칠하면, 알고리즘이 클래스를 1과 0으로 나누는 결정 경계(Decision Boundry)를 만들어내는것을 볼 수 있다. 이전에 사용했던 데이터로 이 결정 경계를 그려보자. 1-NN, 3-NN, 그리고 9-NN을 그려서 특징을 파악해보았다.

     

    먼저, 필요한 패키지를 설치 후 Import 했다.

    !pip install mglearn
    import mglearn
    import matplotlib.pyplot as plt

     

     

    그리고 이웃의 갯수가 1, 3, 9일때마다 어떤 Decision Boundry가 그려지는지 파악했다.

    from sklearn.model_selection import train_test_split
    from sklearn.neighbors import KNeighborsClassifier
    x, y = mglearn.datasets.make_forge()
    
    fig, axes = plt.subplots(1, 3, figsize=(10, 3))
    
    for n_neighbors, ax in zip([1, 3, 9], axes):
      # fit method return self object
      # So you can write one line code for object creation and fit method
      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("{} Neighbors".format(n_neighbors))
      ax.set_xlabel("Feature 0")
      ax.set_xlabel("Feature 1")
    
    axes[0].legend(loc=3)

     

    결과는 아래와 같았다.

    1, 3, 9-NN Decision Boundry

     

    이웃을 1개만 선택했을때는 훈련 데이터에 가깝게 따라가고 있고, 이웃의 수를 늘릴수록 결정 경계가 더 smooth 해졌다. 즉, 이웃을 적게 사용할수록 모델의 복잡도가 높아지고, 많이 사용하면 낮아진다. 그렇다면, 훈련 데이터 전체를 이웃의 수로 지정하면 어떻게 될까?

    from sklearn.model_selection import train_test_split
    from sklearn.neighbors import KNeighborsClassifier
    x, y = mglearn.datasets.make_forge()
    
    fig, axes = plt.subplots(1, 4, figsize=(10, 3))
    
    for n_neighbors, ax in zip([1, 3, 9, 26], axes):
      # fit method return self object
      # So you can write one line code for object creation and fit method
      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("{} Neighbors".format(n_neighbors))
      ax.set_xlabel("Feature 0")
      ax.set_ylabel("Feature 1")
    
    axes[0].legend(loc=4)

     

     

     

    파랑색(0) 클래스가 이겼고, 모두가 같은 이웃(파란색)을 갖게 되었다. 의미없는 모델이겠지만, 모두 같은 이웃을 가지게 되었다.

     

    모델의 복잡도와 일반화(Generalization)에 대해 다시 한번 생각해보자. 실제 유방암 데이터셋을 가져와서 사용하도록 한다. 지난번 데이터셋에 대해 논의했을 때 처럼, 훈련 세트와 테스트 세트를 나눠서 성능을 평가해보자. 필요한 패키지나 함수도 import 했다.

    from sklearn.datasets import load_breast_cancer
    from sklearn.model_selection import train_test_split
    from sklearn.neighbors import KNeighborsClassifier
    
    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
    )

     

    그리고 K=1 부터 K=10까지 모델을 생성해서 score를 이용해 일반화와 훈련 정확도를 계산해서, plot에 그려보자.

    training_accuracy = []
    test_accuracy = []
    
    # 1 - 10 KNN
    neighboars_settings = range(1, 11)
    
    for n_neighbors in neighboars_settings:
      # Create Model
      clf = KNeighborsClassifier(n_neighbors=n_neighbors)
      clf.fit(x_train, y_train)
    
      # Save Training Set Accuracy
      training_accuracy.append(clf.score(x_train, y_train))
    
      # Save Generalization Accuracy
      test_accuracy.append(clf.score(x_test, y_test))
    
    
    plt.plot(neighboars_settings, training_accuracy, label="Training Accuracy")
    plt.plot(neighboars_settings, test_accuracy, label="Test Accuracy")
    plt.ylabel("Accuracy")
    plt.xlabel("n_neighbors")
    plt.legend()

     

     

     

    과대적합(overfitting)과 과소적합(underfitting)의 특징을 확인할 수 있었다. 이웃의 수가 적을수록 모델이 복잡해지기 때문에, 그래프가 뒤집힌 형태이다. 훈련 데이터에 대한 예측은 완벽했다. 하지만, 이웃의 수가 늘어나면 모델은 단순해지고 훈련 데이터의 정확도는 줄어든다. 하지만, 이웃을 하나 사용한 테스트 세트의 정확도는 이웃을 많이 사용했을 때보다 낮았다. 이는 1-NN 모델이 너무 복잡하게 만든다는 것을 설명해준다. 반대로 이웃을 10개 사용했을 때는 모델이 너무 단순해서 정확도가 다시 하향 곡선을 그려냈다. 정확도가 가장 좋을 때는 중간정도인 여섯개를 사용한 경우였다.

     

     

    Reference

    https://colab.research.google.com/drive/1fzSiPpwbTUplw6G0PJSpGaVBWx5CEMIZ?usp=sharing

     

    _02_supervised_machine_learning.ipynb

    Colaboratory notebook

    colab.research.google.com

    https://www.yes24.com/Product/Goods/42806875

     

    파이썬 라이브러리를 활용한 머신러닝 - 예스24

    사이킷런 핵심 개발자에게 배우는 머신러닝 이론과 구현 현업에서 머신러닝을 연구하고 인공지능 서비스를 개발하기 위해 꼭 학위를 받을 필요는 없다. 사이킷런(scikit-learn)과 같은 훌륭한 머신

    www.yes24.com

     

    댓글

Designed by Tistory.