MLOps

머신러닝 시스템 설계 - Chapter 5. 피처 엔지니어링

kkam99 2023. 10. 10. 20:34
반응형

2014년 논문 Practical lessons from predicting clicks on Ads at Facebook 에서는 올바른 피처를 보유하는 것이 ML모델을 개발하는 데 가장 중요하다고 말함

실제로 모델 개발에 있어 하이퍼파라미터 조정 같은 알고리즘 기법보다 피처 설계가 성능에 더 결정적인 영향을 줌

5.1 학습된 피처 vs. 엔지니어링된 피처

딥러닝이 발전하면서 피처 엔지니어링에 대한 의존도가 많이 줄어듦

딥러닝은 피처를 수작업으로 만들 필요없이 알고리즘에 의해 자동으로 학습되고 추출됨

하지만 모든 피처가 자동으로 학습되는 것도 아니고 ML 프로덕션 환경에서 쓰이는 모델 대부분은 딥러닝 모델이 아님

예를 들어 딥러닝 이전에 자연어 분석을 위해서는 원본 텍스트에서 불용어 제거, 표제어 추출, 줄임말 확장, 구두점 제거, 소문자화, 토큰화, N-gram 등 많은 단계를 거쳐야 함

수작업으로 피처 엔지니어링을 진행하는 경우 도메인에 대한 많은 지식이 필요

딥러닝을 적용하면 표제어, 구두점, 불용어 등에 신경쓰지 않고 원시 텍스트를 단어로 분할하고 (토큰화; tokenization 등) 단어로 어휘를 만들고 one-hot 벡터로 변환

모델은 이로부터 유용한 피처를 추출하는 것부터 학습하게 됨

이런 식으로 딥러닝을 사용하면 피처 엔지니어링 상당 부분이 자동화 가능

5.2 피처 엔지니어링 기법

피처 엔지니어링 기법에는 결측값(missing value) 처리, 스케일링(scaling), 이산화(discretization) 등등 많은 기법이 존재

5.2.1 결측값 처리 (Missing value)

데이터에 결측값이 존재하는 것은 빠르게 알아차릴 수 있음

그러나 결측값마다 유형이 다르다는 사실은 알아차리기 힘들 수도 있음

결측값에는 3가지 유형이 존재

  • 비무작위 결측 (MNAR; Missing not at random)

    결측값이 발생한 이유가 실제 값 자체에 존재

    예를 들어 소득이 결측인 경우 소득이 높은 사람은 결측일 가능성이 높음

  • 무작위 결측 (MAR; Missing at random)

    결측값이 발생한 이유가 값 자체가 아닌 다른 변수에 존재

    예를 들어 성별이 여성인 경우 연령이 결측인 경우가 많음

  • 완전 무작위 결측 (MCAR; Missing completely at random)

    결측값에 패턴이 없는 경우

    완전 무작위 결측은 현실에서 드물게 발생하며 보통은 이유가 있기 때문에 조사가 필요

결측값은 특정 값으로 채우는 대치로 처리하거나 삭제

결측값 삭제 (Deletion)

결측값 삭제는 처리하기 쉬우므로 많이 선호되는 방법

열 삭제, 행 삭제가 가능

열 삭제

누락된 값이 너무 많은 변수를 제거하는 방법

열 삭제는 변수를 통째로 제거하는 방법이므로 중요한 정보를 제거하거나 모델의 정확도를 낮출 수 있다는 단점이 존재함

행 삭제

누락된 값이 있는 샘플을 제거하는 방법

결측값이 완전 무작위(MCAR)이거나 샘플의 비중이 적을 때 유용

데이터 샘플을 제거하면 결측값이 비무작위(MNAR)인 경우 모델이 예측을 수행하는 중요한 정보가 제거될 수 있음 (결측값 자체가 정보를 내포할 수 있으므로)

또한 결측값이 무작위(MAR)인 경우 모델에 편향이 발생할 수 있음

특정 변수의 값에 따라 다른 변수의 값이 결측될 확률이 높은 경우(여성일 경우 연령 등) 해당 값에 대한 예측이 부정확해짐

결측값 대치 (Imputation)

결측값을 삭제하는 대신 특정값으로 채우는 방법

이 ‘특정값’을 결정하는 것이 어려운 문제

일반적으로 통계적 대푯값으로 대치하는 방법이 주로 사용

평균(mean), 최대(max), 최소(min), 중앙값(median), 최빈값(mode) 등을 주로 사용

대치값을 잘못 설정하면 모델의 예측을 방해하는 주요 원인이 될 수 있음 (연령 결측값을 0으로 채우는 등)

가능한 값(데이터에서 존재할 수 있는 값)으로 대치하지 않는 편이 좋은데, 결측 그 자체에 정보가 포함되어 있을 수도 있고 수치를 0으로 채울 경우 0이 의미를 가지고 있을 수도 있음(자녀수를 0으로 채우는 경우 등)

특정 데이터에 대한 결측값을 처리하기 위해 여러 기법들을 동시에 혹은 순서대로 적용할 수 있지만 정답은 없음

결측값을 삭제하면 중요한 정보가 손실되거나 편향이 강조될 수 있음

결측값을 대치하면 데이터에 자신의 편향을 주입하고 데이터에 잡음을 더할 수 있으며 데이터 누수의 위험도 있음

5.2.2 스케일링 (Scaling)

ML모델에 수치형 변수를 넣는 경우 스케일링은 매우 중요한 작업

소득과 연령 두 가지 변수가 있을 때 예측에 유용함과는 상관없이 수치가 더 큰 소득값을 모델은 더 중요하다고 생각할 수 있음

따라서 각 변수들을 유사한 범위로 맞춰주는 작업이 필요함

스케일링은 단순하지만 모델 성능 향상에 크게 도움이 되고 하지 않으면 모델이 엉뚱한 예측을 할 가능성이 높아짐

특히 Gradient boost나 로지스틱 회귀 같은 고전적인 알고리즘에서 이런 경향이 심함

주로 사용하는 스케일링 기법으로는 min-max scaling 이나 표준화(standardization)가 있음

min-max scaling

x=xmin(x)max(x)min(x)x' = \frac{x - min(x)}{max(x) - min(x)}

min-max scaling의 범위는 [0,1]이고 임의의 범위 [a,b] 사이로 조정하려면 아래 공식 사용

x=a+(xmin(x))(ba)max(x)min(x)x' = a + \frac{(x-min(x))(b-a)}{max(x)-min(x)}

(이 책의 필자인 칩 후옌의 경험 상 [-1,1] 범위가 [0,1]보다 잘 동작했다고 함)

이런 스케일링 방법은 변수에 대해 아무런 분포 가정을 하지않을 때도 효과적

변수가 정규 분포를 따른다고 생각되면 평균과 표준 편차를 활용해 표준화를 실시

x=xxˉσx' = \frac{x-\bar{x}}{\sigma}

실무적으로는 비대칭 분포를 따르는 피처가 많음

왜곡을 완화하는 방법으로 일반적으로 로그 변환(log transformation)을 적용할 수 있음

로그 변환 역시 모든 경우에 잘 작동하는 것은 아니고 실제값이 아닌 로그 변환된 값으로 분석하지 않도록 주의 필요함

스케일링에 대한 주의사항으로

  1. 스케일링이 데이터 누수의 원인이 될 수 있음
  1. 전역 통계치가 필요한 경우가 많음

    추론하는 중에는 훈련 중에 얻은 통계치를 재사용해 신규 데이터 스케일링

    신규 데이터가 훈련 데이터의 통계에서 크게 변경되었다면 이전 데이터가 필요없어짐

    따라서 모델을 자주 재훈련하는 것이 중요

5.2.3 이산화 (Discretization)

이산화는 연속형 변수를 불연속 변수로 바꾸는 과정

이산화는 양자화(quantization) 또는 비닝(binning) 이라고 하며 주어진 값에 대한 버킷을 생성함

양자화를 적용하면 모델은 무한한 범주에 대해 훈련할 필요없이 훈련하기 편한 적은 범주로 훈련 가능

이 기법은 훈련 데이터가 제한된 경우에 더 유용

이산화는 연속형 변수만 아니라 이산형 변수에도 적용 가능

여러가지 범주를 하나의 버킷으로 그룹화하여 전체 범주 개수를 줄일 수 있음

이산화는 범주 경계에서 불연속성을 발생시킨다는 단점이 존재

예를 들어 범주가 35,000 이상인 경우 100,000과 35,000은 동일한 값으로 처리되지만 34,999는 완전히 다른 값으로 처리됨

또한 범주의 경계를 설정하는 일도 어려움

변수의 히스토그램을 확인하고 적절한 경계를 선택해야 하며 상식, 기본 분위수, 도메인 지식 등을 활용

5.2.4 범주형 피처 인코딩

실제 프로덕션 환경에서는 범주가 ‘정적’이 아닌 경우가 많음

연령이나 소득과 같은 범주는 시간에 따라 거의 변화하지 않고 총 개수도 정확하게 알고 있는 경우가 많지만 그 외 범주는 시간이 지남에 따라 변화하는 경우가 대다수

시간에 따라 새로운 범주가 추가되는 경우 인코딩할 수가 없는 문제가 발생

이런 문제를 해결하기 위해 새롭게 추가되는 범주를 위한 UNKNOWN 범주 생성

UNKNOWN을 통해 하나로 묶을수 있지만 모델은 이 범주를 학습 과정에서 보지 못했으므로 신규 범주를 결과값으로 예측하지 않는 문제 발생

이렇게 새로운 범주가 계속 생성되는 문제는 여러 도메인에서 빈번하게 발생하지만 적절한 해결책을 찾기 힘듦

이 때 사용할 수 있는 기술이 바로 해싱 트릭(feature hashing, hashing trick)

해싱 트릭은 해시 함수를 사용해 각 범주의 해시 값을 생성하고 이 해시 값을 해당 범주의 인덱스로 사용하는 방법

해시 공간을 지정할 수 있으므로 범주가 총 몇 개 인지 알 필요없이 피처에 대해 인코딩된 값의 개수를 고정 가능

해시 함수의 고전적인 문제는 충돌(hash collision)

두 범주가 동일한 해시값을 가질 수 있으나 UNKNOWN 범주를 사용할 때처럼 항상 신규로 할당되는 것은 아님

연구에 따르면 해시 충돌이 50%가 발생해도 로그 손실은 0.5% 미만으로 증가한다고 함

또한 해시 충돌을 줄이기 위해 충분히 큰 해시 공간을 설정할 수도 있음 (계산부담과 공간부담은 일단 차치하고)

유사한 범주가 서로 가까운 값으로 해시되는 지역 민감 해싱(locality-sensitive-hashing;LSH)도 선택 가능

해싱 트릭은 정석적인 방법은 아니므로 학계에서는 크게 다루지 않는 방법

하지만 업계에서는 실제로 많이 쓰이고 있으며 주요 머신러닝 프레임워크에서도 지원함

해싱 트릭은 특히 연속 학습(온라인 러닝, 프로덕션에 들어오는 데이터로 학습)에 유용

5.2.5 피처 교차

피처 교차는 둘 이상의 피처를 결합해 새로운 피처를 생성하는 기법으로 피처 간의 비선형 관계 모델링에 유용

선형 회귀, 로지스틱 회귀와 같이 비선형 관계를 학습할 수 없는 모델에는 필수적이며 딥러닝에서는 비교적 덜 중요하지만 여전히 매우 유용한 방법

명시적으로 피처 간의 비선형 관계를 만들어주면 신경망에서 비선형 관계를 더 빠르게 학습할 수 있음

피처 교차 기법을 사용할 때 주의할 점은 피처 공간이 매우 커질 수 있다는 점

피처 1, 2가 각각 100가지 값이 있으면 둘을 교차한 피처는 총 1만개의 값을 가지게 됨

따라서 가능한 피처값을 모두 학습하려면 훨씬 많은 데이터가 필요하고 과적합이 발생할 위험도 높음

5.2.6 이산 및 연속 위치 임베딩

위치 임베딩은 텍스트 분석에서 쓰이는 임베딩 방법으로 그 유명한 논문 Attention Is All You Need 에서 소개

일반적인 순환 신경망은 단어가 순차적으로 처리되므로 단어 위치가 암시적으로 입력되지만 트랜스포머와 같은 모델은 단어가 병렬적으로 처리되므로 위치 정보를 모델이 알기 어려움

위치 임베딩을 통해 모델에 단어 위치를 명시적으로 알려 줌

임베딩은 모델 가중치가 업데이트됨에 따라 함께 변경되는 값

하지만 위치 임베딩 값을 고정할 수도 있음

각 위치에 대한 임베딩은 요소 S에 대한 벡터이지만 각 요소는 사인 및 코사인 함수로 정의

(트랜스포머 논문에서는 요소가 짝수 인덱스이면 사인, 홀수 인덱스이면 코사인 함수 사용)

고정 위치 임베딩은 푸리에 피처로 알려진 방식의 특수한 경우

5.3 데이터 누수

데이터 누수(data leakage)는 훈련 데이터셋의 피처 집합으로 레이블 정보가 누수되는 현상

학습 시에는 누수된 데이터로 정답을 쉽게 맞추지만 추론 시에는 해당 정보가 존재하지 않아 성능이 감소

데이터 누수는 대처하기 까다로운 문제로 아래 예시처럼 누수가 분명하지 않은 경우가 많음

코로나19 환자의 중증 여부 판단 모형을 구축할 때 환자가 누워서 찍은 사진과 일어서서 찍은 사진을 혼합해 모델을 구축했더니 모델이 환자의 자세로 코로나 위험을 예측 (통상 누워서 찍은 경우 더 중증이었으므로)

또 다른 사례로 폐 스캔영상으로 암 징후를 예측하는 모델을 구축했더니 데이터를 제공한 A병원에선 성능이 좋았지만 다른 B병원에서는 성능이 좋지 않았음

A병원에서는 환자가 폐암에 걸렸다고 생각하면 더 해상도 좋은 장비로 촬영하고 B병원에서는 무작위로 장비 배정

모델은 훈련 데이터인 A병원 데이터에서 해상도를 사용하여 결과를 예측하는 방법을 학습

데이터 누수는 ML분야를 처음 배우는 사람에게만 생기는 것이 아니라 일반적으로 발생할 수 있지만 커리큘럼에서는 거의 다뤄지지 않는 내용

(캐글 대회에서조차 제공한 데이터에 누수가 있는 경우도 있었다!)

5.3.1 일반적인 원인

시간 대신 무작위로 시간적 상관 데이터를 분할한 경우

데이터를 학습, 검증, 평가 세트로 분할할 때 무작위 분할이 데이터 누수의 원인이 되는 경우가 많음

일반적으로 무작위 분할을 시행하지만 현실에서는 시간 상관관계를 지닌 데이터가 많음을 기억해야 함

데이터에 시간 상관관계가 있으면 데이터가 생성된 시간이 레이블 분포에 영향을 주게 됨

주가, 날씨 같은 전통적인 시계열 데이터가 대표적인 예

상관관계가 명확하지 않은 경우도 있음

예를 들어 추천 노래를 클릭할지 예측하는 경우 클릭 여부는 음악 취향에 더해 그 날의 음악 트렌드에도 민감

특정 날짜가 어느 가수의 기념일이라면 그 가수의 노래를 들을 가능성이 높아짐

이 경우 이 가수의 선택 여부가 학습, 검증, 평가에 동시에 포함된다면 누수가 될 가능성이 높음

데이터에 시간 정보가 포함되어 있을 경우 가능한 시간별로 분할하는 편이 좋음

정답 레이블과 직접적인 연관이 없다하더라도 다른 변수가 시간 상관이 있다면 간접적으로 유추하게 됨

분할 전 스케일링을 수행한 경우

정규화, 표준화 같은 스케일링을 전체 훈련 데이터 대상으로 시행 후 분할한 경우

이 경우 테스트 샘플의 평균과 분산이 훈련 프로세스에 유출되고 모델은 테스트 샘플에 대한 예측을 스케일링

추론 과정에서는 이 정보를 사용할 수 없으므로 성능이 감소하게 됨

항상 스케일링 전에 데이터를 분할하고 학습 데이터의 통계치를 사용해 모든 분할을 스케일링해야함

테스트 분할의 통계치로 결측값을 채운 경우

위의 경우와 마찬가지로 결측값을 대치할 때 전체 데이터 통계량으로 대치한 경우 발생

마찬가지로 데이터를 분할한 후 학습 데이터의 통계량으로 데이터 대치 수행

분할 전 데이터 중복을 제대로 처리하지 않은 경우

데이터에 중복 혹은 거의 중복되는 데이터가 학습, 평가 데이터에 함께 포함되는 경우

데이터 중복은 실무뿐만 아니라 연구용 데이터에서도 흔히 발생하는 문제

이미지 연구 데이터셋으로 유명한 CIFAR-10,100 에서도 중복 존재함

데이터 중복은 데이터 수집 혹은 여러 소스에서 온 데이터를 병합하는 과정에서 주로 발생

또는 데이터 전처리 과정에서 발생하기도 함

데이터 중복을 방지하기 위해 분할 전 분할 후 항상 중복 여부 확인 필요

데이터 오버샘플링은 데이터 분할 후 수행해야 함

그룹 누수

강한 레이블 상관관계를 갖는 데이터 포인트들(그룹)이 서로 다른 분할로 들어가는 경우

예를 들어 연속 사진의 경우 1초 뒤 사진이 다른 분할에 포함되는 경우 등

이런 누수는 데이터 생성 과정에 대한 이해가 없으면 확인하기 쉽지 않음

데이터 생성 과정에서 누수가 생긴 경우

앞선 폐 스캔 영상 사례처럼 장비의 해상도 차이 때문에 누수가 발생할 수도 있음

이런 경우 두 병원의 장비나 절차가 다르다는 사실을 알지 못하면 원인을 파악하기 매우 어려움

이런 누수를 확실히 피할 방법은 없지만 데이터 소스를 추적하고 수집 및 전처리되는 과정을 이해함으로써 위험을 줄일 수는 있음

정규화를 통해 소스가 다른 데이터끼리 동일한 평균과 분산을 갖도록 조정

이미지의 경우 같은 해상도로 정규화하여 해상도에 따른 누수 방지 등

특히 데이터 생성 과정에 많은 지식을 가지고 있는 도메인 전문가의 역할이 중요함

5.3.2 데이터 누수 검출

데이터 누수는 데이터 생성, 수집, 샘플링, 분할, 처리까지 여러 단계에서 발생

따라서 ML프로젝트 전체 수명 주기동안 데이터 누수를 모니터링하는 것이 중요함

타겟 변수(레이블)에 대한 각 피처 또는 피처 집합의 예측 검정력 측정

특정 피처군의 상관관계가 비정상적으로 높다면 해당 피처가 생성되는 방식과 상관관계가 적절한 지 조사 필요

두 피처가 독립적으론 누수를 포함하지 않아도 같이 쓰면 포함할 수 있음

특정 피처나 피처군이 모델에 얼마나 중요한지 측정하기 위해선 절제 연구 수행

해당 피처 제거 시 모델 성능이 크게 저하된다면 해당 피처가 왜 중요한 지 조사 해야함

피처가 방대하다면 전부에 대해 조사할 순 없어도 가장 의심이 되는 영역만으로도 유용함

특히 모델에 추가되는 피처에 유의

해당 피처가 특별히 좋다면 정말 좋은 것인지 아니면 누수가 일어난 것인지 확인해야함

테스트 분할은 신규 피처에 대한 아이디어를 내거나 하이퍼파라미터를 조정하여 모델의 최종 성능을 산출하는 것 외의 목적으로 사용하면 안됨!

5.4 좋은 피처를 설계하는 방법

일반적으로 피처를 추가하면 모델 성능이 향상됨

그러나 피처가 많다고 모델 성능이 항상 좋은 것은 아님

오히려 너무 많으면 아래의 이유로 모델 학습과 서빙에 좋지 않음

  1. 피처가 많을수록 데이터 누수 가능성이 높음
  1. 피처가 너무 많으면 과적합이 발생
  1. 모델을 제공하는데 필요한 메모리가 증가하고 모델을 학습 및 서빙하기 위해 더 비싼 머신과 인스턴스가 필요
  1. 온라인 추론 시 추론 레이턴시가 증가함. 특히 온라인 예측을 위해 원시 데이터에서 데이터 추출이 필요한 경우 더욱 치명적
  1. 쓸모없는 피처는 기술 부채(technical debt)로 작용. 데이터 파이프라인이 변경될 때 영향을 받는 모든 피처가 조정되어야 함

이론적으로 모델에 도움이 안되는 피처는 L1정규화를 통해 제거할 수 있으나 실제로는 깔끔하지 않음

수동으로 피처를 제거하는 것이 모델이 더 빨리 학습하는데 도움이 됨

피처가 모델에 적합한지 평가할 때는 모델에 대한 중요도(피처 중요도)와 본 적 없는 데이터에 대한 일반화를 고려해야함

5.4.1 피처 중요도

피처 중요도를 측정하는 방법은 여러 가지

가장 대표적으로 전통 알고리즘에 포함되어 있는 내장 함수를 사용하는 방법 (사이킷런 함수 대부분에 구현된)

혹은 모델에 상관없는 SHAP 과 같은 기법을 적용할 수 있는데, 특히 SHAP은 모델 전체에 대한 피처 중요도와 동시에 개별 예측에 대한 피처 기여도도 측정할 수 있어 유용

피처 중요도 기법은 올바른 피처를 선택하는데 유용할 뿐 아니라 모델이 내부에서 작동하는 방식을 이해하는데 도움이 돼 해석 가능성에도 좋음

5.4.2 피처 일반화

ML모델의 목표는 이전에 본 적없는 unseen 데이터에 대한 예측이므로 모델에 사용된 피처는 본 적 없는 데이터로 일반화되어야 함

하지만 모든 피처가 동일하게 일반화되기는 어려움

피처의 일반화 측정은 중요도 측정보다는 비과학적이며 통계적 지식 외에 직관과 도메인 지식이 모두 필요

일반화와 관련해서는 피처 커버리지(coverage)와 피처 값 분포에 대한 고려가 필요함

커버리지는 해당 피처에 대한 값이 있는 샘플의 백분율

결측값이 적을수록 커버리지가 높고 결측치가 많으면 일반화할 수 없음

하지만 결측값 그 자체에 정보가 포함되어 있을 경우엔 유용한 경우도 많음

(특정 값이 결측인 경우에 레이블이 전부 A라던가 등등)

피처 커버리지는 훈련 분할과 테스트 분할에서도 다를 수 있고 시간에 따라서도 다를 수 있음

훈련/테스트 분할에서 다른 경우 분할 방식이 타당한지, 데이터 누수는 없는지 확인이 필요함

피처 값에 대한 분포 역시 조사가 필요함

이미 봤던 데이터에 나타나는 값과 본 적 없는 데이터에 대한 값이 겹치지 않는다면 이 피처는 오히려 모델의 성능을 저하하는 역할을 함

피처 일반화 능력과 구체성 사이에는 트레이드오프가 존재

일반화 능력이 뛰어난 피처는 구체적인 정보는 제공하지 못할 수 있음

그러므로 피처 설계 시 두 가지 정보를 동시에 줄 수 있는 적절한 방안 강구 필요

5.5 정리

💡
ML시스템의 성공은 여전히 피처에 달려있음 프로덕션 환경에서 ML을 성공적으로 적용하려면 피처 엔지니어링에 대한 많은 노력이 필요 특히 피처 엔지니어링은 모델이 배포되는 한 계속되는 프로세스임을 기억!
💡
좋은 피처를 설계하는 것은 복잡한 문제이며 정답이 따로 없는 문제 많은 경험을 통해 다양한 피처를 시험해보고 모델에 어떤 영향을 미치는지 관찰이 필요함 도메인 전문가의 지식이나 캐글 우승팀의 피처 설계 방식도 좋은 참고자료가 됨
💡
피처 엔지니어링에 대한 모범 사례 1. 무작위 분할보단 시간별로 학습, 검증, 평가 데이터로 분할 2. 오버샘플링은 분할 후에 수행 3. 데이터 누수를 방지하기 위해 스케일링 역시 분할 후에 수행 4. 스케일링과 결측값 처리는 전체 데이터 대신 분할 데이터의 통계량만 사용 5. 데이터가 생성되고 수집, 처리되는 방식을 이해 (도메인 전문가의 도움 필요) 6. 데이터 계보(lineage) 추적 7. 모델에 대한 피처 중요도 이해 8. 일반화가 잘 되는 피처 사용 9. 모델에서 더 이상 유용하지 않은 피처는 제거

<참고자료 - 머신러닝 시스템 설계>

Uploaded by N2T

반응형