4.3 데이터 전처리, 특성 공학, 특성 학습

모델 평가 외에도 모델 개발로 들어가기 전에 우리가 넘어야 할 중요한 질문이 있습니다. 신경망에 입력 데이터와 타깃 데이터를 주입하기 전에 어떻게 준비해야 할까요? 많은 데이터 전처리와 특성 공학 기법은 특정 도메인에 종속적입니다(예를 들어 텍스트 데이터나 이미지 데이터에 특화되어 있습니다). 이후 장에서 실전 문제를 보면서 이에 대해 다루겠습니다. 여기서는 모든 종류의 데이터에 공통되는 기본 사항을 살펴보겠습니다.

4.3.1 신경망을 위한 데이터 전처리

데이터 전처리 목적은 주어진 원본 데이터를 신경망에 적용하기 쉽도록 만드는 것입니다. 벡터화(vectorization), 정규화(normalization), 누락된 값 다루기, 특성 추출 등이 포함됩니다.

벡터화

신경망에서 모든 입력과 타깃은 부동 소수 데이터로 이루어진 텐서여야 합니다(또는 특정 경우에 정수로 이루어진 텐서입니다). 사운드, 이미지, 텍스트 등 처리해야 할 것이 무엇이든지 먼저 텐서로 변환해야 합니다. 이 단계를 데이터 벡터화(data vectorization)라고 합니다. 예를 들어 이전에 나온 2개의 텍스트 분류 예에서 텍스트를 (단어 시퀀스를 의미하는) 정수 리스트로 변환했습니다. 그다음 원-핫 인코딩을 사용하여 float32 타입의 데이터로 이루어진 텐서로 바꾸었습니다. 숫자 이미지 분류와 주택 가격 예측의 예에서는 이미 데이터가 벡터 형태로 주어졌으므로 이 단계를 건너뛰었습니다.

값 정규화

숫자 이미지 분류 예에서 이미지 데이터를 그레이스케일 인코딩인 0~255 사이의 정수로 인코딩했습니다. 이 데이터를 네트워크에 주입하기 전에 float32 타입으로 변경하고 255로 나누어서 최종적으로 0~1 사이의 부동 소수 값으로 만들었습니다. 주택 가격을 예측할 때는 특성들의 범위가 제각각이었습니다. 어떤 특성은 작은 부동 소수 값이고 다른 특성은 매우 큰 정수 값을 가졌습니다. 이 데이터를 네트워크에 주입하기 전에 각 특성을 독립적으로 정규화하여 평균이 0이고 표준 편차가 1이 되도록 만들었습니다.

일반적으로 비교적 큰 값(예를 들어 네트워크의 가중치 초깃값보다 훨씬 큰 여러 자릿수를 가진 정수)이나 균일하지 않은 데이터(예를 들어 한 특성의 범위는 0~1이고 다른 특성은 100~200인 데이터)를 신경망에 주입하는 것은 위험합니다. 이렇게 하면 업데이트할 그래디언트가 커져 네트워크가 수렴하는 것을 방해합니다. 네트워크를 쉽게 학습시키려면 데이터가 다음 특징을 따라야 합니다.

  • 작은 값을 취합니다. 일반적으로 대부분의 값이 0~1 사이여야 합니다.
  • 균일해야 합니다. 즉 모든 특성이 대체로 비슷한 범위를 가져야 합니다.

추가적으로 다음에 나오는 엄격한 정규화 방법은 꼭 필수적이지는 않지만(예를 들어 숫자 이미지 분류 예에서는 사용하지 않았습니다) 자주 사용되고 도움이 될 수 있습니다.

  • 각 특성별로 평균이 0이 되도록 정규화합니다.
  • 각 특성별로 표준 편차가 1이 되도록 정규화합니다.

넘파이 배열에서 하는 방법은 간단합니다.1

# x가 (샘플, 특성) 크기인 2D 행렬이라고 가정합니다.
x -= x.mean(axis=0)
x /= x.std(axis=0)

누락된 값 다루기

이따금 데이터에 값이 누락된 경우가 있습니다. 예를 들어 주택 가격 예측 문제에서 첫 번째 특성(데이터에서 인덱스가 0인 컬럼)은 1인당 범죄율입니다. 이 특성이 모든 샘플에 들어 있지 않으면 어떻게 될까요? 훈련 데이터나 테스트 데이터에 누락된 값이 포함됩니다.

일반적으로 신경망에서 0이 사전에 정의된 의미 있는 값이 아니라면 누락된 값을 0으로 입력해도 괜찮습니다. 네트워크가 0이 누락된 데이터를 의미한다는 것을 학습하면 이 값을 무시하기 시작할 것입니다.2

테스트 데이터에 누락된 값이 포함될 가능성이 있다고 가정합시다. 하지만 네트워크가 누락된 값이 없는 데이터에서 훈련되었다면 이 네트워크는 누락된 값을 무시하는 법을 알지 못합니다! 이런 경우에는 누락된 값이 있는 훈련 샘플을 고의적으로 만들어야 합니다. 훈련 샘플의 일부를 여러 벌 복사해서 테스트 데이터에서 빠질 것 같은 특성을 제거합니다.3

4.3.2 특성 공학

특성 공학은 데이터와 머신 러닝 알고리즘(여기에서는 신경망)에 관한 지식을 사용하는 단계입니다. 모델에 데이터를 주입하기 전에 (학습이 아닌) 하드코딩된 변환을 적용하여 알고리즘이 더 잘 수행되도록 만들어 줍니다. 많은 경우에 머신 러닝 모델이 임의의 데이터로부터 완벽한 학습을 한다고 기대하기는 어렵습니다. 모델이 수월하게 작업할 수 있는 어떤 방식으로 데이터가 표현될 필요가 있습니다.

이해하기 쉬운 예를 하나 살펴보죠. 시계 이미지를 입력으로 받고 하루의 시간을 출력하는 모델을 개발한다고 가정합시다(그림 4-3 참고).

이미지의 원본 픽셀을 입력으로 사용한다면 어려운 머신 러닝 문제가 될 것입니다. 이를 해결하려면 합성곱 신경망이 필요할 것이고 이 네트워크를 훈련하기 위해 꽤 많은 컴퓨팅 자원도 필요합니다.

나타낼 수 없음 그림 4-3. 시계의 시간을 읽기 위한 특성 공학

고수준에서 이 문제를 이해하고 있다면(우리는 시계에서 시간을 읽는 방법을 알고 있습니다) 머신 러닝 알고리즘을 위해 훨씬 더 좋은 입력 특성을 만들 수 있습니다. 예를 들어 시계 바늘의 검은색 픽셀을 따라 각 바늘 끝의 (x, y) 좌표를 출력하는 간단한 파이썬 스크립트를 만듭니다. 그다음 머신 러닝 알고리즘이 이 좌표와 적절한 시각을 연결하도록 쉽게 학습될 수 있습니다.

이보다 더 좋은 특성을 만들 수도 있습니다. 좌표를 바꾸어 (x, y) 포인트를 이미지 중심에 대한 극좌표로 나타낼 수 있습니다. 이제 각 시계 바늘의 각도가 입력됩니다. 이렇게 특성을 준비하면 문제가 너무 쉬워져서 머신 러닝이 전혀 필요하지 않습니다. 간단한 반올림 연산과 딕셔너리 참조만으로 하루의 시간을 추정하기 충분합니다.

이것이 특성 공학의 핵심입니다. 특성을 더 간단한 방식으로 표현하여 문제를 쉽게 만듭니다. 일반적으로 해당 문제를 아주 잘 이해하고 있어야 합니다.

딥러닝 이전에는 특성 공학이 아주 중요했습니다. 전통적인 얕은 학습 방법의 알고리즘들은 스스로 유용한 특성을 학습할 만큼 충분히 넓은 가설 공간을 가지고 있지 않습니다. 알고리즘에 데이터를 표현하는 방식에 성공 여부가 달려 있습니다. 예를 들어 합성곱 신경망이 MNIST 숫자 이미지 분류 문제를 해결하기 전까지 전형적인 해결책은 하드코딩된 특성을 사용하는 것이었습니다. 숫자 이미지에 있는 동심원의 수, 이미지에 있는 숫자의 높이, 픽셀 값의 히스토그램(histogram) 등입니다.

다행히 최근 딥러닝은 대부분 특성 공학이 필요하지 않습니다. 신경망이 자동으로 원본 데이터에서 유용한 특성을 추출할 수 있기 때문입니다. 그렇다면 심층 신경망을 사용할 때는 특성 공학에 대해 신경 쓰지 않아도 될까요? 두 가지 이유로 그렇지 않습니다.

  • 좋은 특성은 적은 자원을 사용하여 문제를 더 멋지게 풀어낼 수 있습니다. 예를 들어 시계 바늘을 읽는 문제에 합성곱 신경망을 사용하는 것은 어울리지 않습니다.
  • 좋은 특성은 더 적은 데이터로 문제를 풀 수 있습니다. 딥러닝 모델이 스스로 특성을 학습하는 능력은 가용한 훈련 데이터가 많을 때 발휘됩니다. 샘플의 개수가 적다면 특성에 있는 정보가 매우 중요해집니다.
  1. 코드 3-25에서 했던 것과 동일하지만, 훈련 세트에 적용한 평균과 표준 편차를 기록하지 않았기 때문에 테스트 세트에 적용할 수 없습니다. 반드시 훈련 세트에 적용한 전처리 기준으로 테스트 세트에 적용해야 합니다. 이와 마찬가지로 교차 검증 안에서도 훈련 데이터에 적용한 전처리 기준으로 검증 데이터를 변환해야 합니다. 이렇게 하려면 전처리 단계가 미리 수행되어서는 안 되고 교차 검증 안으로 들어가야 합니다. 사이킷런의 Pipeline 클래스를 사용하면 전처리 단계를 손쉽게 교차 검증 반복 안에 포함시킬 수 있습니다. 

  2. 훈련 세트에 누락된 값을 해당 특성의 평균 또는 중간 값으로 대체하기로 했다면 계산된 평균 또는 중간 값을 기록해 놓아야 합니다. 테스트 세트에서 해당 특성에 누락된 값이 있다면 훈련 세트에서 계산한 값으로 채웁니다. 마찬가지로 교차 검증 단계 안에서 훈련 데이터에서 계산한 평균 또는 중간 값이 검증 데이터에 적용되어야 합니다. 일반적으로 어떤 방법(0, 평균, 중간 값)이 주어진 문제에 적합한지 직관적으로 알기 어렵습니다. 교차 검증으로 모두 확인해 보는 것이 좋습니다. 

  3. 훈련 데이터에 누락된 값이 있는 샘플이 적다면 테스트 세트를 떼어 놓기 전에 이 샘플들을 제외시킬 수 있습니다. 또는 누락된 값이 있는 특성이 덜 중요하다고 판단된다면 이 특성을 모두 제외시킬 수도 있습니다. 

댓글남기기