티스토리 뷰

Study/AI

[ML] Data내에서 NaN 데이터 처리하기

생각많은 소심남 2017. 12. 25. 22:48

 가끔 데이터를 외부에서 읽어오다보면 원하지 않는 데이터들이 포함되는 경우가 종종 있다. 예를 들어 전체 결과에 영향을 주는 변수(outlier)가 있는가 하면, 아예 데이터가 없는 경우(NaN)도 존재한다. 이중 NaN을 처리하는 방법에 대해서 잠깐 언급해보고자 한다. 

 내가 생각하는 NaN이 있으면 안 좋은 이유는 딱 한가지, NaN 자체가 Pandas 내에서 mean이나 median을 계산할 때, 그 자체적으로 수행이 안된다는 것이다. 가령 NaN은 내부적으로 np.nan으로 처리되는데 이 값에 어떤 값을 더하거나 빼도 그 결과가 NaN으로 반환되어 정상적인 결과를 얻을 수 없다. 이 때문에 NaN을 배제해야 할 필요성이 생기는데, 이를 해결하는 방법도 여러가지가 있다. 아예 NaN은 배제하고 계산한다던지, 아니면 NaN을 다른 수로 변환해서 계산할 수 있게끔 한다던지 말이다. 그럼 어떤 값으로 바꿔야 전체 결과에는 영향을 미치지 않으면서 연산을 수행할 수 있을까? 딱 mean 값을 넣으면 괜찮지 않을까.. 이를 위해서 sklearn.preprocessing 내에 있는 Imputer를 사용하면 된다. 잠깐 sklearn의 Imputer definition을 살펴보면 다음과 같다.

여기서 우리가 관심있게 봐야할 변수는 missing_values와 strategy 그리고 axis이다. missing value는 말 그대로 dataset 내에서 없는 값에 대한 처리가 어떻게 되어 있는지를 정의하는 부분이고, strategy는 그 없는 값을 어떤 값으로 대체할 것인가에 대한 정의이다. 아마 넣을 수 있는 변수를 보면 알겠지만 strategy에는 mean, median, most_frequent 값을 넣을 수 있다. 그리고 axis는 빈값에 대한 정의를 어떤 기준으로 하겠냐를 정의하는 부분인데 만약 data의 정렬이 row형식이나 column 형식이냐에 따라서 달라질 것이다. 그럼 실제 예시에서 어떻게 사용되는지를 잠깐 살펴보겠다.

  1. # Importing the libraries
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import pandas as pd
  5.  
  6. np.set_printoptions(threshold=np.nan)
  7.  
  8. # Importing the dataset
  9. dataset = pd.read_csv("Data.csv")
  10. = dataset.iloc[:, :-1].values
  11. = dataset.iloc[:, 3].values

와 같이 Data.csv 파일을 읽어오고 데이터의 일부를 X와 y로 나누는 작업을 했다. (참고로 6번째줄은 Ipython상에서 data 일부가 생략되는 현상을 막기위해 넣은 printoption이다. 이렇게 수행하면 ... 으로 표기되는 data가 전체적으로 출력된다.)

 이때 dataset과 X는 다음과 같다.

이렇게 보면 X와 dataset에 각각 한개의 NaN 값이 포함되어 있는 것을 확인할 수 있다. 일단 이 NaN값에 전체값의 평균을 넣기로 하고 data 배열이 column 형식으로 되어 있는 것을 확인한다. 참 모든 sklearn 내의 package의 사용법이 비슷할지는 모르겠지만, 내가 본 대부분의 package는 거의 주어진 package를 우리 dataset에 맞게 맞추고(fit), dataset을 그 맞춰진 package에 넣고 변형(transform) 하는 형식으로 동작하는 것 같았다. 물론 이 Imputer도 역시 imputer object를 하나 생성하고 우리 dataset에 맞게 fit을 한 뒤에, 우리 dataset을 넣고 transform 시키는 과정을 수행한다. 

  1. # Importing the libraries
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import pandas as pd
  5.  
  6. np.set_printoptions(threshold=np.nan)
  7.  
  8. # Importing the dataset
  9. dataset = pd.read_csv("Data.csv")
  10. = dataset.iloc[:, :-1].values
  11. = dataset.iloc[:, 3].values
  12.  
  13. # Taking care of missing data
  14. from sklearn.preprocessing import Imputer
  15. imputer = Imputer(missing_values='NaN', strategy='mean', axis=0)
  16. imputer = imputer.fit(X[:, 1:3])
  17. X[:, 1:3] = imputer.transform(X[:, 1:3])

 첨언을 하자면 NaN이 포함되어 있는 array field가 X의 첫번째와 두번째 column 이었고, python의 array access 문법상 해당 column을 접근하기 위해서는 첫번째 column부터 마지막 column인 1:3이 우리가 접근해야 할 영역이 되겠다. 그러고 난후 원래 data를 새로 생성한 data로 바꿔치기 하는 과정까지 포함되었다. 이에 대한 결과가 반영된 X를 살펴보면 Imputer가 정상적으로 동작했다는 것을 확인할 수 있다. 

지금 위와 같은 작업들 모두를 보통 Data-preprocessing이라고 하는데, 뭔가 data를 가지고 분석하기에 앞서서 이런 전처리과정을 수행해야 원하는 결과를 정상적으로, 빠르게 얻을 수 있다. 


출처 : Machine Learning A-Z : Missing Data

댓글