Data Preprocessing

[ML] 데이터 전처리

Week#4 / Video2 / Reference: Prof.Choi

Definition

데이터의 품질은 데이터 분석의 90%를 좌우한다.
GIGU Garbage In Garbage Out

data preprocessing, 데이터 전처리는 한 마디로 data의 quality를 향상시키는 과정이다. 학습을 위해 모아둔 데이터가 잘 가공된 상태여야 그만큼 결과의 신뢰도가 높아지기 때문이다. 데이터 전처리의 과정은 다음과 같다.

  • 데이터 실수화: 컴퓨터가 이해할 수 있는 값으로 변환

  • 불완전한 데이터 제거: null, NA, NaN 값의 제거

  • 잡음 섞인 데이터 제거: 비상식적인 값, noise의 제거

    가격 데이터에 있는 (-)값, 연령 데이터 중 과도하게 큰 값 등

  • 모순된 데이터 제거

    남성 데이터 중 주민번호가 ‘2’로 시작하는 경우 등

  • 불균형 데이터 해결: Undersampling(과소표집), Oversampling(과대표집)

Techniques

데이터 전처리 기법에는 다음과 같은 주요한 요소들이 존재한다.

  • 데이터 실수화 Data Vectorization
  • 데이터 정제 Data Cleaning
  • 데이터 통합 Data Integration
  • 데이터 축소 Data Reduction
  • 데이터 변환 Data Transformation
  • 데이터 균형 Data Balancing

Data Vectorization

데이터 실수화는 범주형 자료, 텍스트 자료, 이미지 자료 등을 실수로 구성된 형태로 전환하는 것이다. 2차원 자료로 이루어진 vector의 예시로는 [n_sample, n_features]가 있으며, 행렬 혹은 2차원 tensor라 부른다.

  • 자료의 유형
    • 연속형 자료 (Continuous data)
    • 범주형 자료 (Categorical data)
    • 텍스트 자료 (Text data)
범주형 자료의 경우
  • One-hot encoding을 이용한 데이터 실수화

    단어 집합의 크기를 벡터의 차원으로 하고, 표현하고 싶은 단어의 인덱스에 1의 값을 부여하는 반면 다른 인덱스에는 0을 부여하는 단어의 벡터 표현 방식이다.

    onehot

  • Scikit-Learn의 DictVectorizer 함수

    • 범주형 자료를 실수화 하는 함수
    • Input argument: default option (sparse=True)
    1
    2
    3
    4
    5
    6
    7
    x = [{'city':'seoul':'temp':10.0},
         {'city':'Dubai', 'temp':33.5},
         {'city':'LA', 'temp':20.0}] # 범주형 자료
      
    from sklearn.feature_extraction import DictVectorizer
    vec = DictVectorizer(sparse=False) # 함수 호출을 위한 instance 생성
    vec.fit_transform(x) # x를 범주형 수량화 자료로 변환
    
    1
    2
    3
    array([[ 0. ,  0. ,  1. , 10. ],
           [ 1. ,  0. ,  0. , 33.5],
           [ 0. ,  1. ,  0. , 20. ]])
    
  • Sparse Matrix (희소 행렬)

    • 행렬의 값이 대부분 0인 경우

    • 불필요한 0 값으로 인해 메모리 낭비가 심함

    • 행렬의 크기가 커서 연산 시 시간도 많이 소모됨

    • COO / CSR 표현식을 통해 해결 가능

      CSR(Compressed Sparse Row)이 COO형식에 비해 메모리가 적게 들고 빠른 연산이 가능하다.

텍스트 자료의 실수화
  • 단어의 출현 횟수를 이용한 데이터 실수화

    출현 횟수가 정보의 양과 비례하는 것이 아니므로 TF-IDF 기법을 이용해야 한다.

    text

    • TF-IDF(Term Frequency Inverse Document Frequency): 자주 등장하여 분석에 의미를 갖지 못하는 단어의 중요도를 낮추는 기법

      the, a 등의 관사

  • Scikit-Learn의 CountVectorizer 함수

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    text = ['떴다 떴다 비행기 날아라 날아라',
           '높이 높이 날아라 우리 비행기',
           '내가 만든 비행기 날아라 날아라',
           '멀리 멀리 날아라 우리 비행기'] # 텍스트 자료
      
    from sklearn.feature_extraction.text import CountVectorizer
    vec2 = CountVectorizer() # default는 sparse=True
    t = vec2.fit_transform(text).toarray() # sparse=True를 풀고 text를 배열 자료로 변환 (CSR 표현의 압축 풀기)
      
    import pandas as pd
    t1 = pd.DataFrame(t, columns = vec2.get_feature_names())
    t1
    
      날아라 내가 높이 떴다 만든 멀리 비행기 우리
    0 2 0 0 2 0 0 1 0
    1 1 0 2 0 0 0 1 1
    2 2 1 0 0 1 0 1 0
    3 1 0 0 0 0 2 1 1
  • Scikit-Learn의 TfidfVectorizer 함수

    • TF-IDF를 통해 가중치 재계산
    • 높은 빈도에 낮은 가중치를, 낮은 빈도에 높은 가중치를 부여한다.
    1
    2
    3
    4
    5
    6
    from sklearn.feature_extraction.text import TfidfVectorizer
    tfidf = TfidfVectorizer()
    x2 = tfidf.fit_transform(text).toarray() # 가중치 조절
      
    x3 = pd.DataFrame(x2, columns = tfidf.get_feature_names())
    x3
    
      날아라 내가 높이 떴다 만든 멀리 비행기 우리
    0 0.450735 0.000000 0.00000 0.86374 0.000000 0.00000 0.225368 0.000000
    1 0.229589 0.000000 0.87992 0.00000 0.000000 0.00000 0.229589 0.346869
    2 0.569241 0.545415 0.00000 0.00000 0.545415 0.00000 0.284620 0.000000
    3 0.229589 0.000000 0.00000 0.00000 0.000000 0.87992 0.229589 0.346869

Data Cleaning

없는 데이터는 채우고, 잡음 데이터는 제거하고, 모순 데이터를 올바른 데이터로 교정하는 기법이다.

  • 결측 데이터 채우기 (Empty Values)

    • np.nan, npNaN, None

    • mean, median, most frequent value, constant 로 대체하는 기법 사용

      • median의 경우 비교 대상이 되는 값들이 짝수인 경우 중앙 값 2개를 더해 반으로 나눈 값, 홀수인 경우 중앙값으로 대체한다.

      • most_frequent의 경우 최빈수가 하나도 없으면 가장 작은 수를 return한다.
      • constant의 경우 fill_value parameter와 함께 사용하여 지정 값으로 대체할 수 있다.
  • SimpleImputer()

    1
    2
    3
    4
    5
    6
    7
    import numpy as np
      
    mat = [[7, 2, 3], [4, np.nan, 6], [10, 5, 9]]
      
    from sklearn.impute import SimpleImputer
    imp_mean = SimpleImputer(missing_values=np.nan, strategy='mean') # mean 값을 활용하여 결측치 대체
    print(imp_mean.fit_transform(mat))
    
    1
    2
    3
    [[ 7.   2.   3. ]
     [ 4.   3.5  6. ]
     [10.   5.   9. ]]
    

Data Integration

여러 개의 데이터 파일을 하나로 합치는 과정이다. Pandas의 merge() 함수를 사용한다

  • merge()

    1
    2
    3
    4
    5
    6
    7
    import pandas as pd
      
    df1 = pd.DataFrame({'lkey': ['foo', 'bar', 'baz', 'foo'],
                        'value': [1, 2, 3, 5]})
    df2 = pd.DataFrame({'rkey': ['foo', 'bar', 'baz', 'foo'],
                        'value': [5, 6, 7, 8]})
    df1.merge(df2, left_on = 'lkey', right_on='rkey')
    
      key1 value_x key2 value_y
    0 foo 1 foo 5
    1 foo 1 foo 8
    2 foo 5 foo 5
    3 foo 5 foo 8
    4 bar 2 bar 6
    5 baz 3 baz 7

Data Reduction

데이터가 과도하게 큰 경우, 분석 및 학습에 시간이 오래 걸리고 비효율적이기 때문에 데이터의 수를 줄이거나(Sampling), 데이터 차원을 축소하는 작업이다.

Data Transformation

데이터를 정규화하거나, log를 씌우거나, 평균값을 계산하여 사용하거나, 사람 나이 등을 10대, 20대, 30대 등으로 구간화 하는 작업이다. Machine Learning은 data의 feature들을 비교하여 pattern을 찾는데, 이러한 feature 간 scale 차이가 심하면 pattern을 찾는 데 문제가 발생할 수 있다.

  • 데이터 변환법

    • Standardization (표준화): StandardScaler

    • Normalization (정규화): MinmaxScaler

      일반적으로 정규화가 표준화보다 유용하다. 단, 데이터 특성이 bell-shape 이거나 이상치가 있을 경우에는 표준화가 유용하다.

Data Balancing

특정 class의 관측치가 다른 클래스에 비해 매우 낮을 경우 data Imbalance, 데이터 불균형이라 한다. 이를 해소하기 위한 기법으로는 undersampling과 oversampling이 있다.

일반적으로 oversampling이 통계적으로 유용하다고 한다. 추가적으로 decision tree(의사결정나무)와 ensemble(앙상블)은 상대적으로 불균형 자료에 강인한 특성을 보인다.

data-imb

  • Undersampling

    • 다수 클래스의 표본을 임의로 학습 데이터로부터 제거하는 것
  • Oversampling

    • 소수 클래스의 표본을 복제하여 이를 학습 데이터에 추가하는 것

    • SMOTE(Synthetic Minority Oversampling Technique)

    • ADASYN(Adaptive Synthetic Sampling Method)

      sampling

.

Summarize update needed