LY Corporation Tech Blog

LY Corporation과 LY Corporation Group(LINE Plus, LINE Taiwan and LINE Vietnam)의 기술과 개발 문화를 알립니다.

This post is also available in the following languages. Japanese, English

오프라인과 온라인 A/B 테스트를 통해 오픈챗 추천 모델 개선하기

들어가며

안녕하세요. AI Services Lab 팀의 ML 엔지니어 박희웅입니다. 저희 팀에서는 오픈챗과 관련해 다양한 AI/ML 모델을 개발하여 서빙하고 있습니다. 일전에 머신러닝을 활용한 오픈챗 클린 스코어 모델 개발기라는 글에서 '부적절한 콘텐츠가 오가지 않으며 대화 중 에티켓이 얼마나 잘 지켜지는지'라는 관점에서 각 오픈챗을 평가해 점수화하는 '오픈챗 클린 스코어 모델'을 소개 드린 바 있는데요. 이번 글에서는 '오픈챗 개인화 추천 모델'을 어떻게 개선하고 있는지 그 과정을 공유드리고자 합니다. 

오픈챗 추천 서비스와 추천 모델 소개

오픈챗(OpenChat)은 관심사가 비슷한 익명의 사용자가 LINE 친구를 맺지 않고도 함께 모여 대화를 나눌 수 있는 오픈 채팅방 서비스로, 현재 일본과 태국, 대만에서 서비스하고 있습니다.

오픈챗의 모바일 앱 메인 페이지에는 사용자가 오픈챗을 검색하거나 마음에 드는 오픈챗을 발견해 참가할 수 있도록 오픈챗 검색창과 추천 오픈챗 및 오픈챗 랭킹을 표시하는데요. 이 글에서 다루고자 하는 서비스는 2023년 11월 기준으로 오픈챗 메인 페이지 상단에 노출되고 있는 'Recommended for you'라는 오픈챗 개인화 추천 서비스입니다.

오픈챗 추천 서비스의 특징

오픈챗 서비스는 빠른 속도로 변화하는 역동적인 서비스입니다. 기획 및 운영 팀에서 사용자의 요구에 맞춰 지속적으로 새로운 기능을 출시하고 메인 구성 화면을 개편하며, 마케팅 이벤트를 실시해 기존 사용자의 활동을 촉진하거나 새로운 사용자를 서비스로 끌어들이기도 합니다.

이와 같은 활동으로 사용자 층이 변화하고 서비스가 성숙하면 그에 맞춰 서비스를 이용하는 사용자의 행태나 이용 문화가 달라지기도 하며, 이런 변화는 모델 자체 성능과는 별개로 추천 지표에 직접적인 영향을 미칩니다.

또한 오픈챗은 다양한 콘텐츠를 포함하고 있는 고정적이지 않은 아이템입니다. 한 번 생성되면 거의 변하지 않는 포스트나 동영상, 판매 상품과는 달리 끊임없이 참여 멤버가 바뀌고 새로운 메시지가 생성됩니다. 하나의 오픈챗 안에는 여러 개의 하위 챗들을 생성할 수 있으며, 각각의 챗에서는 텍스트뿐 아니라 이미지나 동영상, 포스트 형태의 메시지 등 다양한 메시지를 주고받을 수 있습니다.

따라서 오픈챗 추천 모델은 여러 종류의 데이터를 피처로 활용해야 하며, 아이템이나 사용자 피처를 추출할 때 같은 대상에 대해서도 최신 정보가 반영될 수 있도록 반복적으로 수행해야 합니다.

오픈챗은 한 사용자가 단시간 내에 잇달아 여러 오픈챗에 가입하는 빈도가 적다는 특성도 있습니다. 오픈챗의 사용자는 마음에 드는 오픈챗을 발견해서 가입하고 나면 그 안에서 활동하고 머무는 시간이 늘어나면서 다른 오픈챗에 가입할 욕구가 잠시 줄어듭니다. 이런 특성은 적절하게 추천했을 때 연속적인 아이템 소비로 이어지는 숏폼 콘텐츠 추천과 대비되는 지점이라고 할 수 있는데요. 따라서 숏폼 콘텐츠 추천과 같은 서비스에 적합한 세션 기반(session-based) 또는 시퀀셜(sequential) 추천은 오픈챗 추천과는 잘 맞지 않습니다.

또한 오픈챗은 재가입 비중이 크지 않아 이미 한 번 가입한 이력이 있는 오픈챗은 추천 다양성 등을 고려해 추천 대상에서 제외하는 게 좋습니다. 이는 오픈챗 추천이 재구매 패턴을 주요하게 반영해야 하는 온라인 쇼핑 아이템 추천과도 다르다는 것을 의미합니다.

오픈챗 추천 모델 소개

오픈챗 개인화 추천 모델은 추천 시스템에서 널리 활용하는 2단계(two-stage) 프레임워크를 따르고 있습니다. 이 프레임워크는 수백, 수천 개의 후보 아이템을 적은 연산량으로 선정하는 후보 선정(candidate selection) 단계와, 보다 정밀한 모델로 각 후보 간 순위를 결정하는 랭킹(ranking) 단계로 구성됩니다.

후보를 선정할 때에는 사용자를 추정한 뒤 인구 통계적 정보를 활용해 인기 있는 오픈챗을 매칭하는 방식과, 상호작용이 발생했던 오픈챗과 참여 멤버가 많이 중첩되는 오픈챗을 선택하는 방식을 사용합니다.

랭킹 모델로는 사용자와 아이템의 상호작용을 2차 항으로 고려하면서 효율적으로 연산할 수 있는 Field-aware Factorization Machines(FFM) 모델을 채택했습니다. 랭킹 모델은 끊임없이 변화하는 오픈챗의 활동성과 선호도, 유행 등을 반영하기 위해 매일 학습합니다. 모델 업데이트 완료 시기를 앞당기기 위해 사전 학습(pre-training)과 미세 조정(fine-tuning)을 병렬로 진행합니다. 미세 조정의 경우 이전에 사전 학습된 모델로부터 단시간에 훈련할 수 있습니다. 미세 조정을 완료한 모델을 이용해 매일 추론해서 개인화한 추천 결과를 생성하며, 활동성이 높은 사용자에 대해서는 매시간 갱신된 피처를 반영해 추천 목록을 업데이트합니다.

오픈챗 추천 모델과 관련해서 LINE Engineering 블로그에 발행됐던 LINE Timeline의 새로운 도전 3편 - Discover 추천 모델을 읽어보며 LINE VOOM 포스트 추천 모델과 오픈챗 추천 모델을 비교해 보시는 것도 좋을 것 같습니다.

기존 오픈챗 추천 모델 개선 과정 소개

이제 본격적으로 본 주제로 들어가 보겠습니다. 오픈챗 추천 서비스를 제공하기 시작한 지 벌써 4년이 흘렀고, 그동안 수차례 대대적으로 모델을 개선했는데요. 저희가 추천 모델을 개선할 때에는 대략 다음과 같은 과정으로 진행합니다. 

  1. 사전 문헌 조사 및 기존 추천 결과 분석
  2. 분석 결과를 바탕으로 개선점을 도출하고 모델에 구현해 오프라인 테스트 성능 확인
  3. 계획 기간 동안 기존 모델 대비 오프라인 테스트의 성능을 최대한 향상시키기 위해 지속적으로 개선 시도
  4. 오프라인 테스트를 통해 최적의 모델을 선정하고 기존 모델과 온라인 A/B 테스트를 수행해 검증
  5. 유의미한 성능 향상을 달성했을 경우 새 모델을 릴리스

위 과정 중에서 가장 중요한 두 가지 테스트 과정인 오프라인 테스트와 온라인 테스트를 살펴본 뒤, 두 테스트 사이에 발생하는 간극과 이 간극 때문에 발생한 이슈를 말씀드리겠습니다.

오프라인 테스트란

오프라인 테스트는 축적돼 있는 히스토리 데이터로 정답 셋을 구성해 모델을 비교하는 과정입니다. 오픈챗 추천에서는 사용자의 특정 오픈챗 가입 여부를 정답 레이블로 이용하며, 테스트 데이터에는 서비스 중인 모델의 노출 편향에 영향받지 않도록 추천 외 경로(검색이나 사용자 간 초대 등)로 가입한 것만 활용합니다. 훈련 데이터와 테스트 데이터는 타임스탬프 기준으로 구분합니다. 모델을 매일 학습시키므로 테스트 데이터는 하루치를 마련하고, 해당 날짜 전까지의 데이터만 훈련 용도로 사용합니다. 검증 신뢰도를 확보하기 위해 최소 일주일 이상의 테스트 데이터 셋에 대해 각각 모델을 학습하고 평가합니다. 서비스 시 모델이 사용자당 상위 k개를 추천 아이템으로 선정하면 그중 랜덤하게 사용자에게 노출되는 것을 가정해, 선정된 상위 k개에 대해 평가 지표를 산출합니다.

오프라인 테스트에서 사용하는 평가 지표

메인 지표로는 모델이 추천한 결과를 테스트 데이터에서 각 사용자가 실제로 가입한 오픈챗과 비교해 몇 개나 일치하는지 세어 전체 사용자 결과를 합산한 TP(true positive) 개수를 채택했습니다. 모델을 비교할 때는 동일한 테스트 셋에 대해 목록 크기 k를 고정했으므로 Precision 혹은 Recall 지표와 스케일만 다를 뿐 비교 측면에서는 동등합니다. 모델 추천 결과에 실제로 가입한 오픈챗이 하나라도 있는 사용자 수를 집계하는 Hit rate 값도 아웃라이어 사용자의 영향을 덜 받는 의미 있는 수치이나, 사용자당 가입이 많지 않은 특성이 추천 결과가 실제로 노출되지 않는 오프라인 환경과 맞물려 TP 개수와 크게 차이가 없어서 메인 지표로 사용하지 않았습니다. 

추가로, 전체 사용자를 대상으로 하루 동안 추천되는 고유 오픈챗 개수도 살펴봅니다. 오픈챗 메인 페이지에는 개인화 추천 외에도 소수의 인기 있는 혹은 엄선된 오픈챗을 보여주는 랭킹이나 에디터 추천 섹션이 있는데요. 이런 섹션에 비해 사용자의 적극적인 탐색 행위 없이도 다양한 오픈챗을 보여주는 데 기여한다는 것을 어필하기 위한 수치입니다.

이외에도 여러 보조 척도를 살펴보고 있으며 새로 정의도 해보고 있습니다. 다만 모델 선택이 간편하며, 이미 많은 분들이 알고 계셔서 지표에 관해 따로 설명할 필요가 없다는 커뮤니케이션 편의 측면을 고려해 메인 지표를 중점적으로 활용하고 있습니다. 

아래 그림과 같이 MLFlow 플랫폼을 이용해 오프라인 테스트에서 산출된 각종 파라미터와 지표를 로깅하며 모델 간 성능을 비교하고 있습니다.

온라인 A/B 테스트란

온라인 A/B 테스트는 사용자들을 임의의 두 집단 A와 B로 나누고, 각 집단에게 기존 모델 추천과 새 모델 추천을 보여주는 대조 실험입니다. 각 집단별로 평가 지표를 집계해 어느 모델이 우수한지 판단합니다. 오프라인 테스트와 달리 테스트하는 동안 새 모델이 실제 서비스에 반영되기 때문에 실제 사용자의 직/간접적인 반응을 평가 지표로 측정할 수 있습니다.

온라인 A/B 테스트에서 사용하는 평가 지표 - 오픈챗 추천 KPI

온라인 A/B 테스트에서 평가 기준으로 삼은 주요 지표는 다음과 같습니다. KPI 정의에 포함된 모든 행위는 추천에 의한 결과만 집계합니다. CPI와 UU-CPI 지표를 우선 판단 기준으로 삼으며, 다른 지표는 보조 지표로 활용하거나 모델을 분석하는 데 활용합니다.

KPI정의설명
CPI(conversion per impression)가입 수 / 노출 수오픈챗 서비스는 일단 가입해야 채팅방에서 활동할 수 있으므로 가입 행위에 가장 큰 관심을 갖습니다. 이는 통상적인 상품 추천 문제에서 구매 행위에 대응되는 행위입니다.
UU(unique user) CPI가입자 수 / 노출된 사용자 수UU가 아닌 CPI 지표에 비해 극단적인 소수 사용자의 활동에 영향을 적게 받는 지표로, 대표적인 서비스 지표인 활성(active) 사용자 수 등과 연관성이 높은 지표입니다.
CTR(click-through rate)커버 뷰 횟수 / 노출 수사용자가 노출된 아이템에 관심을 보이고 클릭할 경우 해당 오픈챗의 커버 뷰가 팝업됩니다. 사용자는 팝업창에서 가입 신청할 수 있으며, 승인이 필요 없는 경우 바로 가입돼 오픈챗에 참가할 수 있습니다.
CVR(conversion rate)가입 수 / 커버 뷰 횟수위 지표들과는 달리 시기적인 영향이나 마케팅에 민감한 노출 수를 계산식에서 제외하기 때문에 비교적 날짜별 변동성이 적은 지표입니다.
Request CPI가입 신청 수 / 노출 수사용자가 추천된 아이템에 흥미를 보였는지 관리자의 승인을 고려하지 않고 살펴보기 위한 지표입니다.

온라인 A/B 테스트 평가 지표 사용 시 주의할 점

위 지표들을 이용해 서로 다른 기간에 노출된 추천 모델을 비교하는 것은 다소 무리입니다. 앞서 언급했듯 오픈챗은 서비스 환경이 역동적으로 변화하며, 그에 따라 지표 수치 또한 달라집니다. 10대 사용자의 활동성이 높은 서비스의 특성상 방학이나 신학기 시작 등의 시기적 요인에 상당한 영향을 받기도 합니다. 10대 사용자는 타 연령대에 비해 추천에 대한 반응도 활발한 편입니다.

또한 데이터 수집 및 활용 정책이나 추천 아이템 필터링 규칙 등의 수정 작업이 추천 성능 개선 작업과는 별도로 진행되고 있어서 지표 변동 요인을 어느 하나로 단정 짓기도 어렵습니다. 여기에 요일 효과도 존재하므로 오프라인 테스트 셋 구성 때처럼 최소 일주일 이상(권장 이주일)은 테스트해야 합니다.

여기에 기존 모델 때문에 형성된 필터 버블(filter bubble, 사용자의 히스토리를 기반으로 제공하는 개인화한 알고리듬의 결과가 마치 거품 안에 갇힌 것처럼 사용자가 선호하는 관점으로만 구성되는 현상)이 새 모델을 노출함에 따라 약간 변동될 수도 있고, 단순히 이전과 노출되는 목록이 다르다는 사실이 마치 출시 효과처럼 테스트 초기 지표에 영향을 줄 수도 있습니다.

오프라인과 온라인 테스트의 간극

오프라인 테스트에서는 실제 서비스 중 모델 결과가 노출되는 추천 섹션에서 발생한 정답 레이블을 활용하지 못합니다. 다시 말해 오프라인 테스트 성능으로부터 모델이 사용자의 가입 성향을 잘 파악했다는 것은 확인할 수 있으나, 이것이 사용자가 모델이 추천한 오픈챗을 가입할 것인지 대한 결과는 아닙니다.

예를 들어 오프라인 사회생활이나 LINE 외 서비스에서의 관계로 초대돼 가입하는 비중이 큰 오픈챗은, 추천했을 때의 가입률이 상대적으로 저조합니다. 가입할 때 오픈챗 관리자(방장)의 승인이 필요한 오픈챗의 경우에도, 모델이 사용자의 성향을 제대로 파악해 추천했고 그 결과 사용자가 오픈챗에 가입을 신청하더라도 관리자가 승인하지 않아 결과적으로 가입까지 이어지지 못하는 경우가 발생합니다.

또한 오프라인 테스트에서는 추론 결과 생성을 위한 연산량이 많이 필요할 뿐 아니라 평가 셋업을 복잡하게 만드는 시간별 추천에 대한 비교는 여건상 보통 생략하기 때문에 이로 인해 발생하는 간극도 있습니다.

서비스가 성숙하면서 도출된 기존 모델 개선 과정의 문제

그동안 진행한 몇 번의 모델 버전 업 과정에서는 오프라인 테스트에서의 성능 향상이 온라인 A/B 테스트에서도 그대로 나타나면서 모델 개선 과정이 잘 작동했습니다. 이전 버전 업에서는 사용자의 성향이나 오픈챗의 개별 특징을 파악할 수 있는 강력한 피처를 추가한다거나 학습이나 추론 주기를 줄이는 등의 개선 작업을 통해 성능이 확연히 상승했기 때문입니다.

그런데 서비스가 궤도에 오르고 주요 피처가 어느 정도 모델에 반영된 뒤에는 개선폭이 줄어들면서 오프라인과 온라인 테스트에서 모델 성능의 우열 관계가 동일하지 않은 경우가 발생하기 시작했습니다. 그리고 그 원인으로 앞서 말씀드렸던 두 테스트 간의 간극이 지목됐습니다.

온라인 테스트 결과가 좋지 않으면 앞서 진행한 개선 과정을 다시 반복해야 하는데요. 여러 개선점이 반복적인 오프라인 테스트 과정에서 누적되기 때문에 어떤 변경점이 온라인 테스트 성능에 특히 악영향을 준 것인지 특정하는 게 쉽지 않습니다. 오프라인 테스트 평가 지표를 온라인 테스트 평가 지표와 정비례하도록 최대한 다듬는 방법도 있겠으나 이 방법은 공수가 많이 들고, 서비스 환경에 영향을 받을 수 있어서 지속적으로 보정하는 작업도 필요합니다.

Adhoc A/B 테스트 도입

위와 같은 이슈를 해결하기 위해 Adhoc A/B 테스트를 도입했습니다.

Adhoc A/B 테스트란

Adhoc A/B 테스트는 온라인 성능 테스트라는 점에서 기존의 A/B 테스트와 동일하나, 즉석(adhoc)으로 개별 변경점 단위로 모델 성능을 테스트한다는 점에서 다릅니다.

테스트할 때에는 즉석 모델의 리스크를 줄이기 위해 A와 B의 비율을 5:5가 아니라 9:1의 비율로 그룹 B를 작게 설정합니다. 그룹 B의 크기가 1/5로 줄어들어도 통계 관점에서 신뢰도를 확보하기 위해 5배 기간이 필요하지는 않은데요. 그 이유는 비교 대상인 그룹 A의 크기가 오히려 늘어나기에 필요한 샘플 증가량이 얼마 정도 상쇄되기 때문입니다.

다음 그림은 statsmodels 패키지를 이용해 그룹 B의 비율이 50%에서 10%로 줄어들 때 필요한 샘플 크기를 계산한 결과입니다. 서브 플롯에서는 가입률 0.01, 검정력(statistical power) 0.8, 유의 수준(significance level) 0.05 조건에서 각각 3%와 5% 지표 개선(expected lift)을 가정했습니다. 그래프를 보면 그룹 B의 크기가 줄어들수록 필요한 전체 샘플 크기가 늘어나긴 하지만, 50%에서 10%로 줄이는 조건에서 5배까지 늘어나지는 않습니다. 약 3배 이내의 샘플 수로 충분한 것을 확인할 수 있습니다.

Adhoc A/B 테스트 기반 모델 개선 과정은 다음과 같습니다.

  1. 조사 및 분석을 바탕으로 개선점을 도출하고 Adhoc 모델에 구현(기존과 동일)
  2. 오프라인 테스트 후 향상된 것이 확인되면 해당 Adhoc 모델로 Adhoc A/B 테스트 수행
    1. Adhoc 테스트 성능이 좋으면 Adhoc 모델의 개선점 유지
    2. 성능이 좋지 않다면 Adhoc 모델에서 개선점 롤백
  3. 추가 개선점을 Adhoc 모델에 누적해 구현하면서 2번 과정 반복 수행
  4. 서너 번의 Adhoc 테스트 후 최종적으로 새 모델을 구성해 기존과 같이 5:5 비율로 A/B 테스트

기존 A/B 테스트가 어느 정도의 성능 개선을 잠정적으로 가정하고 릴리스 전 단계에서 최종 확인하는 과정이었다면, Adhoc A/B 테스트는 부담을 완화해 개별 변경점의 성능을 검증하는 것을 목적으로 삼은 과정입니다. 기존과 비슷한 개발 기간 동안 보다 길게 온라인 테스트를 수행하기 때문에 신뢰도가 높아지는 장점도 있습니다.

적용 결과

이와 같이 개선한 결과를 최근 진행한 오픈챗 개인화 추천 모델 개선 과정에 도입했습니다. 아래가 이번에 수행한 모델 개선 과정 타임라인으로, Adhoc A/B 테스트 4회 수행 후 최종 A/B 테스트를 실시했습니다. 개발 기간을 단축하기 위해 Adhoc A/B 테스트 간 간격을 최소화했으며, 각 테스트 진행 기간에는 다음 Adhoc 모델을 구현하고 오프라인 테스트를 수행했습니다.

이번 개선 과정에서는 아래 성능 향상 그래프에서 보듯 운 좋게도 Adhoc A/B 테스트 결과가 테스트를 거치면서 대체로 점차 향상돼 롤백 없이 변경점을 계속 누적하면서 Adhoc 모델을 업데이트해 나갔습니다(현재 국가별로 따로 모델을 학습하고 추론하며 각각 평가 지표를 집계). 

JP: 일본, TH: 태국, TW: 대만

직전 테스트에 비해 향상도가 소폭 낮아진 경우도 있었으나 유의미한 정도는 아니었습니다. 앞서 언급했듯 서로 다른 기간의 KPI 값을 모델 비교에 활용하는 데에는 한계가 있고, 기존 모델과 비교해서는 꾸준히 결과가 좋았기 때문입니다.또한 각 개별 변경점의 기여도를 엄밀히 살피려면 여러 변경점의 조합을 테스트해야 하는데 이런 방식으로 진행하면 테스트 기간이 너무 늘어납니다. 이에 변경점을 누적해 나가면서 해당 변경점이 온라인 테스트에 심대한 악영향을 끼치는지를 확인하는 데 주로 초점을 뒀습니다.

참고로 태국의 경우, 마지막 Adhoc A/B 테스트와 최종 테스트 사이에 모델 성능 개선과는 별도로 필터링 정책이 변경됐습니다. 이 정책 변경이 기존 모델과의 성능 격차를 줄이면서 최종 향상도가 살짝 우하향하는 그래프가 나타났습니다.

개선 결과를 적용하고 보니 전체 과정이 선명하게 구조화된다는 큰 장점도 얻을 수 있었습니다. 계획된 테스트가 어디까지 진행됐는지 체계적으로 정리되면서 진척 사항을 가시화해 팀 외부로 공유하기에 적합했는데요. 덕분에 릴리스 결정 또한 지체 없이 이뤄지면서 성공적으로 새 모델을 릴리스할 수 있었습니다.

마치며

Adhoc A/B 테스트를 수행할 수 있는 권한을 받을 수 있었던 것은 오픈챗 기획 팀의 전폭적인 지지 덕분입니다. 일부 사용자로 제한되긴 하지만 새 모델의 결과를 노출하는 것은 분명 어느 정도 리스크가 있는 작업인데요. 오픈챗 기획 팀에서 그동안 지속적으로 모델을 개선해 온 저희 팀을 믿어주었기에 작업을 진행할 수 있었습니다. 문제 발생 시 A/B 테스트를 신속하게 중단하고 원래대로 복구할 수 있는 훌륭한 서빙 역량을 갖춘 저희 팀의 역량도 이와 같은 신뢰의 배경을 마련해 줬다고 생각합니다. 

모든 것의 기본이자 중심은 사용자라는 기준에 따라 오픈챗 사용자들이 더 양질의 추천을 받을 수 있도록 앞으로도 가열차게 모델을 개선해 나가겠습니다.