스타트업에서 나홀로 식단 추천 시스템 만들기(2)

조홍철·2023년 7월 27일
5
post-thumbnail

Rule 기반에서 벗어날 수 있을까?


식단이라는 지켜야하는 규칙이 상당히 많은 컨텐츠를 정해진 규칙없이 만들 수 있을까? 라는 고민에 도달하게 되었다. 식단을 구성하는 음식들을 예측할 수 있다면 유저의 선호를 음식 단위로 관리하여 위에 있던 문제들을 상당 부분 처리할 수 있을 것이라고 생각하였다. 음식을 예측하는 모델을 만들기 위해서는 딥러닝을 알 필요가 있었고, 필요한 부분을 빠르게 학습 하기로 하였다. 식단의 경우 맥락(context)이 존재하는 sequence 데이터라고 생각했다(앞에 나온 음식이 뒤에 음식에 영향을 미치기 때문에). 그래서 자연어와 관련된 부분을 빠르게 학습하며 병렬적으로 여러 가지 시도를 해보게 되었다. 이제까지 유저에게 추천해주었던 식단을 데이터로 하여, 이를 학습하여 식단을 만들 수 있는 모델을 만들고자 하였다. 이 때, 기존에 추후에 필요할지 몰라서 식단 추천 시에 그 세부 내용을 로그 형태로 기록하는 DB 스키마를 정의했던게 도움이 되었다.

딥러닝을 어떻게 활용할 수 있을까?


처음에는 식품 자체를 예측하려고 했으나, 분류 문제로 생각했을 때 식품의 입점 상황이 빠르게 변화하여 과거에 있던 식품이 지금은 없을 수 있고 새롭게 추가된 식품들을 예측하려면 모델을 식품을 추가할 때마다 새롭게 학습하고 output의 크기가 바뀌어야한다. 하지만 해당 과정이 빠르게 이뤄질 수 없을 것이라고 판단하여 음식의 속성 중에 하나인 카테고리를 예측하면 어떨까 생각하게 되었다. 카테고리는 크게 바뀔 일이 없고, 새롭게 추가되는 음식들도 기존에 있는 카테고리에 포함되기 때문에 음식을 실시간으로 추가하더라도 모델을 새롭운 음식을 문제 없이 추천할 수 있다. 따라서 구현 난이도와 속도를 고려하였을 때 카테고리 예측을 먼저 시도해보기로 했다.

다양한 시도가 있었지만 최종적으로는, LSTM과 Word2Vec를 활용하여 모델을 구현하게 되었다. 맥락이 있다는 점에서 앞에 내용이 뒤에도 영향을 미쳐야하기 때문에 LSTM을 활용하였다. 또한 카테고리를 임베딩할 때 카테고리간의 유사도 또한 판단할 수 있도록 Word2Vec를 사용하여 카테고리 임베딩을 진행하였다.

input으로는 다양한 유저의 정보(신체 정보와 관련된 데이터 + 선호/비선호에 대한 데이터)와, 구매 데이터에서 얻은 데이터, 끼니 별 음식 수(이 또한 Fully connected 를 이용하여 예측하였다)등을 이용하였고, output으로는 1주일 식단의 카테고리였다

카테고리 예측 가정을 거친 뒤에 유저가 비선호하는 카테고리에 대해서 필터 과정을 거친 뒤에 카테고리가 부족하거나 없어지는 경우에는 Word2Vec를 이용한 embedding을 기반으로 유사한 카테고리로 확장하여 추천하도록 하였다. 유사도를 기반으로 한 확장을 통해 다양성도 확보할 수 있었다. 이 후 카테고리를 기반으로 음식들을 추출하여 실시간으로 조합하고 몇 가지 조건 검사를 한 뒤 최종 추천을 하는 시스템을 구축하였다.

측 이 과정을 통해서 식단의 각 위치 별로 가능한 음식들의 후보군(candidates)를 빠르게 추출할 수 있는 것이다. 이 때 당시에는 구매 예측에 대한 모델을 넣기 보단 우선은 해당 후보군 끼리의 모든 조합 중 조건을 만족하는 끼니들을 일정한 규칙에 따라 조합하여 식단을 생성하였다

모델의 예측 성능은 대략 60%정도였지만, 정확하게 예측하기 보다 다양하게 예측하며 사람이 보기에 자연스러운지가 더 중요하였다. 따라서 A/B 테스트를 진행하였다. A/B테스트 진행 결과 결제 전환율에서 약 6%의 수치로 기존 룰과 비슷한 수준의 결과가 나왔다. 물론 딥러닝 자체가 구매 데이터를 활용한 것이 아니라, 추천 식단을 기반으로 학습하였기 때문에 결제 전황에서 크게 상승하지는 않았지만, 결제 전환이 하락하거나 식단이 이상하다는 CS가 들어오지 않았기 때문에 성공적으로 딥러닝을 이용한 시스템으로 옮겼다고 판단하였다.

딥러닝 방식으로 옮기면서 점수제 방식에서는 필터로 처리하지 못했던 부분들을 필터 처리로 바꿀 수 있었다. 따라서 유저가 싫어한다고 표현한 요소에 대해서는 추천에서 볼 일이 사라지게 된다. 유저 Interview 결과 유저는 비선호 상품이 노출되었을시 서비스 전반적인 호감도가 크게 하락함을 알게되었다. 따라서 비선호를 완전히 제거할 수 있게 된 것은 향 후 결제 전환율에 긍정적인 영향을 미칠 것으로 기대한다. 또한 추가 입점이 있을 시에 별도로 끼니를 만들어 DB에 입력한다거나, 매 코호트마다 DB에 추천 시스템과 관련하여 미리 데이터를 올릴 필요성이 사라졌다. 이로 인해 배포 전 필요 작업 누락으로 인한 버그들이 사라졌다.

성과 추가) 딥러닝 기반 카테고리 예측에 따른 후보군 생성으로 인해 유저에게 추천해줄 수 있는 조합과 상품의 다양성이 증가하였고 2회차 재구매율 50%를 달성할 수 있었다. 비선호 상품 노출로 인한 CS가 90% 감소하였다.

어떻게 하면 결제 전환과 리텐션을 올릴 수 있을까?


여기 까지는 ‘어떻게 하면 식단을 만들 수 있을까?’에 초점이 맞춰져있었다. 물론 유저에게 더 맞는 식단을 만들기 위해서 explicit/implicit feedback을 이용하였지만 구매 확률이 높은 음식을 예측한 것은 아니었다. 그렇다면 비지니스 측면에서 어떻게 하면 유저들의 구매 전환율이나 리텐션을 증가시킬 수 있을까?

  • 여전히 필터 요소 때문에 식품 입점 상황에 따라 추천 실패가 발생하여 유저가 추천도 받아보지 못하고 이탈하는 경우가 발생한다.
  • 조건을 만족하면서도, 유저가 구매할 만한 상품들을 위주로 추천한다

1번에 대해서는 이제까지 추천 실패로 받아보지 못했던 유저들이 식단을 받아보고 1명이라도 결제로 전환이 된다면, 결제 전환에 + 방향으로 영향을 미치게 된다.

2번의 경우에는 최근 wide & deep learning for recommendation논문을 읽고 모델을 구현한 적이 있었는데 이를 활용하면 구매 예측을 할 수 있을 것이라고 생각하였다

유저의 특성에 따라 추천에 사용하는 필터를 유동적으로 한다


유저에게 추천 컨텐츠(식단)을 제공할 수 없는 경우는 보유하는 음식에 비해서 유저가 비선호하는 요소에 속하는 음식의 비율이 월등히 높아 식단을 구성할 수 없는 경우 때문이다. 이를 해결하기 위해서 식단 생성을 시도해보고 실패시에 차례로 많은 영향을 미치는 필터링 요소를 소거하여 추천을 하는 방식을 채택하였다. 이를 위해서 API요청 시에 property를 전달하여 필터 요소를 조절하는 방식을 사용하였다.

영향을 많이 미치는 요소들을 측정하기 위해서, 표본 집단을 추출하고 동일한 표본 집단에 대해서 필터 요소를 바꿔보면서 얼마나 추천에 영향을 미치는지를 측정하였다

예를 들어 알러지요소만 검사할 경우, 영양소 요소의 경우 제공된 식단의 평균적으로 93%의 끼니가 영양소 기준을 지키지 못하여 분산은 5.9가 된다는 것이다. 따라서 해당 실험 결과를 통해서 알러지 외의 다른 요소 중에는 영양소, 비선호 카테고리가 가장 많은 영향을 끼친다는 것을 알게되었습니다. 이에 따라 시도 실패에 따라서 알러지/영양소/비선호 카테고리 만 지키는 생성을 시도하고, 이후에 알러지를 제외한 요소들을 하나씩 소거하며 생성하도록 하였습니다. 이를 배포하여, 전체 추천 실패가 0명이 되었다. 또한 샐패 대응에 따른 생성에 대해서도 결제 전환율이 10%로 1000명의 유저가 기존에 추천도 못받고 이탈 하였다면 이제는 그 중 100명을 결제 유저로 전환하게 된 것이다. 만약 전체 유저에 대해서 기존 실패 확률이 10%라면, 이에 대한 10% 이므로 전체 유저의 1%가 된다. 이를 통해 결제 전환에 1%의 상승을 기여하게 되었다.

구매 확률이 높은 음식들을 위주로 식단 구성하기


식단을 생성하는 과정에서, 식품의 후보군을 만든 후에 이 후보군에 대해서 wide & deep model을 이용하여 구매 확률에 대해 예측한 뒷 랭킹화시켜 높은 랭크에 있는 음식을 위주로 추천하는 방식을 생각하게 되었다. 물론 구매 확률이 높더라도, 영양 조건을 못 지키거나 기타 다른 필터 요소를 지키지 못할 때는 추천 하지 못할 수 있다(고도화 시키면서 느꼈던 것은 유저가 구매하고 싶어하는 상품과 건강한 요소를 지키기 위해서는 유저 선호만을 따라갈 수 없다는 것이 상당히 챌린지 하다는 것이다.)

wide & deep 모델을 다음과 같이 구현하였다

기존 결제 데이터를 활용하여, 간단하게 모델을 구현한 뒤 학습한 결과 약 70%의 acc이 나왔다. 이를 좀 더 고도화 하여서 프러덕트에 적용시킨다면 유저의 객단가, 결제 전환율, 재결제에 긍정적인 영향을 미칠 수 있다고 생각한다. 현재는 해당 프로젝트를 진행중에 있다.

성과 추가) 해당 구매 예측 모델의 도입으로 결제 전환율에서 25%의 개선이 있었다
결과적으로 만들어진 시스템을 도식화하면 다음과 같다

그 간의 경험


‘나홀로’ 라고 표기한 이유는 처음 아이템을 시작할 때 개발팀의 인원이 나를 포함여 3명이었고, 각각 자신의 역할을 맡아 구현을 시작하였기 때문이다. 이 후 개발팀의 인원이 충원 되긴 했지만, 내가 하고있는 데이터 업무에는 인원이 충원되고 있지 않아 혼자 시스템을 고도화 해야하는 외로운 경험을 하고있다. 하지만 해당 프로젝트를 진행하면서 오히려 전문 영양사님이나 기획팀과의 교류가 상당히 많았던 것 같다. 그 과정에서 더 좋은 설득이나 회의 진행을 위해서 미리 데이터를 시각화하여 준비하면 좋다는 것, 이야기 할 점들을 미리 대략적으로라도 정리하고 의사소통에 임하는 것 등등을 배우게 된 것 같다. 물론 개발적으로도 고도화를 진행하면서 전반적인 코드 설계, CS적인 지식, 전에는 몰랐던 DL에 대한 부분들을 빠르게 학습하고 적용하는 경험도 해볼 수 있게 되었다. 여러 가지 공부를 하면서 적용해보는 것도 좋았지만, 역시나 나보다 경험이 많은 분과 함께 프로젝트를 진행하며 어깨 너머로 배우고 시너지를 낼 수 있었다면 더 좋지 않을까하는 아쉬움은 남아있다! 그래도 그 간의 과정들을 정리하고보니 처음과 비교 하였을 때 성장했음을 느낄 수 있어서 좋다.

profile
데이터와 파이썬을 좋아합니다 :) contact : chal405@naver.com

4개의 댓글

comment-user-thumbnail
2023년 7월 27일

좋은 글이네요. 공유해주셔서 감사합니다.

1개의 답글
comment-user-thumbnail
2023년 7월 28일

너무 좋아요

답글 달기
comment-user-thumbnail
2023년 7월 28일

정말 멋있어요!

답글 달기