python의 k-부근법(kNN)에 따라 분류([고교정보과정보Ⅱ] 교사연수용 교재)

14088 단어 교육Pythonk-NN

개시하다


k-인접역법(k-nearest neighbor method, kNN)은 예측하고자 하는 값과 가장 가까운 k에서 다수결을 얻어 예측 값을 결정하는 간단한 머신러닝 알고리즘이다.
다음 설명은 직관적이고 알기 쉽다.
오른쪽 그림에서 미소가 예측하고자 하는 값의 위치를 표시하고 k=3시 부근의 범위를 나타낸다.이런 상황에서 ◆미소 표시의 예측치다.

본고는 교재에서 k-부근법에 따라 분류하여 R이 실시하는 부분을python으로 개작하고자 한다.

교재.


고등학교 정보과 정보Ⅱ 교원 연수용 교재(정편): 문부과학성
제3장 정보 및 데이터 과학 후반부(PDF: 7.6MB)

컨디션

  • ipython
  • Colaboratory - Google Colab
  • 교재에서 언급해야 할 부분


    학습 15 분류 예측: "3. k-부근법에 따라 분류"

    이번 처리 데이터


    교재와 마찬가지로,kaggle에서digit-recognizer의 데이터를 다운로드합니다.
    train.csv를 사용합니다.

    python의 설치 예시와 결과


    트레이닝 데이터 및 테스트 데이터 읽기


    train.csv에는 42000개의 핸드폰 숫자 정보가 저장되어 있으며, 핸드폰 숫자 정보는 1열(label)에서 정해 라벨(정해 숫자), 2열 이후(pixel)에서 784(28)×28) 픽셀의 256 레벨 그레이스케일 레벨 값(0-255).
    여기에는 처음부터 1000개의 훈련 데이터를 테스트 데이터로 100개의 데이터를 사용한다.
    import numpy as np
    import pandas as pd
    from IPython.display import display
    
    mnist = pd.read_csv('/content/train.csv')
    
    mnist_light = mnist.iloc[:1000,:]
    mnist_light_test = mnist.iloc[1000:1100,:]
    
    # 訓練データ
    Y_mnist_light = mnist_light[['label']].values.ravel()
    #display(Y_mnist_light)
    X_mnist_light = mnist_light.drop('label', axis = 1)
    #display(X_mnist_light)
    
    # テストデータ
    Y_mnist_light_test = mnist_light_test[['label']].values.ravel()
    #display(Y_mnist_light_test)
    X_mnist_light_test = mnist_light_test.drop('label', axis = 1)
    #display(X_mnist_light_test)
    
    

    훈련 데이터의 학습과 예측


    k=3시 k-부근법과 훈련 데이터에 따라 훈련한 후 100개의 테스트 데이터에서 예측치를 얻는다.
    테스트 데이터의 label(정해값)과 비교하여 정확한 응답률을 표시합니다.
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn import metrics
    from sklearn.metrics import accuracy_score
    
    # sklearn.neighbors.KNeighborsClassifier使用
    knn = KNeighborsClassifier(n_neighbors = 3)
    knn.fit(X_mnist_light, Y_mnist_light)
    
    # 予測実行
    pred_y = knn.predict(X_mnist_light_test)
    display(pred_y)
    
    #正答確認
    result_compare = pred_y == Y_mnist_light_test
    display(result_compare)
    
    minist_accuracy_score = accuracy_score(Y_mnist_light_test, pred_y)
    
    #正答率
    print(minist_accuracy_score)
    
    실행 결과는 다음과 같습니다.
    array([1, 5, 1, 7, 9, 8, 9, 5, 7, 4, 7, 2, 8, 1, 4, 3, 8, 6, 2, 7, 2, 6,
           7, 8, 1, 8, 8, 1, 9, 0, 9, 4, 6, 6, 8, 2, 3, 5, 4, 5, 4, 1, 3, 7,
           1, 5, 0, 0, 9, 5, 5, 7, 6, 8, 2, 8, 4, 2, 3, 6, 2, 8, 0, 2, 4, 7,
           3, 4, 4, 5, 4, 3, 3, 1, 5, 1, 0, 2, 2, 2, 9, 5, 1, 6, 6, 9, 4, 1,
           7, 2, 2, 0, 7, 0, 6, 8, 0, 5, 7, 4])
    array([ True,  True,  True,  True, False,  True,  True,  True,  True,
            True,  True,  True, False,  True,  True, False,  True,  True,
            True, False,  True,  True,  True,  True,  True,  True,  True,
            True,  True,  True, False, False,  True,  True,  True,  True,
            True,  True,  True,  True,  True,  True,  True,  True,  True,
            True,  True,  True, False,  True, False,  True,  True,  True,
            True,  True,  True,  True,  True,  True,  True,  True, False,
            True,  True,  True,  True,  True,  True,  True,  True, False,
            True,  True,  True,  True,  True,  True,  True,  True,  True,
            True, False,  True,  True,  True,  True,  True,  True,  True,
            True,  True,  True,  True,  True,  True,  True,  True,  True,
            True])
    0.89
    
    정답률은 0.89다.

    실제 잘못된 손글씨 숫자 확인


    테스트 데이터 중 다섯 번째 테스트 데이터가 잘못 식별되었다.
    실제로 잘못된 숫자 확인이 이뤄졌다.
    import matplotlib.pyplot as plt
    
    # テストデータの表示
    fig, axes = plt.subplots(2, 5)
    fig.subplots_adjust(left=0, right=1, bottom=0, top=1.0, hspace=0.1, wspace=0.1)
    for i in range(2):
        for j in range(5):
            axes[i, j].imshow(X_mnist_light_test.values[i*5+j].reshape((28, 28)), cmap='gray')
            axes[i, j].set_xticks([])
            axes[i, j].set_yticks([])
    plt.show()
    
    실행 결과는 다음과 같습니다.

    위 단락의 맨 오른쪽에 있는 핸드폰 숫자는 label(정해치)이 4인데 예측치는 9인 것 같다.눈으로 봐도 9로 판정될 수 있는 숫자다.

    혼합 행렬과 k의 값을 바꿀 때의 정해율의 변화


    세로축은 예측값을 나타내고 가로축은 정확한 라벨의 개수를 나타내는 표를 표시합니다.
    from sklearn.metrics import confusion_matrix
    
    cfm = confusion_matrix(Y_mnist_light_test, pred_y)
    
    print(cfm)
    
    실행 결과는 다음과 같습니다.
    [[ 7  0  0  0  0  0  0  0  0  0]
     [ 0 10  0  0  0  0  0  0  0  0]
     [ 0  0 13  0  0  0  0  1  1  0]
     [ 0  0  0  5  0  1  0  0  0  0]
     [ 0  0  0  0 11  0  0  0  0  1]
     [ 0  0  0  0  0 10  0  0  0  0]
     [ 0  0  0  0  0  0  9  0  0  0]
     [ 1  0  0  0  0  0  0 10  0  1]
     [ 0  0  0  2  0  0  0  0 10  1]
     [ 0  1  0  0  1  0  0  0  0  4]]
    
    다음에 k의 값이 k의 값을 바꾸어 그것이 어디에 적합한지 볼 때 도표로 정답률을 표시합니다.
    n_neighbors_chg_list = []
    
    # n_neighborsを変化させたときのグラフ
    for i in range(1,100):
        # sklearn.neighbors.KNeighborsClassifier使用
        knn_temp = KNeighborsClassifier(n_neighbors = i)
        knn_temp.fit(X_mnist_light, Y_mnist_light)
    
        # 予測実行
        pred_y_temp = knn_temp.predict(X_mnist_light_test)
    
        #正解率
        minist_accuracy_score_temp = accuracy_score(Y_mnist_light_test, pred_y_temp)
    
        #配列に格納
        n_neighbors_chg_list.append(minist_accuracy_score_temp)
    
    plt.plot(n_neighbors_chg_list)
    
    
    실행 결과는 다음과 같습니다.

    일반적으로 k의 값이 크면 편차가 있어도 결과에 영향을 미치지 않기 때문에 소음의 영향을 줄일 수 있지만 분류 경계가 명확하지 않은 경향이 있다.
    훈련 데이터의 수량 등 적당한 k의 값이 바뀌었지만 이번 실험에서는 k가 클수록 정답률이 낮았다.

    소스 코드

    좋은 웹페이지 즐겨찾기