[딥러닝 알아듣기] 1.2. 머신 러닝 알고리즘의 구현 과정과 데이터셋

“딥러닝 알아듣기” 시리즈는 딥러닝의 기초 지식을 저만의 방식으로 쉽게 풀어내는 시리즈입니다. 이번 챕터에서는 분류 예제를 통해 머신 러닝 알고리즘의 설계 및 구현 과정을 간단히 알아봅니다.


머신 러닝으로 문제를 풀 때, 학습시킬 알고리즘의 전체적인 구조를 머신 러닝의 모델(Model) 이라고 한다. 머신 러닝 알고리즘을 학습시킨다는 말은 머신 러닝 모델을 학습시킨다는 말과 동일하다. 앞으로는 모델이라는 단어를 적극적으로 사용하도록 하자.

강력한 무기일수록 다루기 어려운 것처럼, 머신 러닝 모댈의 학습도 철저한 설계와 과정 밑에서 이루어져야 최고의 성능을 이끌어낼 수 있다. 이번 장에서는 하나의 간단한 문제 상황을 가정해서, 머신 러닝 모델을 학습하는 과정을 이해해보자. 이 장에서 소개하는 머신 러닝 모델의 개발 과정은, 이 시리즈에서 이후에 다룰 모든 머신 러닝과 딥 러닝 모델에 동일하게 적용된다. 대부분의 머신 러닝 모델이 비슷한 과정으로 학습되기도 한다. 그러니 예제와 함께 머신 러닝 알고리즘 개발의 전체적인 흐름에 익숙해지도록 해보자. 항상 기억하자. 지피지기면 백전백승!

1.2.1. 문제 상황의 인식과 모델 설계

먼저 우리가 머신 러닝으로 풀고자 하는 문제 상황을 하나 정의해보자. 어디까지나 이해를 돕기 위해 가정된 상황이니, 의학적으로 정확하지 않은 부분이 있어도 픽션으로 생각하고 넘어가주면 좋겠다.

우리는 이제부터 의료 보조용 소프트웨어를 만들기 위해서, 개인의 신체적 특징과 병력 데이터를 활용해 가장 발생 위험성이 높은 질병을 찾아주는 머신 러닝 모델을 만들 것이다. 인간에게 발생하는 큰 질병들은 이유 없이 갑자기 생기는 경우가 드물다. 대부분의 큰 질병들은 원인이 된 다른 신체적인 문제가 있거나, 오랫동안 굳어진 생활 습관으로 인해 발생하는 경우가 많다. 예를 들어 흡연을 오랫동안 해 온 사람은 폐암이 발생할 확률이 높을 것이고, 비만과 고혈압 상태로 오래 지내온 사람은 심혈관계 질환이 생길 확률이 남들보다 높을 것이다.

물론 그렇다고 해서 모든 비만 환자가 심혈관 질환으로 고생하는 것은 아니다. 유전적 요인부터 시작해서 수많은 환경적 요인, 과거 병력과 생활 습관의 요인 등이 복합적으로 작용해서 질병을 만들어낼 것이다. 그래서 의학 분야에서는 과거의 환자 데이터들을 모으고 분석하는 일이 매우 중요하다. 비슷한 사례의 환자를 치료했던 경험이 많을 수록, 새로운 환자들에 대해 더 나은 치료법을 제공할 수 있기 때문이다. 그렇다면 우리는 머신 러닝을 활용해서, 의사들이 데이터를 기반으로 더 나은 판단을 할 수 있도록 돕는 모델을 만들어 보자. 편의를 위해 ‘질병 예측 모델’ 이라고 부르겠다.

질병 예측 모델의 전체적인 구조를 설계해보자. 모델 설계의 가장 중요한 부분은 입력출력 의 형태 설계이다. 예상되는 입력과 출력은 아래처럼 생각해볼 수 있다.

  • 모델 입력: 개인의 신체 상태와 관련된 정보가 나열되어 입력
  • 모델 출력: 현재 상태에서 가장 발생 확률이 높은 질병의 이름

우리가 구현할 모델은 신체 상태 데이터를 입력받아서 발생 확률이 가장 높은 질병을 알려줄 것이다. 이 모델을 학습시키기 위해서는, 과거에 질병이 발생했던 환자들의 데이터를 모아서 학습시켜야 한다. 우리의 모델이 심장병이 생길 확률이 높은 사람임을 알려주려면, 심장병이 발병한 수 많은 환자들이 기존에 가지고 있던 신체 상태에 대한 데이터를 대량으로 모아서 모델에게 학습시켜야 할 것이다.

어떤 데이터를 수집할 지 결정했으니, 어떤 구조의 머신 러닝 모델으로 이 문제를 풀어낼 지 결정해보자. ‘예측’ 하는 문제라고 이야기했으나, 사실은 입력된 신체 상태 데이터의 특징을 파악해서 어느 질병과 가장 큰 연관을 가지고 있는 상태인지 구분 하는 문제로도 이해할 수 있다. 이러한 문제를 분류(Classification) 라고 한다. 신체 상태가 심장병에 가까운지, 당뇨에 가까운지 머신 러닝 모델을 통해 분류하는 문제로 보는 것이다.

1.2.2. 데이터 구조 설계

이제 머신 러닝의 구현 과정에서 가장 중요한 과정인 데이터의 설계를 진행해보자. 머신 러닝 모델의 입출력 데이터를 설계할 때, 먼저 모델이 출력할 데이터의 형태와 범위를 결정하는 것이 중요하다. 우리의 모델이 어떤 일을 하고 싶은지 명확하게 정의하는 과정이기도 하기 때문이다.

예측해야 할 질병이 많을수록 모델이 입력 데이터의 특징을 더욱 세세하게 이해해야 한다. 입력되는 데이터의 범위는 비슷한데, 그 정보를 가지고 구분해야 할 질병의 종류는 더 많아졌기 때문이다. 이번 장에서는 어디까지나 간단한 예제 상황이기 때문에 입력되는 신체 상태 정보를 복잡하게 만들지 않을 것이다. 그러므로 예측해내고자 하는 질병도 적당히 적은 개수로 설정해주도록 하자. 아래의 세 개 질병만을 일단 분류해보자. 신체 상태가 건강해서 모든 질병의 발병 가능성이 낮은 경우도 포함한다. 총 네 가지의 분류 카테고리가 존재하는 것이다.

  • 심장병
  • 당뇨
  • 발병 가능성 적음

이제 위의 질병들을 분류해내기 위해서 어떤 신체 상태 데이터들이 필요할지 생각해보자. 일단 세 가지 병은 모두 대표적인 성인병이다. 성인병의 발병과 관련되어 가장 많이 거론되는 원인은 비만 여부, 가족력, 음주 및 흡연 여부 등이다. 신체 상태 입력 데이터에 들어가면 좋을 듯한 정보를 나열해보자.

  • 키 및 몸무게 (비만도 판단을 위함)
  • 연령과 성별
  • 암, 심장병, 당뇨의 가족력
  • 고혈압 환자 여부
  • 음주 및 흡연 여부

대충 이 정도면 세 가지 질병을 구분해 낼 만한 정보들을 모은 것 같다. 음주와 흡연 여부는 정도를 데이터로써 다루기 쉽지 않으므로, 단순 여부로만 따지기로 한다. 키, 몸무게, 연령, 성별 데이터를 제외하면 나머지는 모두 ‘예’와 ‘아니오’로 대답할 수 있는 항목들이다. 아래 그림과 같이 이러한 입력 데이터를 모아서 모델에 넣어 주면 모델은 가장 발병 가능성이 높은 질병이 무엇인지 출력 데이터로써 알려줄 것이다.

<그림 1> 입력 데이터와 출력 데이터 정의

입력 데이터는 각각의 사람에 대해서 키, 몸무게, 연령 등등의 다양한 신체 정보를 가지고 있다. 각각의 데이터는 결과 판단에 서로 다른 영향을 미친다. 나머지 신체 상황이 모두 동일해도, 몸무게가 70kg인 사람과 150kg인 사람은 당뇨 발병 확률이 현저히 차이날 것이다. 이렇게 입력 데이터 내에서 구분되는 값들을 각각의 특징(Feature) 이라고 한다. 우리의 데이터처럼 표(Table) 형태로 나타내어지는 데이터에서는 보통 하나의 열(Column)이 하나의 특징을 포함한다. 우리의 데이터는 발병 가능성이 높은 질병을 예측하기 위해 총 10개의 특징을 가진 입력 데이터를 이용하는 것이다.

데이터의 종류와 구조를 정의했으니, 컴퓨터 알고리즘이 이해할 수 있는 형태로 데이터의 형태를 변환하자. 모델이 문자열을 출력하는 것보다 정수 숫자를 출력하도록 만드는 것이 훨씬 쉽다. 그러므로 출력할 수 있는 각각의 질병 카테고리에 번호를 붙여 모델이 그에 맞는 숫자를 출력하도록 하자. 모델의 출력이 2라면 당뇨 발병 가능성이 높다고 분류한 것이다.

  • 암: 0
  • 심장병: 1
  • 당뇨: 2
  • 발병 가능성 적음: 3
<그림 2> 모델의 입출력 데이터 형태 정의

입력 데이터의 특징 갯수가 많아질수록 분류를 위해 참고할 데이터의 종류가 늘어난다는 의미이다. 그래서 많은 경우 입력의 특징 갯수가 많아지면 머신 러닝 모델의 성능 향상을 기대할 수 있다. 분류할 카테고리가 더 많아져도 상대적으로 잘 분류하게 될 것이다.

하지만 많은 특징을 사용한다고 무조건 머신 러닝 모델의 성능이 좋아지는 것은 아니다. 결과 판단에 중요한 특징 만을 잘 선별해서 사용해야 한다. ‘온라인 게임 레벨’ 이라는 특징은 질병의 발생 확률과 아무런 관계가 없다. 설령 있다고 해도 다른 특징들보다 분류시에 영향력이 크게 떨어진다. 그래서 질병 예측 모델의 입력 데이터에 ‘온라인 게임 레벨’ 특징을 포함하면 모델의 성능이 크게 떨어질 것이다. 어쨌든 우리의 모델은 입력 데이터의 모든 특징에 의한 분류를 배워내려고 한다. 온라인 게임 레벨과 같은 일관되지 않은 데이터가 계속 입력되면 모델의 학습에 혼란을 줄 수 있을 것이다.

그래서 머신 러닝 모델을 학습시키는 과정에서 데이터 설계가 매우 중요하다. 먼저 문제 상황을 분석해서 모델의 출력 범위와 형태를 설정한다. 그리고 수집한 데이터에서 어떤 특징을 살려두고 어떤 특징을 버릴 것인지 결정한다. 특징을 잘 선택해야 모델의 성능이 제대로 발휘될 수 있다. 때문에 머신 러닝 모델을 현실 세계 문제에 적용할 때, 적용할 분야의 전문가 도움이 반드시 필요하다. 우리의 질병 예측 모델도 여기서는 예시로써 간단히 만들었으니 상관없지만, 실제로 병원에 적용하고자 한다면 많은 의사들과 충분히 어떤 특징을 사용할지 논의해보아야 할 것이다.

머신 러닝 모델이 적용되는 분야를 도메인(Domain) 이라고 한다. 질병 예측 모델은 의학 도메인에 적용되는 머신 러닝 모델이다. 그리고 의사와 같이 해당 도메인의 전문가를 도메인 전문가 라고 한다. 어떤 문제에 머신 러닝 모델을 적용해서 풀어내려면, 도메인 전문가와 머신 러닝 엔지니어의 긴밀한 협업이 매우 중요하다.

1.2.3. 데이터셋 수집과 구분

모델에 어떤 데이터를 사용할 것인지 결정했으니 이제 데이터를 수집해야 한다. 신체 정보 데이터를 모을 수 있는 환경에서 최대한 많이 모으는 것이 좋겠다. 아마 현실 세계에서 데이터를 수집하면, 수집하는 때에 우리가 원하는 특징들만 골라서 수집하는 것이 매우 힘들 가능성이 크다. 데이터를 수집하는 과정에서 개인의 신체 정보에 대해 수많은 부가 정보들이 따라올 것이고, 모델에 바로 사용할 수 없는 형태로 모일 것이다. 이렇게 수집된 상태 그대로의 데이터를 로우 데이터(Raw data) 라고도 부른다. 날 것 그대로의 데이터라는 의미이다. 머신 러닝 모델을 학습하려면, 데이터를 수집한 후 우리 모델의 입출력 형태에 맞게 정제 해주는 과정이 필요하다. 문제의 도메인, 수집의 방법에 따라 데이터 정제 방법은 천차만별일 것이다. 상황에 맞는 코드를 적절히 작성해서 데이터를 정제한다. 정제를 완료해 모델 학습에 사용할 준비가 된 데이터들을 데이터셋(Dataset) 이라고 부른다.

수집과 정제 과정을 거치고, 정제한 신체 정보 및 발생 질병 데이터가 10만 건 생겼다고 가정해보자. 우리는 이 데이터셋을 용도에 맞게 구분할 필요가 있다. 머신 러닝 모델은 크게 아래와 같은 과정을 반복적으로 거쳐 학습된다.

  • 훈련 데이터(Training data) 로 모델을 학습시킨다.
  • 학습의 중간중간에, 검증 데이터(Validation data) 를 이용해 학습이 옳은 방향으로 이루어지고 있는지 점검한다.
  • 일정량 이상 학습을 마친 후, 실제 데이터를 의미하는 시험 데이터(Test data) 를 이용해 모델의 성능을 평가한다. 목표 성능에 못 미칠 경우 다시 학습 과정을 반복한다.

전체 데이터를 훈련 데이터, 검중 데이터, 시험 데이터의 세 부분으로 나누고 있다. 각각의 데이터는 위와 같은 학습의 각 과정에 활용된다.

먼저 훈련 데이터를 이용해 모델을 학습시킨다. 한번의 학습에서 모델에게 보여줄 데이터의 갯수를 미리 정해 놓고, 그 만큼의 데이터를 보여주고 학습시킨다.

한 번의 학습 반복이 끝나면, 검증 데이터를 이용해 학습시키고 있는 모델의 현재 성능을 대략 평가해본다. 질병 예측 모델의 경우 검증 데이터에서의 분류 정확도를 구할 것이다. 검증 데이터로의 성능 평가는 모델의 학습 정도를 확인하고, 옳은 방향으로 학습되고 있는지 확인하기 위해 이루어진다.

학습 과정을 어느 정도 마치면, 시험 데이터를 사용해 모델의 학습 결과를 평가한다. 시험 데이터는 학습 과정에서 한 번도 보지 못한 데이터여야 한다. 실제 모델이 활용되는 상황을 가정하고 테스트하는 것이기 때문이다. 이미 학습에 사용되었던 데이터로 테스트하면 정확한 성능 평가가 되지 않을 것이다. 모델의 시험 데이터에서의 성능이 측정되면, 목표 성능에 도달했는지 판단한 후 학습 과정을 더 반복할 것인지 결정한다.

보통의 경우 훈련 데이터를 가장 큰 비율로 사용한다. 훈련 데이터, 검증 데이터, 시험 데이터를 각각 6:2:2 또는 7:1:2 비율로 나누는 등의 선택지가 있을 것이다.

<그림 3> 데이터셋의 구분

데이터셋을 어느 비율로 구분하여 사용하는지 결정하는 일도 매우 중요하다. 훈련 데이터가 너무 적을 경우 학습이 제대로 되지 않을 것이며, 검증 데이터가 너무 적을 경우 학습의 진행도를 제대로 파악하기 어려울 것이다. 시험 데이터가 너무 적을 경우 모델의 정확한 실 성능을 파악할 수 없어 문제가 될 수 있다. 항상 상황에 맞는 비율로 데이터를 나누어주어야 한다.

1.2.4. 모델 구현, 학습과 검증

데이터셋을 준비했으니 이제 학습시킬 모델을 구현할 차례이다. 데이터셋 형태에 맞춘 입출력 형태를 가지는 머신 러닝 모델을 구현하면 될 것이다. 모델의 구현이 완료되면 본격적으로 모델의 학습을 시작한다. 학습은 여러 번의 반복으로 진행된다. 보통 한 번의 학습 반복은 모델이 모든 훈련 데이터셋을 한 바퀴 보는 것을 기준으로 한다. 전체 훈련 데이터셋을 한 번 보았다는 것을 하나의 에폭(Epoch) 이라고 표현하기도 한다.

보통 모델의 학습이 한 번의 에폭을 돌고 난 후에 검증 데이터셋으로 검증을 진행한다. 검증 데이터셋에서의 성능과 출력 경향이 어떤지 확인하고, 검증 결과가 더 좋게 나올 수 있도록 모델과 학습 방향을 수정한다.

그러나 단순히 검증 데이터셋을 나눠 사용하는 것이 문제가 되는 경우도 있다. 전체 데이터셋을 많이 수집하지 못한 등의 이유로, 검증 데이터셋의 크기가 절대적으로 작은 경우에 문제가 된다. 검증 데이터셋의 목적은 학습중인 모델을 잠시 평가해보고, 검증 데이터셋에서의 성능에 따라 학습 방향성을 결정하기 위함이다. 즉 검증을 여러 번 거칠수록 검증 데이터에 대한 성능이 모델의 학습 정도를 평가하는 지표가 된다는 것이다. 검증 데이터셋이 작으면 높은 성능을 보여주기 쉬울 것이고, 학습이 올바른 방향으로 되고 있는지 정확히 알려주지 못할 것이다. 그 조그만한 데이터셋에서만 성능이 잘 나오도록 학습이 진행될 것이기 때문이다.

그래서 검증 데이터셋의 크기가 작은 경우, 교차 검증(Cross Validation) 기법을 사용해서 검증의 신뢰도를 높이기도 한다. 교차 검증은 같은 모델에 대해 여러 검증 데이터셋을 동시에 사용해서 검증의 신뢰도를 높이는 방법이다. 검증 데이터셋을 따로 구분해서 사용하지 않고, 훈련 데이터에서 일정 부분을 여러 번 나누어 여러 번 검증하고 모든 검증 결과를 합친다. 하나의 작은 검증 데이터셋을 사용했을 때보다, 여러 검증 데이터를 동시에 사용해서 검증했으니 확실히 결과를 더 신뢰할 수 있을 것이다. 대표적인 교차 검증의 방법론으로는 K-Fold Cross Validation 등이 있다.

<그림 4> K-Fold Cross Validation

1.2.5. 모델 성능 평가 및 배포

머신 러닝 모델의 학습이 어느 정도 진행되었다고 판단되면, 시험 데이터를 이용해 모델을 평가한다. 시험 데이터를 사용하는 목적은 모델이 학습 과정에서 한번도 보지 못했던(Unseen) 데이터를 입력시켜 실 성능을 파악하기 위함이다.

머신 러닝 모델을 설계하면서 같이 생각해 둔 목표 성능이 있었을 것이다. 시험 데이터에서의 성능이 목표 성능에 도달했는 지 확인해보고, 학습을 더 진행해야 할지 결정한다. 시험 데이터에서의 성능이 부족할 경우, 학습을 더 많이 진행해야 할 것이다. 분석에 따라서 더 많은 훈련 데이터셋을 보강해주어야 할 수도 있고, 모델의 구조 자체를 수정해야 할 수도 있다.

올바른 성능 평가를 위해서, 성능 평가의 방법을 결정하는 것도 중요하다. 어떤 지표(Metric) 을 보고 모델의 성능을 평가할 것인지 결정해야 한다. 학습 못지 않게 중요한 과정이 모델의 평가 과정이다. 보통 문제의 종류에 따라 대표적으로 쓰이는 지표들이 각각 존재한다. 우리의 질병 예측 모델의 성능은 시험 데이터에 대해 평균적으로 얼마나 분류를 잘 했는지에 대한 정확도(Accuracy) 가 제일 좋은 성능 지표이다. 문제에 맞춘 성능 지표를 따로 개발하는 경우도 많다. 이 시리즈에서도 앞으로 정밀도, 재현율 등 수많은 지표들을 공부하고 성능 평가에 사용할 것이다.

시험 데이터에서의 성능이 목표 성능 기준을 넘어섰다면, 학습을 중단하고 실제 문제 해결에 사용해도 괜찮은 수준이라는 뜻일 것이다. 이 때 모델을 배포(Deploy) 할 수 있다. 질병 예측 모델을 사용할 수 있도록 의사용 프로그램에 모델을 심는 작업을 배포 작업으로 볼 수 있다. 웹 어플리케이션에서 결과를 봐야 한다면 웹 서버에 모델을 배포해야 하고, 스마트폰 어플리케이션에 올려야 할 수도 있다. 배포를 제대로 하지 못하면 모델을 아무리 잘 학습시켜도 쓸모가 없기 때문에, 최근의 머신 러닝 분야에선 배포 과정의 유연성이 중요하게 여겨지고 있다. 모델의 배포와 사용자 피드백만 전담으로 처리하는 개발자들도 존재한다.