ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] 혼공 머신러닝 + 딥러닝 데이터 표준화의 중요성
    데이터 분석 2022. 4. 11. 22:33
     

    출처 : 혼자 공부하는 머신러닝 + 딥러닝

    데이터 전처리_2

    fish_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, 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]
    fish_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, 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]
    
    # 각 파라미터에 할당 받은 리스트에 인덱스에 맞춰 zip 함수와 같은 역할을 한다
    np.column_stack(([1,2,3],[4,5,6]))
    
    # 데이터의 원소가 물고기의 길이와 무게 값을 가진 배열이 되도록 처리
    fish_data = np.column_stack((fish_length, fish_weight))
    
    # 35개의 1을 원소로 가진 배열 과 14개의 0을 원소로 가진 배열을 concatenate 함수로 하나의 배열로 통합
    fish_target = np.concatenate((np.ones(35), np.zeros(14)))
    
    # 사이킷런의 데이터를 train dataset과 test dataset으로 분리하는 함수
    from sklearn.model_selection import train_test_split
    
    # 기본 test dataset의 비율은 20%, random_state 파라미터는 분리 결과 값을 일관되게 만듦
    train_input, test_input, train_target, test_target = train_test_split(fish_data, fish_target, random_state=42)
    
    print(train_input.shape, test_input.shape) # (36,2) (13, 2)로 나눠짐
    print(train_target.shape, test_target.shape) # (36, ) (13, )로 나눠짐
    
    # stratify 파라미너는 입력한 매개변수의 원소비율을 파악하고,
    # 분리하는 배열들이 파악한 비율과 동일한 비율을 가지도록 한다
    train_input, test_input, train_target, test_target = train_test_split(fish_data, fish_target,
                                                            stratify=fish_target, random_state=42)

    K-최근접 이웃 모델링_2

    # k-최근접 이웃 객체에 train_input과 train_target을 이용하여 학습을 진행하여 모델링
    kn = kn.fit(train_input, train_target) 
    
    # 위의 학습 진행한 모델의 테스트 점수
    kn.score(test_input, test_target) # 1.0
    
    # 모델을 이용하여 test_input을 기반으로 예측값 출력
    kn.predict(test_input) # array([0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0])
    test_target # array([0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0])

    K-최근접 이웃 모델_2를 통한 데이터 분류

    # 도미로 분류하는 것이 적절한 데이터를 예측을 진행 했으나 빙어로 분류했다
     print(kn.predict([[25,150]])) # [0.]
    
    # 산점도 그래프를 출력, 데이터 확인
    plt.scatter(train_input[:,0], train_input[:,1])
    plt.scatter(25, 150, marker='^')
    plt.xlabel('length')
    plt.ylabel('weight')
    plt.show()

    산점도 그래프를 그려 보았을 때도 도미의 데이터들가 가까워 보인다. k-최근점 분류가 가까운 데이터의 분류를 따라가는 알고리즘이란 것을 상기해보면 노란 화살점(25,150)을 빙어로 구분하는 것은 이상하다.

     # kn.kneighbors 함수는 입력된 데이터와 입력된 데이터,
     # 최근접한 데이터 사이의 거리와 최근접한 것으로 인식된 데이터의 인덱스를 할당
     distances, indexes = kn.kneighbors([[25, 150]])
    
    # train data의 데이터를 모두 그래프에 표시
    plt.scatter(train_input[:,0], train_input[:,1]) 
    # 무게 : 25,길이 : 150인 데이터 그래프에 표시
    plt.scatter(25, 150, marker='^') 
    # 인덱스에 할당된 데이터를 그래프에 표시, marker 파라미터 'D'를 통해 표시 모양을 다이아몬드로 지정
    plt.scatter(train_input[indexes,0], train_input[indexes,1], marker='D') 
    plt.xlabel('length')
    plt.ylabel('weight')
    plt.show()

    # 25, 150과 가장 가까운 데이터 5개 출력
    print(train_input[indexes])
    '''
     [[[ 25.4 242. ]
      [ 15.   19.9]
      [ 14.3  19.7]
      [ 13.   12.2]
      [ 12.2  12.2]]]
    '''

    25, 150 데이터와 가까운 데이터 5개 중 4개가 빙어의 데이터인 것을 확인할 수 있었고 이로 인해 빙어로 분류되었다는 것을 파악하였다.

    # # 25, 150 데이터와 가장 가까운 데이터 5개 사이의 거리 출력
    print(distances)
    # [[ 92.00086956 130.48375378 130.73859415 138.32150953 138.39320793]]
    # x, y 축의 한계가 같은 그래프 출력
    plt.scatter(train_input[:,0], train_input[:,1])
    plt.scatter(25,150, marker='^')
    plt.scatter(train_input[indexes,0], train_input[indexes,1], marker='D')
    plt.xlim((0,1000)) # x 축의 한계를 0~1000으로 연장
    plt.xlabel('length')
    plt.ylabel('weight')
    plt.show()

    물고기 무게의 축의 한계와 물고기 길이의 축의 한계를 같게 설정하였을 때 무게의 분포에 비해 길이의 분포는 미미한 것을 파악할 수 있다. 고로 분류에 무게 변수의 영향이 더 크다는 것을 알 수 있다.

    데이터 표준화

    mean= np.mean(train_input, axis=0)
    std=np.std(train_input, axis=0)
    
    train_scaled = (train_input - mean) / std # 표준화 진행
    new = ([25,150] - mean) / std # (25, 150) 데이터에 표준화 진행
    
    plt.scatter(train_scaled[:,0], train_scaled[:,1])
    plt.scatter(new[0], new[1], marker='^')
    plt.xlabel('length')
    plt.ylabel('weight')
    plt.show()

    K-최근접 이웃 모델링_3

    # 표준화 데이터로 모델링
    kn.fit(train_scaled, train_target) 
    
    # test dataset 표준화 진행
    test_scaled = (test_input - mean) / std 
    
    # 표준화 데이터 모델 테스트
    kn.score(test_scaled, test_target) # 1.0
    
    # 표준화한 25,150 데이터 예측, 도미로 분류 됨^^
    print(kn.predict([new])) # [1.]
    
    distances, indexes = kn.kneighbors([new])
    plt.scatter(train_scaled[:,0], train_scaled[:,1])
    plt.scatter(new[0], new[1], marker='^')
    plt.scatter(train_scaled[indexes,0], train_scaled[indexes,1], marker='D')
    plt.xlabel('length')
    plt.ylabel('weight')
    plt.show()

    표준화 데이터로 kneighbores 함수를 실행 시킨 후 최근접 데이터를 산점도 그래프에 출력해보았을 때 표준화된 25, 150 데이터와 최근접한 데이터가 모두 도미로 분류되어 있는 것을 확인할 수 있다. 데이터 분석을 위해서는 각 특성의 영향력의 차이를 고려하여 전처리 과정에서 표준화를 진행한 후 분석을 진행하는 것이 중요하다는 점을 알 수 있다.

    댓글

Designed by Tistory.