세미나 광고 이미지
  • 데이터 분석

100+ 팀원의 의사결정에 영향을 주는 Data Scientist, Decision : 실험플랫폼

세미나 광고 이미지
세미나 광고 이미지
💬 이 글의 원문은 당근 테크 블로그에 업로드 된 ‘100+ 팀원의 의사결정에 영향을 주는 Data Scientist, Decision : 실험플랫폼’ 입니다.
 
 
안녕하세요! 당근마켓의 데이터 가치화 팀에서 Data scientist, Decision으로 일하고 있는 Matthew예요. 당근마켓의 Analytics 직군에는 Data scientist, Decision과 Data analyst 2가지의 직군이 있어요. 사실 Data analyst는 모두 친숙한 직군일 거예요. 하지만 Data scientist, Decision는 사실 저희에게도 생소한데요. 주변에 이 직군으로 일하는 분이나 그러한 회사가 없어서 그런 것 같아요. 그래서 최근에 팀원들과 두 직군 사이의 차이점에 관해서 이야기를 나눴어요.
두 직군의 공통점과 차이점에 관해서 이야기하다 보니 공통점이 생각보다 많다는 것과 그 경계를 명확하게 하는 것이 힘들다는 걸 알게 됐어요. 그래도 함께 이야기하면서 다 같이 동의한 차이점이 있었어요. 그것은 몇 명의 의사결정에 영향을 주는 것을 염두에 두고 일하는지였어요. Data analyst는 함께 일하는 프로덕트 팀의 의사결정에 도움이 되려고 하기 때문에 보통 5명에서 10명 내외의 팀원의 의사결정에 영향을 줘요. 하지만 Data scientist, Decision은 전사의 데이터 기반 의사결정을 더 좋은 방향으로 개선하려고 노력해요. 따라서 100명 이상의 의사결정에 영향을 주는 일을 하게 되는데, 그래서인지 통계와 엔지니어링의 힘을 더 많이 빌리게 되더라구요.
이 글에서는 Data scientist, Decision이 어떻게 100명 이상의 팀원의 의사결정에 영향을 주는지 설명하려고 해요. 무엇을 설명할 때 예시를 들어 설명하는 것이 효과적이에요. 그래서 Data analyst로 일하던 시절에 Data scientist, Decision의 관점으로 일했던 경험을 소개하려고 해요.
 
 

배경

저는 중고거래 서비스를 만드는 중고거래 팀에서 Data analyst로 일했어요. 중고거래팀은 서비스의 지속적인 성장을 위해 그로스팀을 중고거래팀 안에 만들었어요. 그로스팀은 많은 데이터 분석을 통해 서비스의 성장을 이끌어낼 방법을 찾아내려고 노력했어요. 하지만 분석하면 할수록 분석만으로 알 수 있는 것은 적다는 생각이 들었어요. 예를 들어, 중고거래 서비스를 사용하는 사용자들이 만족을 느끼는 순간인 “Aha-moment”를 데이터로 찾아보려고 노력했던 순간이 있었어요. 10개 이상의 분석을 통해 종합적으로 결론을 내리고 싶었는데, 결국에 상관관계 이상의 것을 찾아내기 어려웠어요. 인과관계를 알아내야 서비스를 더 어떻게 개선할지 알 수 있겠다는 생각이 들어서 그때부터 팀이 A/B 테스트를 통해 의사결정을 할 수 있도록 여러 가지를 준비하기 시작했어요.
 
아하모멘트 구하기 프로젝트. 수많은 분석을 통해 의미있는 것을 추론하려 노력했었어요.
아하모멘트 구하기 프로젝트. 수많은 분석을 통해 의미있는 것을 추론하려 노력했었어요.
 
처음 A/B 테스트를 타사의 A/B 테스트 기능을 사용해서 진행했는데 사용 과정에서 여러 가지 어려움을 만나서 직접 만들어서 해야겠다는 결론을 냈어요. 실험 설계를 팀원들과 하고 실험을 실행하고 나면 결과를 분석해야 하는데 그것을 위해 colab에 스크립트를 만들어서 돌렸어요. 하지만 이렇게 하다 보니 실험 결과까지 보는데 data analyst가 병목이 되는 현상이 발생했어요. 또한 팀과 서비스는 늘어나는데, 수동으로 data analyst가 계속 스크립트를 돌려서 하는 방식으로는 실험 기반 의사결정을 정착시키기 어려웠어요. 하나의 의사결정에 여러 멋진 분석들 통해 영향을 주는 것도 큰 임팩트지만, 앞으로 일어날 모든 의사결정의 과정을 변화시키는 것이 필요하겠다고 생각했어요.
 
Colab에서 실제로 사용하던 실험 결과 분석 수동 스크립트
Colab에서 실제로 사용하던 실험 결과 분석 수동 스크립트
 
 

실험플랫폼

이러한 근본적인 개선을 하려면 팀이 필요해요. 당시에 데이터 TF라는 팀이 만들어져서 자체 실험플랫폼을 만들기 위한 준비를 시작했어요. 실험플랫폼이라는 제품은 “실험을 진행하고 결과를 볼 수 있는 플랫폼”이지만 좀 더 구체적으로 어떤 제품을 만들 것인가 생각할 필요가 있었어요. 다음과 같은 점들이 실험플랫폼의 중요한 기능이라고 생각했어요.
 
  • Triggered analysis : 당근마켓을 사용하는 사용자는 1000만 명이 넘어요. 여러 서비스가 그 안에 존재하는데요. 30만 명의 사용자를 가지는 서비스의 기능을 실험하는 경우도 많아요. 이런 경우에 당근마켓의 전체 사용자 대상으로 분석을 진행하게 되면 원하는 의도대로 실험 결과를 분석할 수 없어요. 따라서 특정 실험에 참여하게 되었다는 “trigger”라는 개념을 도입해서 적용했어요.
  • Metric definition : 실험할 때 가장 많이 에너지를 쏟고 또 가장 많이 실수하는 지점이 지표 정의였어요. 항상 복잡하다고 느꼈는데, 사실 실험에 사용하는 지표의 형태는 많지 않아요. 따라서 정형화해서 실수를 줄이고 누구나 쉽게 지표를 사용하게 할 수 있었어요. 또한 지표가 정의되어 있으면 누구나 가져다가 사용할 수 있어서 전사적으로 이점이 많아요.
  • SRM & outlier elimination : 실험하는 것도 중요하지만 실험을 신뢰할 수 있는 형태로 하는 것이 정말 중요해요. 실험하는 이유는 (근본적으로 데이터를 보는 이유기도 하죠) 정확한 사실을 알기 위해서예요. “Trustworthy”한 데이터를 기반으로 의사결정을 하게 하려면 많은 장치가 필요해요. 이 2가지는 실험의 신뢰성을 올리기 위해 한 작업이에요.
  • Statistics engine : A/B 테스트는 통계적 가설 검정이라고 부르는 방법 중에 하나에요. 실험하고 나면 그 결과를 통계적으로 해석할 수 있어야 하는데요. 통계 계산을 정의된 지표에 대해서 자동으로 해주는 기능을 만들었어요.
 
TF의 구성원이었던 Data analyst와 Software engineer분들과 협업해서 이 일을 진행했어요. Playground라는 repository를 파서 리뷰를 받으며 코드화하고 그 이후에 airflow에서 돌아가도록 migration을 했어요. 최종적으로 실험플랫폼 서버와 연동이 되어서 팀원들이 하나의 제품으로서 실험플랫폼을 사용할 수 있었어요.
 
실험플랫폼의 결과 페이지 예시
실험플랫폼의 결과 페이지 예시
 
현재까지 실험플랫폼을 통해서 진행된 실험은 350+개가 넘어요. 실험을 직접 진행한 분들은 80명 정도에요. 중고거래, 커뮤니티, 피드, 머신러닝, 광고 등 다양한 도메인의 의사결정에 명확한 인과관계를 제공하고 있어요. 제품이 점점 복잡해짐에 따라서 한 곳에서 한 실험이 다른 곳에 영향을 줄 수 있는데 그런 어려운 의사결정 상황에서 실험플랫폼을 통해 실행한 실험이 많은 도움이 되었어요.
 
데이터 가치화 팀 대시보드
데이터 가치화 팀 대시보드
 
 

Triggered analysis

당근마켓에서는 동네생활이 2번째 탭에 있어요. 이 동네생활을 대상으로 실험을 진행한다고 가정해볼게요. 만약 전체 당근마켓 방문 사용자 수가 1000만 명이고 동네생활 방문 사용자가 200만 명이고 진행한 실험이 어떠한 지표에 0.1만큼 개선했다고 해볼게요. 만약에 실험 결과를 구할 때 동네생활 방문 사용자만 대상으로 분석하지 않고 전체에 대해서 분석한다면, 0.1의 개선은 0.02의 개선으로 축소되어서 나타날 거예요. 이렇게 되면 차이가 있음에도 불구하고 없다고 판단할 가능성이 커져요. 당근마켓같이 여러 서비스가 공존하는 서비스에서는 이렇게 실질적으로 실험에 참여한 사용자들 대상으로만 결과 분석을 하는 것이 중요해요. 이러한 분석을 “triggered analysis”라고 불러요.
조금 더 설명해 볼게요. 동네생활 게시글 상세 화면 UI/UX를 변경하는 실험이라고 생각해 보아요. 실험이 시작되면 당근마켓을 방문한 사용자는 대조군과 실험군으로 구분돼요. 이 과정을 assign이라고 하고, assign은 실험마다 개별로 진행되어요. 다음 그림처럼 당근마켓을 킨 사용자들은 대조군, 실험군 1, 실험군 2로 “assign”이 돼요. 그룹이 구분된 이후, 실험을 하기로 한 요소가 노출되는 시점(Trigger Point)을 기준으로 실험 분석에 필요한 이벤트를 수집해요. 만약 어떤 사용자가 앱을 켰지만 trigger point에 도달하지 못하면 그 사용자는 “assign 되었지만 trigger되지 않았다”고 판단하고 실험 결과에서 제외해요. 또한 동네생활 게시글을 탐색했다면 앱을 키자마자의 모든 행동 이벤트를 실험 분석에 사용해요. 하지만 어떤 사용자가 상당히 많은 행동을 하다가 동네생활 게시글을 클릭했다면, 그 이전의 이벤트는 실험 결과 분석에 사용하지 않아요.
 
Assign과 trigger에 대한 예시
Assign과 trigger에 대한 예시
 
Triggered analysis를 구현하려면 3가지가 필요해요. Triggering event 같은 경우 실험플랫폼 SDK를 사용하면 사용자에게 A를 보여줄지 B를 보여줄지 결정한 순간에 자동으로 발송해줘요. 2번째와 3번째는 실험 결과 계산 파이프라인 안에서 수행하도록 만들었어요.
 
  • triggering event logging
  • 위 이벤트를 토대로 사용자 필터링
  • 위 이벤트 이후의 이벤트만 사용하도록 필터링
 
 

Metric definition

A/B 테스트는 지표에 대한 통계적 가설 검정을 해요. 따라서 통계 엔진도 중요하지만 지표 정의 자체도 정말 중요해요. 하지만 이전까지는 지표의 정의라는게 딱히 없고 그때그때 SQL 문으로 구성해서 사용했어요. 이렇게 하니까 문제가 많이 생겼어요.
 
  • SQL이 길어지다 보니 잘못 작성되는 문제
  • 실험을 진행하는 구성원끼리 지표에 대한 이해가 서로 다른 문제
  • 지표를 실험에 맞는 형태로 누구나 정의하기 어려운 문제
  • 같은 지표를 여러 실험에서 활용 못 하는 문제
 
이런 문제를 해결하기 위해 실험에 사용되는 지표를 크게 분류해 보고 각 종류에 따라 간단한 방식으로 지표 정의가 가능하도록 했어요. 실험에서 사용하는 지표는 다음과 같아요.
 
  • conversion ratio : 전환율 (x를 한 사용자 / 실험에 참여한 사용자) → “실험 기간 내 특정 행동을 한 사용자의 수”를 비교하고 싶을 때 사용해요.
  • retention : 리텐션 (n일 뒤에 x를 한 번 더 한 사용자 / x를 한 사용자) → “특정 행동 최초 발생 후 특정 기간 내에 다시 해당 행동을 한 사용자의 비율”를 비교하고 싶을 때 사용해요.
  • total ratio : 전체 비율 지표 (전체 클릭 수 / 전체 노출 수) → CTR(Click-Through Rate)과 같은 사용자 기준의 비율이 아닌 다른 기준(노출)에 따른 비율 지표에요. A/B 테스트는 기본적으로 사용자 기반으로 randomization을 하므로 사용자가 아닌 다른 기준의 지표일 경우 delta method를 써서 보정하는 것이 필요해요. 쉽게 생각하면 count()/count()라고 생각하시면 돼요. ”실험 기간 내 그룹의 X 행동 수 대비 Y 행동 수의 비율“을 비교하고 싶을 때 사용해요.
  • count : 행동 수 (1인당 평균 x를 한 횟수) → “실험 기간 내 X 행동을 한 수“를 비교하고 싶을 때 사용해요.
  • value sum : 1인당 총 합해서 얼마를 했는지 (시간, 매출) → 특정 행동이 수치(ex. CPC, 머문 시간 등)을 가질 때, 사용자 한 명당 평균 수치을 의미하는 지표에요. “실험 기간 내 사용자가 X 행동을 하면서 만든 수치”을 비교하고 싶을 때 사용해요.
 
위 지표를 만드는 과정을 다음과 같은 구조로 모듈화했어요. 그 이유는 지표를 코드화해서 관리함으로써 명확성과 재사용성을 높이고 운영 비용을 줄이기 위해서예요. 지표를 정의하는 방식은 다음과 같아요.
 
  • metrics.yaml : 실험 결과 계산 파이프라인은 이 파일을 보고 연산해요. 최종적인 지표에 대한 spec을 표현하는 곳이에요.
  • subject_events.yaml : metric은 subject_event의 조합 및 연산 방법의 정의로 인해서 계산돼요. 지표 연산의 단위가 subject_event이고 이게 정의된 곳이에요. subject_event는 SQL문을 활용해서 재사용할 수 있도록 만들어져 있어요. events/ 하위에 있는 SQL문을 가져다가 조건이나 조합을 통해 실질적으로 metric 계산할 재료로 subject_event를 만들어요.
  • events/*.sql : subject_event가 사용하는 재료에요. 어떤 사용자가 어떤 이벤트를 언제 일으켰는지가 SQL로 기록되어 있어요.
 
notion image
 
예를 들어, count라고 지표의 종류를 정했다면 실제로는 다음과 같은 SQL 문이 돌아가면서 지표 연산을 자동으로 해요. SQL 문을 누구나 다 작성하는 것은 어렵고 또한 틀릴 가능성이 높아요. 비효율적이기도 하죠. 따라서 지표의 종류를 정했다면 그 세부적인 계산은 자동으로 되도록 했어요.
 
 
 

SRM & outlier elimination

실험의 신뢰성을 올리기 위해서는 SRM (sample ratio mismatch)를 항상 체크해야 해요. A/B 테스트는 기본적으로 random assignment (무작위 배분)을 행하기 때문에 인과적인 추론을 할 수 있어요. 하지만 이 무작위 배분이 제대로 동작하지 않을 가능성이 있어요. 만약 그렇다면 그 이후에 하는 통계적 추론은 모두 그 의미를 잃어버리게 돼요. SRM은 의도한 대로 무작위 배분이 잘 일어났는지를 체크하는 지표로서 실험의 신뢰성을 올리기 위해 꼭 필요해요.
1000명의 사용자를 5:5로 대조군과 실험군을 배분한다고 하면 500명:500명 나오는 경우는 많지는 않을 거예요. 이 경우에도 실험결과 분석에서처럼 우리가 관찰한 상황이 우연으로 발생할 수 있는 정도인지를 p-value라는 개념을 통해 판단해요. 실험 결과 분석과는 달리 SRM 같은 경우 통계적 유의성 판단 기준을 더 작은 p-value 값으로 보는 경우가 많아요. 당근마켓에서는 p-value가 0.001 보다 이하인 경우 SRM이 발생했다고 보고 후속 조치를 취하고 있어요. SRM 판단에 사용하는 p-value는 다음과 같은 코드를 통해 계산해요.
 
 
실험의 신뢰성을 올리기 위해 실험 결과에서 outlier를 제거하는 작업을 했어요. Outlier란 통계적으로 전체 분포에서 상당히 극적으로 떨어진 대상을 의미해요. 그 기준이 딱히 정해져 있지는 않은데요. 극단적 outlier는 단 1개만으로도 실험의 결과를 바꿔놓을 수 있어요. Outlier를 실험 결과에서 제거하는 것이 맞는지 (극단적 헤비 사용자를 제외하게 될 수도 있으므로), outlier를 어떻게 판별해야 하는지에 대해서는 논쟁의 여지가 있을 거예요. 당근마켓에서는 outlier를 제외한 결과가 좀 더 우리가 알고 싶어 하는 진실이라는 생각을 해서 실험 결과에서 제외하기로 했어요. Outlier를 제거하면 실제로 실험 결과들이 더러 달라지는 것을 보면서 상당히 중요한 작업이라는 것을 깨달았어요. 당근마켓에서는 평균으로부터 표준편차의 30배 이상 떨어지면 outlier라고 보고 지표 중에서는 count 지표와 value_sum 지표에 이 로직을 사용하고 있어요.
 
 
 

Statistics engine

당근마켓 실험플랫폼에서는 통계적 가설검정에 NHST(Null hypothesis significance testing)를 사용하고 그 방법은 two-sample t-test를 사용해요. 대조군과 실험군에서 관찰한 지표의 차이가 정도가 우연으로 인해서 생긴 것인지 아닌지를 판별하는 테스트에요. 코드로는 다음과 같이 구현했어요. 실험군과 대조군에서 표준편차가 다를 수 있는 가능성을 염두에 두고 그런 상황에서도 문제 없이 작동할 수 있는 Welch’s two-sample t-test로 구현했어요. T-test는 대학교 수준에서 배울 수 있는 어렵지 않은 통계이지만, 모두가 다 잘 이해하고 있는 내용은 아니에요. 통계적인 지식이 없더라도 실험을 활용해서 의사결정 해야하기 때문에 자동화했어요. 이 결과로 나온 p-value를 통해 의사결정을 하도록 했어요.
 
 
통계적 가설 검정에서는 검정력(power) 또한 중요하게 봐야 해요. 보통은 검정력을 0.8로 놓고 개선 정도를 예상한 다음에 그걸 위해 필요한 사용자 수를 계산해요. 실제로 실험을 여러 번 해보니 미리 어느 정도 개선할지 예측하기가 어렵다는 것을 알게 되었어요. 또한 당근마켓은 사용자 수가 많은데 0.8에 맞는 사용자를 미리 구한다면 아주 일부의 사용자에게만 실험하려는 경향이 생길 수 있다고 생각했어요. 따라서, 일반적인 power analysis가 아니라 MDE(minimum detectable effect)를 계산해서 알려주기로 했어요. 현재 실험의 사용자 수나 여러 가지를 고려했을 때 검정력이 0.8이 나오려면 이 정도의 차이는 보여야 한다는 것이에요. 다음과 같이 MDE를 구하는 것을 함수로 만들어서 모든 실험에서 이 값을 구해서 보여주도록 했어요.
 
 
 

수동 & 자동 pipeline

실험 결과 자동 계산 pipeline을 만들기 위해 2단계로 나눠서 일했어요.
 
  • Step 1 : 위에서 이야기했던 내용을 python 코드로 모듈화해서 구현해서 로컬에서 수동으로 돌아가도록 함.
  • Step 2 : 로컬에서 돌아가는 것이 문제가 없다는 것이 확인되면 Airflow 위에 동일하게 구현해서 하루에 한 번 자동으로 실행되도록 함.
 
처음에는 빠르게 작업하기 위해 Airflow가 아닌 로컬에서 python class와 method 형태로 구현했어요. 실험에 관한 메타 정보를 run.json에 JSON 형태로 적고 그 정보를 통해 아래의 코드를 실행해서 실험 결과를 다시 로컬에 CSV형태로 저장했어요.
 
 
위 코드의 검증이 끝나고 실험플랫폼이 개발이 끝난 이후에 실험 결과 계산을 자동으로 하기 위해서 airflow로 옮겼어요. 이 작업은 TF내의 Software Engineer 분들이 도와주셨어요. 실험플랫폼에서는 하루에 한 번 이 파이프라인이 돌아가면 그 결과를 가지고 와서 UI에서 팀원분들에게 보여주고 있어요.
 
실험플랫폼 Airflow 파이프라인
실험플랫폼 Airflow 파이프라인
 
 

Data scientist, Decision으로 일하면서 느꼈던 점

이 작업은 실험플랫폼에서 이뤄진 350개 이상의 실험에 영향을 줬어요. 크고 작은 의사결정을 감이 아닌 실험을 통해서 하게 되면서, 실제로 사용자에게 어떤 영향을 주는지를 기반으로 의사결정 할 수 있었어요. 실험하지 않았다면 개인의 생각에 기반을 두고 이야기하기 때문에 방향을 찾기 쉽지 않았을 거예요. 하지만 실제 사용자에게 어떤 영향을 주는지에 대한 신뢰할 수 있는 정보가 있으니 의사결정의 중심에 사용자가 자리 잡게 되는 것 같아요. 서비스의 성장과 사용자의 만족도에 직간접적으로 영향을 줬다고 생각하니 뿌듯하더라구요.
 
사실이 작업을 하면서 느꼈던 점이 많아요. 다음은 제가 느꼈던 점을 정리한 거예요.
  • 팀워크가 중요하다 : Data analyst로 일할 때는 거의 혼자 일했던 것 같아요. 하지만 이 작업을 할 때는 3~4분과 지속적으로 이야기하고 실제로 코딩도 같이했어요. ‘혼자서는 절대 못 했겠다’라는 생각이 들었고 팀으로서 일하는 게 이런 거구나 느꼈어요. 더 큰 작업을 하려면 많은 사람과 협업해야 한다는 것을 알게 되었고 그래서 더 재밌었던 것 같아요. 함께한 팀원분들께 고마움을 많이 느꼈고 또 많이 배웠어요.
  • 더 임팩트를 내려면 더 긴 시간이 필요하다 : 보통 분석한다고 하면 최대 2주 정도 작업했던 것 같아요. 대부분의 분석은 1일 이내에 하는 작업이었어요. 따라서 분석하는 것에 대해 PRD나 tech-spec과 같은 문서를 미리 작성하지 않았는데요. 실험플랫폼 작업은 반년 정도 했던 것 같아요. 그만큼 시작하기 전에 많은 논의가 필요했어요. 더 오래 한다고 해서 더 큰 임팩트가 나는 것은 아니지만 보통 더 큰 임팩트를 내기 위해서는 좀 더 긴 호흡으로 작업하는 것 같아요.
  • 표준이 되려면 많은 공부를 해야 한다 : Data analyst로서 일할 때는 나만의 스타일과 나의 생각과 판단대로 빠르게 분석하는데 초점을 맞췄던 것 같아요. 하지만 이 작업을 하면서 제가 가지고 있던 습관들이 모두 방해가 되더라구요. SQL을 작성하는 것도 convention에 따라서 작성해야 함께 협업하는 분들부터 시작해서 이 기능을 접하는 분들이 잘 이해할 수 있고 실수가 적어져요. 통계적인 것에 대해서도 350개 이상의 의사결정에 영향을 끼치는 것을 염두에 두면 더 꼼꼼하게 많은 것을 공부할 수 밖에 없었어요.
  • 끝없이 개선해야 한다 : 사실 실험플랫폼은 여전히 계속 개선하고 있어요. 실험플랫폼은 지속적으로 많은 분들이 사용하는 제품이다 보니 여러 불편함이나 예상치못한 문제가 생겨요. 그러한 문제를 해결하기 위해 끝없이 개선해야 했어요. 이 과정을 통해 “아 내가 프로덕트를 만들고 있구나”라는 생각하게 됐어요.
 
Data scientist, Decision이 어떤 일을 하는 직군인지에 대한 정보가 업계에 많지 않아요. 당근마켓이 사용자에게 더 큰 가치를 주려면 우리의 매일의 의사결정 과정을 혁신해야 한다고 믿어요. 그리고 그 혁신의 가운데 있는 여러 직군 가운데 Data scientist, Decision이 있어요. 그 사례를 직접 그리고 함께 만들어보고 싶으신 분이 있다면 이 채용 공고를 보고 지원해주세요!
당근당근 테크 블로그

함께 읽어보면 좋은 글

주식회사 데이터리안