Home
🚕

정보 : 우버 이츠에서 Graph을 추천에 사용하는 방법(번역)

UberEats

(2019.12 기준) 36개국 5000개 이상의 도시에 320,000개의 레스토랑을 연결해주고 있음
최근 Graph의 강력함에 영감을 받아 유저가 관심 가질만한 음식을 추천하는 Graph Model을 구축함
이를 통해 플랫폼에서 음식 및 레스토랑 추천 품질을 개선했음

GNN

연결되어있는 Node간 확률이 최대가 되고, 끊어져있는 Node간 확률이 최소화 되도록 GNN 학습함
Neighbor Sample을 수행하면 아무리 큰 그래프라도 Computation Cost가 커지지 않아서 확장 가능
Node의 기본 Feature과 연결관계가 주어지면 새로운 Node에 대해서도 Representation을 뽑을 수 있음
이를 통해 대규모의 & 새롭게 추가되는 사용자와 음식에 대해 추천이 가능함

Recommendation in UberEats

메인 피드에선 과거 주문 기록 등을 이용해 추천 시스템이 레스토랑과 메뉴 캐러셀을 취향에 맞게 추천해줌
추천 시스템은 (1) Candidate Generation, (2) Personalized Ranking 두 파트로 이루어져 있음
Candidate Generation은 메뉴와 레스토랑이 계속 증가하므로 확장성 있는 구조로 만들어야 함
Personalized Ranking은 유저가 상호작용하는 맥락(요일,시간,위치)를 바탕으로 순위를 매김

GNN in UberEats

Graph System

2개의 Bipartite Graph를 이용해 UberEats의 상호작용을 표현함
첫 번째는 유저와 메뉴(Dish)간의 Bipartite Graph로 Edge는 메뉴를 주문한 횟수를 표현함
두 번째는 유저와 레스토랑간의 Bipartite Graph로 Edge는 레스토랑에 주문한 횟수를 표현함
GNN 모델로는 확장성 때문에, 이웃을 Sampling하는 방법인 GraphSAGE를 사용했음

GraphSAGE

Node의 Feature를 Projection해 Type별로 같은 차원을 갖도록 함
Edge의 연결 강도에 따른 가중치를 부여해주고 싶어서 새로운 컴포넌트을 도입함
일반적인 Margin Loss는 Edge에 강도에 따른 가중치를 주기 어려워서 Low-Rank Positive을 이용함
Negative Sample 뿐만아니라, Row Rank인 Positive Sample에 대해서도 Loss를 발생시킴
Neighborhood Sampling, Aggregation 과정에서도 연결 강도에 따른 가중치를 이용했음
이렇게 학습된 GNN은 Embedding 모델의 역할을 하며 DownStream Task에 활용됨

Evaluation

Offline은 4개월동안의 데이터를 학습시키고, 이후 10일에 대하여 모델 성능을 테스트함
사용자와 해당 지역의 모든 요리&레스토랑간의 거리를 계산하고 그 안에 실제 주문한게 있는지 확인함
모든 지표(MPR, Precision@K, NDCG)에서 기존 모델보다 20% 이상의 성능 향상을 얻어낼 수 있었음
추가로 Ranker에 GNN Embedding을 Feature로 사용했더니 기존 모델 대비 AUC 12% 향상됨
Ranker의 Feature Importance를 분석해보니 GNN Embedding이 지배적이었음
위의 결과를 바탕으로 GNN에 확신이 생겨 Online Test도 진행함
샌프란에서 A/B Test한 결과 GNN Feature를 사용한 경우 기존보다 CTR과 Engagement가 크게 향상됨

Data & Training Pipeline

GNN이 Recsys에 긍정적 Impact를 가져다 주는것을 확인했음
광범위한 사용을 위해 Production에서 Real-Time Train & Inference가 가능한 파이프라인을 구축함 (아래 파이프를 보면 알겠지만 Real-Time은 아님 ㅎㅎ..)
도시별로 Graph가 느슨하게 연결되어있으므로, 이를 분리해서 도시별 Graph를 구축 & 학습시켰음
데이터 파이프라인을 통해 Raw 주문 데이터를 Aggregated Feature와 Graph로 녹여냈음
Step 1
Hive 테이블에서 병렬로 데이터를 가져오고, Node와 Edge 정보를 갖고있는 Paquet으로 변환
Node, Edge는 TimeStamp로 버저닝된 프로퍼티가 있음 (Backfill등의 재현을 위함인 듯)
Step 2
날짜가 주어지면, 날짜 기준 Node와 Edge의 최신 Property를 Cypher로 변환해서 저장함
Production으로 나가는 모델을 학습시킬때는 항상 현재 날짜 사용, 과거 날짜에 대해서도 프로세스 동일함
Step 3
Spark로 Cypher Query를 실행시켜 도시별 Graph를 생성해냄
Step 4
생성된 Graph를 NetworkX형태로 변환하고, Model Train & Embedding Generation에 넘겨줌
생성된 Embedding은 Lookup Table에 저장되어 추천 요청이 있을 때 Ranking 모델이 검색해옴

Visualized Learned Embedding

Graph Representation의 특징을 파악하기 위해 가상의 시나리오에 따른 임베딩 시각화를 해봄
탄두리치킨과 야채 커리(인도음식들)를 주문한 신규 사용자가
아래의 음식을 주문하면 임베딩 어떻게 달라지는지를 관찰함
피자, 콥샐러드, 도넛, 마파두부, 치킨 마살라, 난
다 같은 그래프인데 하이라이팅 박스만 다르게 함 X축은 추가 주문 전 Y축은 추가 주문 후 코사인 유사도를 나타냄
(좌측 하단)
아무런 하이라이팅 하지 않은 표
(좌측 상단)
X축과 Y축의 양상이 많이 다른걸 볼 수 있는데, 모델이 새로운 요리를 추천해줄 수 있음을 시사함
(우측 하단)
신규 사용자가 인도음식을 주문했으므로 X축이 커질수록 인도음식이 많아짐
X축 높은 중국요리도 꽤있는데 이는 인도음식과 중국 음식이 어느정도 상관관계가 있다는것을 보여줌
Y축을 보면 중국요리가 상당히 많은데 마파두부 주문이 영향을 미친것을 보임
(우측 상단)
추가주문을 하고 나니 아메리칸, 이탈리안, 타이, 코리안이 올라간 걸 볼 수 있음
아메리칸, 이탈리안은 피자, 도넛, 콥샐러드가 영향을 끼친 결과로 보임
인도와 중국음식 때문에 타이 코리안이 올라감

Future Directions

대규모로 이미 배포된 추천시스템에도 Graph를 이용해 개선할 수 있는 다양한 옵션이 있음
우리도 Graph를 이용해 추천 품질을 끌러 올렸으나 할 일이 많이 남아있음
1.
메뉴과 레스토랑을 분리해서 학습시키는 것을 통합하려고 함
2.
우버 이츠가 처음 들어가는 도시와 같이 데이터가 없는 경우에도 추천을 잘하는 방법을 찾고있음