본문 바로가기

데이터/머신러닝

Chapter 02-2 데이터 전처리

<해당 글은 혼자 공부하는 머신러닝+딥러닝을 공부하고 정리한 내용입니다.>

1. 넘파이로 데이터 준비하기

#생선 데이터
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]​

 

 

  •  넘파이의 column_stack( )
    import numpy as np​
    
    fish_data=np.column_stack((fish_length,fish_weight))
    print(fish_data[:5])
     

 

  • 넘파이 배열을 출력하면 행과 열을 맞추어 가지런히 정리된 모습을 보여준다.

 

  • np.one( )와 np.zeros( )함수로 원하는 개수의 1과 0을 채운 배열을 만들어 준다.
    print(np.ones(5))​

 

  • 이 두 함수와 np.concatenate( )함수를 사용해 1이 35개인 배열과 0이 14개인 배열을 간단히 만들 수 있다.


2. 사이킷런으로 훈련 세트와 테스트 세트 나누기

  • train_test_split( )함수 : 전달되는 리스트나 배열을 배율에 맞게 훈련 세트와 테스트 세트로 나누어준다. 자체적으로 랜덤 시드를 지정할 수 있는 random_state 매개변수가 있다. 기본적으로 25%를 테스트 세트로 떼어낸다.
    from sklearn.model_selection import train_test_split
    
    #훈련 데이터와 테스트 데이터를 각각 36개와 13개로 나누었다.
    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)​

 

  • test_target에서 도미가 10개, 빙어가 3개로 빙어의 비율이 부족함

 

  • 무작위로 데이터를 나누었을 때 샘플이 골고루 섞이지 않을 수 있다. → stratify 매개변수에 타깃 데이터를 전달하면 클래스 비율에 맞게 데이터를 나눈다.
    train_input, test_input, train_target, test_target =train_test_split(fish_data, fish_target, stratify=fish_target,random_state=42)​

 

  • 데이터 준비 끝!

3. 수상한 도미 한 마리

  • 앞에서 실습한 k-최근접 이웃을 훈련하면 [25,150]을 도미로 예측하지 못함
    from sklearn.neighbors import KNeighborsClassifier
    kn=KNeighborsClassifier()
    kn.fit(train_input, train_target)
    
    print(kn.predict([[25,150]]))
    # 0출력됨​

 

  • 이를 산점도로 확인해보면 다음과 같이 나타남
    #이를 산점도로 확인해보면 다음과 같이 나타남
    
    import matplotlib.pyplot as plt
    plt.scatter(train_input[:,0],train_input[:,1])
    plt.scatter(25,150,marker='^')
    plt.xlabel('length')
    plt.ylabel('weight')
    plt.show()​

 

  • k-근접 이웃 메서드를 통해 확인
    #근처 특성들 확인해보기 
    distances, indexes=kn.kneighbors([[25,150]])
    
    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.xlabel('length')
    plt.ylabel('weight')
    plt.show()​

 

 

  • 문제를 해결하기 위해서는 이웃 샘플까지의 거리를 확인!

 

4. 기준을 맞춰라

  • x축의 범위를 동일하게 0~1,000으로 맞추어 보자
    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')
    
    #x축의 범위 지정
    plt.xlim((0,1000))
    plt.xlabel('length')
    plt.ylabel('weight')
    plt.show()​
    스케일이 다르다
  • 데이터 전처리 : 이런 특성값을 일정한 기준으로 맞추어준다

 

  • 가장 널리 사용하는 전처리 방법 = 표준점수(특성값이 평균에서 표준편차의 몇 배만큼 떨어져 있는지를 나타냄)

 

  • (X-평균)/표준편차
    mean=np.mean(train_input, axis=0)
    std=np.std(train_input,axis=0)
    
    train_scaled=(train_input-mean)/std

 

5. 전처리 데이터로 모델 훈련하기

  • 이를 산점도로 그려보면 다음과 같이 나옴
    plt.scatter(train_scaled[:,0],train_scaled[:,1])
    plt.scatter(25,150,marker='^')
    plt.xlabel('length')
    plt.ylabel('weight')
    plt.show()​
    훈련세트의 평균과 표준편차를 사용하지 않았기 때문이다
  • 훈련세트의 mean, std를 이용해서 변환해주어야 함
    new=([25,150]-mean)/std
    plt.scatter(train_scaled[:,0],train_scaled[:,1])
    plt.scatter(new[0],new[1],marker='^')
    plt.xlabel('length')
    plt.ylabel('weight')
    plt.show()​

x축과 y축의 범위가 -1.5~1.5사이로 바뀌었음

 

  • 훈련을 마치고 테스트 세트로 평가할 때는 수상한 샘플을 훈련 세트의 평균과 표준편차로 변환해야지 같은 비율로 산점도를 그릴 수 있다. 마찬가지로 테스트 세트도 훈련 세트의 평균과 표준편차로 변환해야 한다.
    kn.fit(train_scaled,train_target)
    
    test_scaled=(test_input-mean)/std
    kn.score(test_scaled, test_target)​

 

  • 마지막으로 kneighbors( )함수로 이 샘플의 k-최근접 이웃을 구한 다음 산점도를 그려보면 특성을 표준점수로 바꾸었기 때문에 가장 가까운 이웃에 변화 생김
    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()

 

 

6. 문제해결 과정 - 스케일이 다른 특성처리

  • 두 특성의 스케일이 달랐기 때문에 틀리게 예측
  • 특성을 표준점수로 변환하여 해결

 

scikit-learn
- train_test_split( ) : 훈련 데이터를 훈련 세트와 테스트 세트로 나누는 함수
- kneighbors( ) : k-최근접 이웃 객체의 메서드로 입력한 데이터에 가장 가까운 이웃을 찾아 거리와 이웃 샘플의 인덱스를 반환한다.

'데이터 > 머신러닝' 카테고리의 다른 글

Chapter 03-2 선형 회귀  (0) 2022.02.22
Chapter 03-1 k-최근접 이웃 회귀  (0) 2022.02.20
Chapter 02-1 훈련 세트와 테스트 세트  (0) 2022.02.20
실전 1.4 행렬 인수분해  (0) 2021.07.27
실전 1.3 협업 필터링  (0) 2021.07.27