ML 엔지니어에게는 유저로 부터 수집된 여러 데이터들이 주어집니다. 이러한 데이터들 중에는 유저의 실수 혹은 서버의 오류와 같은 문제들로 인해 나쁜 데이터가 있을 수 있습니다. ML 엔지니어들은 일반적인 데이터의 상황과 다른 나쁜 데이터를 찾아 정제하는 과정을 수행하여야 합니다.


이번 포스트에서는 나쁜 데이터를 정제하는 방법에 대해서 다뤄보도록 하겠습니다.


특성 값 조정(Scaling feature values)

조정(Scaling)이란, 수집된 특성 값을 0~1 또는 -1~+1의 표준 범위로 변화하는 것을 말합니다. 만약 특성이 하나인 데이터 세트에서는 조정(Scaling)하는 과정이 불필요하겠지만, 데이터 세트가 여러 특성으로 구성되어 있다면 특성 조정(Feature Scaling)을 통해 다음과 같은 이점을 누릴 수 있습니다.


  • 더 빠르게 경사하강법이 수렴함
  • 'NaN(Not a Number) 트랩'이 방지됨
  • 모델이 특성의 적절한 가중치를 익히는데 도움이 됨
     

모든 특성을 동일한 범위로 할 필요는 없습니다. 예를 들어 특성 A는 -1~+1, 특성 B는 -3~+3으로 조정해도 큰 문제는 없습니다. 하지만 특성 B만 -1000~+1000과 같이 너무 큰 차이가 나게 설정을 하면 모델이 적절한 가중치를 찾지 어려울 것입니다.


극단적 이상점 처리(Handling extreme outliers)

우리에게 주어지는 데이터 중에 비이상적으로 튀는 값이 있을 수 있습니다. 아래의 예시는 1인당 몇 개의 방을 가지고 있는지를 나타내는 그래프입니다.

위의 그림을 보면, 1인당 평균 방의 개수가 50개인 유독 튀는 한 점을 볼 수 있습니다. 이러한 데이터는 데이터 수집 단계에서 유저 혹은 서버의 문제로 인해 발생한 이상점입니다.


이러한 극단적 이상점이 주는 영향을 최소화하는 방법은 두 가지가 있습니다.

  • 모든 값에 로그를 취해(Logarithmic scaling) 값의 범주를 줄임
  • 특정 값에서 잘라(Clipping), 이를 넘어서는 값은 잘라낸 값으로 인식함

왼쪽의 그림은 모든 값에 로그를 취해 전체 값의 범주를 줄인 모습입니다. 오른쪽 그림은 원래의 데이터 중 4가 넘는 값을 잘라내어 모두 4로 인식시킨 모습입니다.


비닝(Binning)

한국의 위도에 따른 상대적인 주택 분포를 나타내는 데이터가 아래의 그림과 같이 주어졌다고 생각해 보겠습니다.

주어진 데이터에서 위도(Latitude)는 부동 소수점 값입니다. 하지만, 이 모델에서 위도는 주택 수와의 선형적인 관계가 없기 때문에(위도를 나타내는 숫자와 주택 수는 아무런 관계가 없음으로), 위도를 부동 소수점 특성(floating-point value)으로 표현할 수 없습니다.


예를 들어, 위도 35도에 위치한 주택이 위도 34도에 위치한 주택보다 35/34 만큼 싸거나 비싸지는 않습니다. 그러나 각각의 위도 값은 주택 가격을 예측하는 좋은 지표가 될 수 있습니다.


위도를 부동 소수점 값이 아닌, 하나의 지표로 이용하기 위해서 여러 '빈(Bin)'으로 나누겠습니다.

Binning 이란, 연속적인 하나의 특성을 Bin이라고 하는 그룹의 특성으로 변환하는 작업.(연속적인 값을 일정한 크기의 범주로 나누는 것)


위의 그림은 위도를 11개의 빈(Bin)으로 나눈 것(LatitudeBin1, LatitudeBin2, ..., LatitudeBin11) 입니다. 이렇게 하면 위도 32.6도를 다음과 같이 원-핫 벡터로 표현 할 수 있습니다.

[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]


이렇게 비닝(Binning)을 이용하면 모델에서 각 위도에 따라 완전히 다른 가중치를 학습시킬 수 있습니다.


스크러빙(Scrubbing)

ML을 진행하면서 우리에게 다루는 데이터로 100% 신뢰할 수 있는 데이터만 주어지지는 않을 것 입니다. 아마 다음과 같은 문제를 갖고 있는 데이터 세트를 주로 접하게 될 것입니다.

  • 값 누락(Omitted Value): 유저가 실수로 연령 정보를 입력하지 않았을 수도 있습니다.
  • 중복 예(Duplicate Examples): 서버에서 같은 정보를 실수로 두 번 업로드 했을 수도 있습니다.
  • 잘못 된 라벨(Bad Labels): 사용자가 고양이 사진에 실수로 강아지 라벨을 지정했을 수도 있습니다.
  • 잘못된 특성 값(Bad Feature Values): 사용자가 숫자를 실수로 입력했을 수도 있습니다.
일반적으로 위와 같은 잘 못된 예를 발견하면 데이터를 삭제하는 데이터 세트 수정과정을 거침니다. 값 누락과, 중복 예 같은 경우 간단한 프로그램을 통해 탐지 하기 용이하지만, 잘못 된 라벨, 잘못 된 특성 값을 탐지하기는 매우 까다롭습니다.

철저한 데이터 파악

철저한 데이터를 파악을 위해 다음의 규칙을 항상 상기하여야 합니다.

  • 정상적인 데이터가 어떠한 모습이어야 하는지 항상 생각하자
  • 데이터가 예상과 일치하는지 확인하고, 그렇지 않다면 그 이유를 파악하자
  • 학습 데이터가 대시보드 등의 다른 소스와 일치하는지 확인하자


이번 포스트를 통해서 우리는 수집된 데이터를 어떻게 정제하여 머신러닝에게 학습시킬 지, 특성을 추출하는 방법에 대해서 이야기해 보겠습니다.


원시 데이터를 특성에 맵핑(Mapping Raw Data to Features)


위의 그림에서 왼쪽 부분은 수집된 데이터의 원본인 원시 데이터(Raw Data)입니다. 오른쪽은 실수 벡터로 표현된 특성 벡터(Feature Vector)입니다. 이렇게 원시 데이터로 부터 머신러닝에 적합한 데이터(모델을 학습 시킬 예)로 정제하는 것을 특성 추출(Feature Engineering)이라고 합니다.


보통 머신러닝 프로그래머는 특성을 추출하는데 전체 시간의 75% 정도를 할애합니다.


숫자 값 맵핑(Mapping numeric values)

머신러닝의 모델을 학습 시킬 때 부동 소수점 값을 이용하므로 원시 데이터가 정수 및 부동 소수점인 경우 따로 인코딩을 할 필요는 없습니다.

위의 그림과 같이 이미 실수인 num_rooms의 값을 오른쪽과 같이 6.0의 부동 소수점의 값으로 변환할 필요는 없습니다.


문자열 값 맵핑

머신러닝에서는 문자열 값은 학습할 수 없는 데이터입니다. 그래서 우리는 특성 추출(Feature Engineering)을 통해 필요한 문자열의 값을 숫자로 변환할 필요가 있습니다.



위와 같이 우리가 학습하고 싶은 문자열만 1로 설정하고 다른 문자열을 0으로 하는 원-핫 인코딩 방식으로 치환합니다.


원-핫 인코딩(One-Hot Encoding)이란?

일반적으로 문자열을 표현할 때 사용하는 방식으로, 하나의 요소만 1로 설정하고, 다른 요소들은 모두 0인 벡터를 말합니다.


범주형 값 매핑(Mapping categorical values)

범주형이란 배열로 표현되는 특성을 말하며, 인덱스와 같은 숫자로 치환하여 맵핑 합니다. 아래와 같은 나라 이름이 주어졌다고 하겠습니다.

주어진 나라를 나타내는 숫자로 치환하여 사용할 수 있을 겁니다. 아래 처럼 말이죠.

  • Netherlands => 0
  • Belgium => 1
  • Luxembourg => 2

하지만, 머신러닝 모델에서는 일반적으로 각 특성을 별도의 Boolean 값으로 표현 합니다. 예를 들면, 위의 나라 이름이 아래 처럼 표현됩니다.

  • x1: Is Netherlands? (True or False)
  • x2: Is Belgium? (True or False)
  • x3: Is Luxembourg? (True or False)


앞의 포스트를 통해 우리는 일반화를 하기 위해서는 주어진 데이터 세트를 두 개의 하위 세트(학습 세트와 테스트 세트)로 나눠야 한다고 했습니다.


학습 세트와 데이터 세트의 개념

  • 학습 세트(Training Set): 모델을 학습시키기 위한 데이터 세트의 일부분
  • 테스트 세트(Test Set): 모델을 테스트하기 위한 데이터 세트의 일부분

그렇다면 주어진 데이터 세트를 학습 세트와 테스트 세트로 나눌 때 몇 대 몇의 비율로 나누는 것이 좋을까요?


데이터 분할


보통 학습 세트와 테스트 세트로 나눌 때 보통 8:2의 비율이 되게 데이터 세트를 분할 합니다. 이는 데이터 분석자의 편의에 따라 임의로 조절이 가능합니다. 테스트 세트는 반드시 다음의 두 가지 조건을 만족해야 합니다.


테스트 세트의 조건

  • 통계적으로 유의미한 결과를 도출할 만큼 테스트 데이터가 커야 한다.
  • 데이터 세트를 전체적으로 나타내야 한다.
    => 테스트 세트가 한 쪽에 치우치치 않고 학습 세트와 같은 특징을 가지도록 선별해야 한다.

유의 사항: 테스트 데이터로 학습하지 말 것!

모델을 학습 시킬 때 주의해야 할 것이 있습니다. 바로 테스트 데이터로 모델을 학습시키지 않는다는 것입니다. 모델 학습은 학습 세트로만 진행하며 테스트 데이터는 일반화가 잘 되었는지 확인하는 척도로만 사용되어야만 합니다.


만약 모델의 예측 결과가 이상할 정도로 좋은 결과가 나온다면 실수로 테스트 세트로 학습을 시킨 것은 아닌지, 학습 세트에 테스트 세트가 들어간 것은 아닌지 확인을 해보아야 합니다.


학습 세트와 테스트 세트를 통해 일반화된 좋은 모델을 선택하는 과정


여기서 모델을 조정한다는 것은 초매개변수인 학습률(Learning Rate) 조절, 특성(Feature)의 추가 삭제, 완전히 새로운 모델 설계와 같이 모델에서 가능한 모든 요소를 조정하는 것을 의미합니다.

학습과 손실

  • 학습(Training):
    Label이 있는 데이터로부터 모델을 학습시켜 적절한 가중치(Weight)와 편향(Bias)를 찾는 것
  • 손실(Loss):
    예측한 값과 실제 값간의 차이를 의미하며, 잘못된 예측에 대한 벌점과 같음. 모델의 예측이 실제 데이터보다 차이가 많이 날 수록 손실은 커지게 됨.

모델 학습의 목표: 모든 예(Example)에 대해서 가장 작은 손실(Loss)을 갖는 가중치(Weight)와 편향(Bias)의 집합을 찾는 것


위의 그래프에서 파란선은 예측(Prediction)을, 빨간선은 손실(Loss)를 의미합니다. 빨간색 선의 길이가 비교적 짧은 왼쪽 그래프가 오른쪽 그래프보다 더 좋은 예측을 하는 모델입니다.



제곱 손실(Squared Loss)

손실을 표현하는 함수 중 가장 잘 알려진 제곱 손실 함수는 손실 값을 양수로 표현하기 위해 각 손실에 제곱을 취해 모든 손실을 더한 것을 말합니다.


제곱 손실을 이용할 경우에는 손실의 차이를 양수로 다 더해 손실의 총 크기를 알기 쉽다는 장점이 있지만, 입력된 x의 개수가 다른 두 모델의 대해 손실 정도를 비교하기 어렵다는 단점이 있습니다. 이러한 단점을 보안하기 위해 실제로는 평균 제곱 오차(Mean Square Error)를 주로 사용합니다.



평균 제곱 오차(Mean Square Error)

예시의 수가 다른 두 모델을 비교할 수 없는 제곱 손실의 단점을 보완하는 방법이며, 아래의 식으로 표현할 수 있습니다.

  • (x, y): 모델 학습에 사용되는 예(Example)
    - x: 모델이 예측하는데 사용되는 특징(Feature)
    - y: 라벨(Label)
  • prediction(x): 특징(x)와 가중치의 곱과 편향값의 합으로 된 함수 => y' = b + w*x
  • D: 라벨이 있는 예가 포함된 데이터 세트
  • N: D에 포함된 예의 수


+ Recent posts