사업 모티프2/인물

이은조, ml 서비스 개발시 고려사항

무말랭이 2022. 3. 10. 13:30

가급적 외부에 공개되는 글을 쓸 때는 최대한 정제된 흐름으로 글을 쓰려고 하는데, 최근에는 정제 과정에서 진행이 잘 안돼 글감이 누적되고 있습니다. 그래서 정리가 안된 글이라도 강제 배출해 보면 진전이 있지 않을까 싶어 옮겨 봅니다.
(아래 글도 원래 초안은 2019년에 쓴 글인데 계속 마무리 정리가 안되던 글이네요)

--------------------------------------------------

<ML 서비스 개발 시 고려 사항>
1) 서비스 대상과 목표를 명확히 정의하기
  기계 학습을 이용해 뭔가를 해보려면 우선 예측 대상과 예측 모델을 어떻게 사용할 것인지 활용 방안 및 목표가 명확해야 한다. 예측 대상은 레이블을 결정하고, 활용 방안 및 목표는 모델의 평가 방법을 결정한다. 예를 들어, '주가를 예측하겠다.' 는 건 좋은 목표가 아니다. 구체적으로 어느 시점의 주가를 예측할 것인지, 이렇게 예측한 주가 추정치를 이용해서 무엇을 할 것인지 실행 전략이 명확히 정의되어야 한다.

  대개의 경우 '정확한 예측' 은 좋은 목표가 아니다. 가령, '내일의 주가를 최대한 정확하게 예측하겠다.' 고 목표를 정할 경우 실제 쓸모 없는 모델이 되기 쉽다. 이를 테면, RMSE가 최소가 되도록 내일의 주가를 예측하는 가장 단순한 모델은 y(t) = y(t-1) 이다. 대개의 경우 오늘의 주가는 전날 수치에서 크게 벗어나지 않기 때문이다. 그러나 이것은 RMSE는 최소로 만들 수 있지만 아무 쓸모가 없는 모델이다. 유용한 모델을 만들려면, 실행 전략을 고려했을 때 기대 이익을 최대로 하는 목표를 먼저 정의해야 한다. 최소한 '오늘보다 내일 주가가 오른다고 예측되면 매수하고, 내린다고 예측되면 매도하는 전략을 취할 경우 기대 이익이 최대가 되는 모델을 만들겠다.' 가 되어야 한다.

  따라서 실전 서비스에 적용할 예측 모델은 일반적인 모델 정확도를 측정하는 방법으로 평가해서는 안 된다. 일반적인 모델 정확도를 측정하는 방법이란, accuracy, F1 score, AUC, RMSE 등 우리가 흔히 논문에서 사용하는 방법을 말한다. 이건  범용적으로 모델의 예측 성능을 측정할 때 많이 사용하는 방법이지만, 현실 서비스에서는 적합한 방법이 아니다. 현실 서비스에 사용한 모델의 유용성을 판단하는데 이런 방법을 사용하는 것은 마치 상용 시스템에 들어갈 알고리즘 로직을 평가하는데 Big-O notation 을 이용하는 것과 같다. 실전에서는 조건과 활용 목적에 따라 비용 대비 기대 이익을 기반으로 평가해야 한다. 이를 위해선 목표가 명확해야 한다.

2) 사용할 데이터 검토
  목표가 정해졌으면 이 목표를 충족하기 위해 사용할 수 있는 데이터가 어떤 것이 있는지 검토해야 한다. 이 때 가장 먼저 해야 할 것은 내가 사용할 수 있는 데이터가 목표를 달성하는데 가능한 데이터인지이다. 이것을 판단하려면 경험과 이론이 필요하다. 가령, 내일의 주가를 예측하기 위해 내가 사용할 수 있는 데이터가 과거 주가 정보 밖에 없다면 이것은 불가능한 임무이므로 과감히 포기해야 한다. 주가는 random walk 이며 과거의 시계열 정보 만을 이용해서 미래의 random walk 를 예측하는 것은 불가능하다. 물론 이렇게 명확하게 판단하기 어려운 경우도 있다. 이런 경우 필요한 것이 분석가와 도메인 전문가의 경험과 지식이다.

  더 나아가 여기서 필요한 것이 탐사 분석이다. 그런데 대개의 경우 우리는 프로젝트를 하기로 결정한 후 탐사 분석을 수행한다. 탐사 분석 역시 비용이 필요하기 때문에 프로젝트를 하기로 결정하기 전에 미리 수행한다는 것은 현실적으로 그리 쉽지 않다. 하지만 적어도 탐사 분석 결과에 따라 프로젝트를 더 진행해야 할지 말지를 결정할 필요는 있다. 즉, 탐사 분석은 일종의 POC 같은 역할이 되어야 한다.

  예를 들어, 최근에 우리는 한 보안 솔루션에서 남기는 로그 데이터를 이용해서 PC 사용자들의 사용 패턴을 분석하고 이를 통해 비정상 패턴을 탐지하는 서비스를 만드는 것이 가능한지에 대한 컨셉 검증을 위해 탐사 분석을 하였다. 이를 위해 Doc2Vec 을 써서 아주 간단한 임베딩 알고리즘을 만든 후, 각 PC 사용자의 과거 데이터를 학습하였고 이렇게 만든 임베딩 모델을 써서 학습 시점 이후에 발생된 보안 로그 데이터를 이용해 각 PC 사용자를 분류할 수 있는지 간단한 분석 및 모델링을 수행하였다.

  이러한 초반 분석 단계에서는 모델링에 과도하게 노력을 투입할 필요가 없다. 그 동안의 내 경험 상 실제 데이터가 예측 모델을 만드는데 충분한 정보를 담고 있는 경우라면, 아주 간단한 모델링 만으로도 어느 정도 좋은 결과가 나온다. 이 단계에서 아무런 신호를 찾을 수 없는데 엄청 복잡한 전처리 작업과 최신 알고리즘을 적용한다고 갑자기 예측이 잘 되는 경우는 극히 드물다. 오히려 첫 시도에서 꽤 나쁘지 않은 성능이 나왔는데, 그 이후에 여러 가지 튜닝을 해도 잘 개선이 안 되는 경우가 더 빈번하다.

  정리하자면, 만약 내가 지금 보유한 데이터에 대해 나이브한 방법을 써서 적당히 괜찮은 (이를 테면 100점 만점에 70점 정도가 되는) 결과가 나오지 않는다면, 아무리 더 좋은 학습 알고리즘을 쓰더라도 서비스에 사용될 수준의 좋은 모델을 만들 가능성은 거의 없다고 보면 된다. SOTA 논문을 구현할 시간에 목표에 맞는 데이터가 더 없는지 검토하는 것이 더 맞는 선택이다.

3) 라벨링
  내가 예측하려는 대상의 라벨 정보를 충분히 많이, 그리고 적은 비용으로 구할 수 있는지 검토한다. 대개 적절한 라벨 정보를 충분히 확보하기가 어렵다. 라벨 정보를 어떻게 확보할 수 있는지, 라벨 정보가 충분히 신뢰할 수 있는지, 서비스 적용 시점에서 지속적으로 라벨 정보 확보가 가능한지 등을 파악해야 한다 (이게 가장 중요하다).

  특히, 내가 최근에 경험한 바에 따르면 라벨 정보의 신뢰성 문제가 서비스 구축에서 큰 골치거리이다. 따라서 1) 신뢰도를 어떻게 측정할지, 2) 라벨의 신뢰도를 높이려면 어떻게 해야할지, 3) 낮은 신뢰도의 라벨 정보를 이용해서 어떻게 신뢰도 높은 서비스를 구축할 것인지를 해결하는 것은 실전 ML 서비스를 구축할 때 가장 먼저 극복해야 할 문제이다. Weak supervised learning 이나 human-in-the-loop 와 관련된 다양한 연구들이 있지만 아직까지는 연구 단계인 것 같다.  

  심지어 라벨링 대상에 대한 정의를 어떻게 할 것인지 부터가 이슈가 되는 경우도 있다. 예를 들어, 비구독 (non-contractual setting) 서비스에서 고객의 이탈을 정의하는 것을 생각해 보자. 비구독 서비스에서는 유저의 가입/해지 절차가 없기 때문에 유저의 잔존/이탈 상태가 불명확하다. 대개 '서비스를 오랫동안 이용하지 않는 경우' 를 '이탈'로 정의하는데. 얼마나 오랫동안 이용하지 않는 경우를 이탈로 정의해야 할까? 물론 이를 위한 통계적인 방법도 있다. 가장 널리 알려진 것은 Negative Binomial 분포를 이용하는 것이다. 이 때 서비스를 오랫동안 이용하지 않는 만큼 서비스 제공자 입장에서는 손해이기 때문에 미 사용 기간에 따른 손해를 고려하여 기대 이익을 최대로 하는 이탈 정의 기간을 선정하는 것이 필요하다. 이것을 연구한 논문이 있다. 라벨 기준을 명확히 하는 문제는 '예측 대상과 목표를 명확히 하는 문제'와 연결하여 고려해야 한다.

  또 다른 예로는 맞춤형 광고 서비스가 있다. 예전에 어떤 회사에서 소개한 사례를 본 적이 있다. A라는 물건에 대한 맞춤형 광고 서비스를 만들기 위해 기존에 A라는 물건을 산 고객의 구매 이전 활동 정보를 피처로 활용하여 예측 모델을 만든 사례를 들었다. 즉, 멀리 않은 미래에 A라는 물건을 살 고객의 패턴을 학습한 예측 모델을 만든 후 이 모델에서 A 물건을 구매할 예정인 고객을 예측하여 그들에게 맞춤형 광고를 하겠다는 것이다. 그러나 이것은 비용을 고려하지 않은 잘못된 방법이다. 여기서 라벨링한 것은 P(구매 | 과거 활동 정보) 이다. 즉, 이들은 광고와 상관없이 해당 제품을 구매할 고객들이란 뜻이다. 실제 타겟 광고가 되어야 할 고객은 P(구매 | 타겟 광고) 이다. 당연하게도 P(구매 | 타겟 광고) 확률을 예측하기 위한 라벨링을 하는 것은 어려운 문제이다. 하지만 쉬운 라벨링을 위해 만든 위와 같은 모델은 오히려 기대 이익을 높이기 보다는 불필요한 비용만 발생시킬 수 있다.

4) 모델링
  많은 분석가들이 모델링 단계에서 잘못된 방법을 사용한다. 모델링의 목적은 결국 데이터에서 잡음을 최대한 제거하여 정보를 최대한 단순화 시키겠다는 것이다. 일종의 데이터에 대한 손실 압축이다. 우리가 음악을 들을 때 많이 사용하는 MP3 같은 걸 생각해 보면 쉽다. 음원 데이터를 효율적으로 압축할 수 있는 이유는 일반적인 사람들이 음악을 듣는데 불필요한 주파수 대역의 소리 신호를 과감히 제거하기 때문이다. 즉, MP3 압축 알고리즘에는 '일반적으로 음악을 듣는데 필요한 주파수 대역은 x ~ y Hz 사이이다.' 라는 가정이 깔려 있는 것이다.

  우리가 사용하는 모든 기계 학습 알고리즘에도 이런 가정이 깔려 있다. 따라서 우리가 데이터를 모델링할 때는 이 데이터를 효과적으로 압축하기 위해 버려야 할 잡음이 가진 특징이 무엇인지에 대한 가정이 필요하다. 이 가정이 잘못되면 잘못된 학습 알고리즘을 사용하게 되고, 그러면 잘못된 모델이 만들어 지는 것이다. MP3 는 인간에게는 좋은 오디오 압축 포맷이지만, 돌고래에게는 최악의 포맷일 것이다.

  이러한 데이터에 대한 가정은 당연히 사용하는 데이터의 종류나 적용 분야, 모델링의 목표 등에 따라 달라진다. 따라서 내가 보유한 데이터가 어떤 특징을 갖고 어떤 분야에서 어떤 목적으로 사용될 것인지에 따라 적절한 모델링 방법은 달라져야 한다. 그리고 이걸 판단하기 위해 하는 것이 탐사 분석이다.

  그런데 많은 분석가들이 대개 탐사 분석을 해보라고 하면 그저 데이터의 한계 분포, pair-wise scatter plot 정도를 그려보고 해당 내용을 정리하는 데에 그친다. 혹은 현황 분석과 탐사 분석을 혼동하는 경우도 많다. 탐사 분석의 목표는 어떤 모델링 기법을 사용하는게 적당한지를 파악하는 것이어야 한다. 그런데 대개 탐사 분석이 형식적인 과정에 그치곤 한다.

  그 외에 모델링이나 탐사 분석 단계에서 다음과 같은 여러 가지 실수를 한다.  

4-1) 데이터 전처리 및 모델 설계 단계
  - 다중공선성을 제거하겠다며 선형 상관 계수를 이용하여 변수 선택하기
  초보자들이 하는 대표적인 실수이다. 다중 공선성은 선형 모델의 회귀 계수를 불안정하게 만드는 문제가 있다. 이게 의미하는 것은 '다중공선성은 나쁜 것이다!' 가 아니라 1) 내가 만드는 모델이 선형 모델이 아니고, 2) 모델링의 목적이 (회귀 계수 추정이 아니라) 결과에 대한 예측이라면, 다중공선성 문제를 고민할 필요가 없다는 것이다.  

  - 실제 예측 모델은 뉴럴 네트워크인데 랜덤 포레스트의 피처 중요도를 기반으로 변수 선택하기
  이것은 예시로 든 것인데 쉽게 말해 실제 사용하는 모델링 방법과 다른 모델을 이용해서 피처 중요도를 파악한 후 이를 이용해 중요 변수를 선택하거나 예측 결과를 해석하는 것을 의미한다. 이것이 아주 틀린 방법은 아니지만, 그리 좋은 방법도 아니라 생각한다. 왜냐하면 트리 모델과 뉴럴 네트워크는 모델을 생성하는 방식이 많이 다르기 때문이다.

  - 변수 간의 상호 작용을 고려하지 않고 단일 변수 기준으로만 종속변수와의 관계나 분포를 확인하여 피처 선택하기
  많은 분석가들이 탐사 분석 및 모델링 과정에서 변수 간의 상호 작용을 간과하곤 한다. 하지만 변수 간에 서로 독립이라는 가정은 대부분의 현실 데이터에서는 맞지 않는 매우 비현실적인 가정이다.
  내가 생각하기에 랜덤 포레스트나 XGBoost 같은 트리 기반 모델이 캐글에서 그렇게 높은 성능을 보여준 이유 중 하나는 이들이 변수 간의 상호 작용을 비교적 잘 모델링 해주기 때문이 아닌가 싶다.
  그런데 많은 경우 분석가들은 탐사 분석 과정에서 종속 변수와 독립 변수 간의 관계를 2차원 scatter plot 으로 확인하거나 독립변수 별, 레이블 별 데이터 분포를 확인해 보는 정도에서 더 나아가지 않는다. 특히 선형 회귀 분석을 할 때 많은 이들이 interaction term 을 잘 만들지 않으며, 잔차 분석 시에도 여러 변수를 복합적으로 보는 시도를 잘 하지 않는다. 물론 상호 작용을 확인하는 것은 인지적으로 쉽지 않지만 그럼에도 불구하고 꼭 필요한 작업이다.

  - 데이터의 한계 분포 (marginal distribution) 을 보고 오차 분포를 추정하여 변수 변환
  이것 역시 변수 간의 관계를 간과해서 하는 실수이다. 모든 변수들은 다른 변수의 영향을 받기 때문에, 한계 분포와 오차 분포는 매우 다르다. 한계 분포가 왼쪽으로 쏠려 있는 경우 로그 변환을 통해 종형 분포로 만드는 경우가 종종 있는데 잘못된 방법이다 (그런데 과거 많은 책들이나 인터넷 자료들이 이런 것을 장려하곤 했다).

4-2) 학습 및 평가 단계
  - 학습/평가 데이터를 잘못 분할하여 사용하기
  초보자들이 가장 자주 하는 실수이다. 여기에도 여러 가지 경우가 있는데, 우선 동일 대상에서 생성된 여러 데이터를 임의 샘플링하여 학습과 테스트 데이터로 나눠서 사용하는 경우가 있다. 이를 테면, X-ray 사진을 보고 암을 판단하는 분류 모델을 만들 때 학습/테스트 데이터를 나누는 기준은 사람이 되어야 한다. 그런데 그냥 사진 단위로 학습/테스트 데이터를 나눠서 동일인이 찍은 여러 장의 X-ray 사진을 학습 데이터와 테스트 데이터에 임의 샘플링하여 사용하는 실수를 하는 것이다.
  혹은 시간의 변화에 따른 패턴의 변화를 고려하지 않고 학습/평가 데이터를 사용하는 경우도 있다. 이를 테면, 고객의 이탈을 예측하는데 동일 시점의 데이터를 이용해서 학습과 평가에 사용하는 것이다. 실전에서 모델을 사용할 때는 학습 데이터의 시점에서 한참이 지난 후에야 가능하다. 따라서 정확한 평가를 위해선 평가 데이터의 데이터 생성 시점이 학습 데이터 생성 시점보다 한참 뒤가 되어야 한다 (최소한 라벨링이 가능한 시점 이후가 되어야 한다).

  - 과도하게 무거운 모델 생성하기
  2009년 Netflix prize 에서 1등을 했던 모델은 무려 100여개가 넘는 모델을 조합한 앙상블 기법을 사용했었다. 가장 높은 정확도를 기록했지만 실제 넷플릭스 추천팀에서는 해당 모델을 사용하지 않았고 자체적으로 비슷한 성능의 더 가벼운 모델을 구현하였다.
  논문이나 경진대회에서는 SOTA를 넘어서는 성능을 기록하는 것이 가장 중요하겠지만, 실전에는 모든 것에 비용을 고려해야 한다.

  - 이 밖에도 클래스가 불균형한데 accuracy 기준으로 평가하기, 오탐과 미탐의 비용이 서로 다른데 F1 score를 이용하여 평가하기, 활용 목적을 고려하지 않고 무조건 RMSE 를 최소화하도록 모델링 하기 등도 역시 실제 상황을 고려하지 않고 지나치게 일반화한 방법이다.

5) 서비스 구현
  기계 학습 서비스를 만드는 것은 일반적인 서비스나 프로덕트를 구현하는 것보다 더 어려운 것 같다. 여러 가지 이유가 있겠지만, 무엇보다 디버깅과 테스팅의 어려움이 크다. 일반적인 서비스에서는 테스팅이나 디버깅 대상이나 범위가 비교적 명확하다. 반면, ML 서비스에서는 단위 테스트나 회귀 테스트 (여기서 말하는 회귀 테스트는 회귀 분석과는 상관없는 소프트웨어 공학 기법을 말함) 를 어떻게 해야 할지 아직 감을 못 잡겠다.

  예상과 다른 결과가 나왔을 때 검토해야 할 스펙트럼이 훨씬 더 넓다. 데이터가 더러워진 것인지, 데이터 전처리 단계에서 비즈니스 로직의 문제인지, 기계 학습 모델이 갖는 어쩔 수 없는 통계적 오차인 것인지, 모델링 코드의 오류인지, 아니면 결과를 이용하는 서비스 로직의 오류인지 등등 고려해야 한 사항이 기존 소프트웨어에 비해 더 많기 때문에 파악하기 어렵다.

  ML 서비스는 기존의 소프트웨어 공학 기법을 적용하기가 매우 어려운데 그 이유는 크게 두 가지인 것 같다.

  첫째, 기계 학습 결과는 기본적으로 통계적 오차를 감안해야 하기 때문이다. 즉, 결과가 연역적으로 추정되지 않는다. 내 생각에 이게 다른 소프트웨어와의 가장 큰 차이점인 것 같다. 유닛 테스트나 회귀 테스트 같은 걸 적용하기 어려운 점도 이 때문인 것 같다.

  둘째, 데이터 엔지니어링 자체가 일반적인 소프트웨어 로직에 비해 무거운 작업이기 때문에 뭔가를 테스트하기가 어렵다. 이건 ETL 이 소모적인 작업이 될 수 밖에 없는 이유이기도 하다. 다만, 이 문제는 조금씩 경험이 쌓이고 기술이 발전하면서 개선되고 있는 것 같다.

  정리하자면, ML 서비스는 데이터와 모델, 서비스 구현 이 세 가지가 모두 오류 없이 구성되어야 하는데 세 가지 모두 엔지니어 입장에서 투명하게 확인하기 어려운 상황이다. 오류 없는 ML 서비스를 구현한다는 건 마치 눈을 감고 영점 사격을 했는데 탄착군이 정확히 형성되길 바라는 것과 비슷하다는 느낌이다.

6) 보안
  최근 이루다 서비스를 통해 크게 이슈가 되었듯이, 기계 학습 서비스에 대한 보안 이슈는 앞으로도 계속 심각해질 것이라 생각한다. 앞서 언급했듯이 현재의 기계 학습 서비스에 대한 소프트웨어 공학 측면에서의 수준은 대단히 낙후되어 있다. 로직이 어떻게 돌아가는지도 정확히 이해하지 못한 상황에서 보안 측면에서 안전한 서비스가 구현될 턱이 없다.

  대부분의 보안 전문가들은 기계 학습에 대한 이해도가 떨어지고, 대다수의 기계 학습 전문가들 역시 보안에 대한 배경 지식이 부족하며, 현재 기계 학습 서비스를 준비하는 기업들은 빠르게 발전하는 이 분야의 기술을 쫓아가기에도 바쁘기 때문에 보안에 신경 쓸 여력이 없다.

  심지어 나는 정보보호대학원에서 박사 학위를 받았고, 데이터 분석 및 기계 학습 관련 업무를 수 년 째 하고 있지만 기계 학습 서비스에 대한 보안을 어떻게 해야 할지 아직 감을 못 잡겠다.  

7) 유지보수 및 운영
  실전 서비스가 논문이나 경진 대회가 다른 가장 큰 차이점은 유지 보수에 있다고 생각한다. 서비스에서는 상황이 계속 변하며 이에 따라 데이터가 갖는 패턴이 계속 달라진다. 때문에 기계 학습 모델 역시 이런 변화에 맞춰 지속적으로 변해야 한다. Continual learning 이라는 분야가 이런 것을 연구하는 분야이다. 실전에 ML 서비스를 제대로 정착시키려면 continual learning 이 되거나 최소한 지속적인 모델 업데이트를 위한 자동화 프로세스가 필수적으로 고려되어야 한다. 과거에 이런 고려 없이 몇 차례 ML 서비스를 적용해본 바에 의하면, 처음에 잠깐 효과나 성과를 보이지만, 빠르게 무용지물이 되곤 했다.

  물론 구축한 ML 서비스가 회사의 주력 서비스라면, 소위 사람을 갈아 넣음으로써 유지보수를 할 수 있다. 하지만 대개의 경우 ML 서비스는 회사에서 새로 도전하는 서비스인 경우가 많고 이런 경우에는 개발 단계에 비해 유지 보수 단계에서 받는 지원은 한계가 있다. 심지어 구현 단계에서 주요 역할을 하는 역량 있는 기계 학습 엔지니어들은 대개 유지 보수보다는 신규 프로젝트에 더 관심을 가질 것이다.

  따라서 자동화가 못되더라도 최소한 최초에 모델을 만들 때보다는 훨씬 낮은 비용으로 모델의 초반 성능을 유지할 수 있는 프로세스는 필요한 것 같다.

https://www.facebook.com/1182005821/posts/10223852483158298/?d=n

'사업 모티프2 > 인물' 카테고리의 다른 글

쌍방울 김세호 대표  (0) 2022.03.10
마켓컬리 김슬아, 넥스트키친 정승빈  (0) 2022.03.10
토스벤처스  (0) 2022.03.10
토스 플랫폼 디자인팀, 강수영님  (0) 2022.03.10
임성수님, 그렙 주재원  (0) 2022.03.10