* aws summit에서 vingle의 이상현님이 진행하신 발표를 참고하였다
www.youtube.com/watch?v=-LZFJ6BpplE&ab_channel=AmazonWebServicesKorea
우선, 추천 알고리즘은 아주 다양하며, 많은 경우 이들을 중첩시켜 사용하는 하이브리드 방식으로 사용한다고들 한다.
한 알고리즘을 통해 얻은 점수와 다른 알고리즘을 통해 얻은 점수를 적절하게 다시 평균을 내는 방식으로 말이다.
(당연히 산술 평균은 아니겠고, 어느 정도 가중치를 다르게 줄 것 같다.)
여튼, 추천 방식은 다음과 같이 나뉘어 진다고 한다.
(1) 장바구니 알고리즘(연관성 규칙)
A라는 행동을 할 때 B라는 행동을 할 것이다.
장바구니 알고리즘은 여타 다른 알고리즘보다 간단한 편이기도하고, 효과도 좋다고 한다.
A라는 아이템을 구매(혹은 찜하기)하신 걸 보니 B를 하실 것 같군요? 그러니 B를 추천해드립니다.
(2) 컨텐츠 기반 필터링
과거 아마존에서 하고 있던 방법이죠? 추천 관련 특허도 냈습니다. patents.google.com/patent/US7113917B2/en
제공하고자 하는 아이템 자체를 분석(아이템의 feature를 추출)해야 하는 추천 기법입니다.
A라는 아이템은 B와 가장 비슷합니다. 그러니 B를 추천합니다.
(3) 협업 필터링 : user based filtering과 item based filtering으로 구분된다.
user based filtering이 더 자주 사용되는 편이란다.
유저의 action을 기반으로 분석해야 한다.
당신(A)라는 사람과 비슷한 사람은 B입니다. B가 본 상품 중에서 당신이 안 본 상품이 있네요? 이거 보세요
방법론이 복잡할수록 연산에도 오랜 시간이 걸리고, 이용자 자체가 적은 서비스 초반에는 추천이 정확하지 않은 경우가 많습니다.
🧐 그러면 넷플릭스는 어떻게 추천하는데?
넷플릭스의 경우 여러 필터링을 복합적으로 사용하고 있다. 넷플릭스 뿐만 아니라 추천 시스템으로 재미 좀 보고 있는 회사들은 다 하이브리드로 사용한다.
구체적으론, 같은 컨텐츠를 본 유저들이 비슷한 행동 패턴을 보이면 (이 패턴 자체를 도출하는 과정도 어려울테지만), 같은 그룹으로 묶고 협업 필터링을 거친다.
여기에 추가적으로 콘텐츠 기반 필터링 방식을 섞는데 이 때 AI 뿐만 아니라 콘텐츠에 태그를 매기는 작업을 수행한다. 이 작업을 '태깅'이라고 하는데 콘텐츠를 보고 태깅만 하는 넷플릭스의 gig 노동자들이 존재한다. 무식해보이긴하지만 2018년까지 넷플릭스는 수작업으로 태그를 매겼다고 한다. 이에 대해서는 아래 글을 참고해보자.
rbworld.tistory.com/133?category=851201
학습 여부에 따른 추천 알고리즘은 크게 2개로 나눠진다고 한다.
-비 회귀 단순 알고리즘(jaccard index, consine 유사도)
-회귀 알고리즘(인공신경망, matrix decomposition, clustering)
우선 특정 사업에서 어떤 알고리즘이나 어떤 모델을 적용해야 하는 지는 ML 엔지니어링의 자문을 받아서 수행해야한다.
그러나, 대략적인 추천 서비스를 하기 위한 인프라 구성 전략은 말할 수 있다.
AWS를 기준으로 살펴보고, 인력이 부족한 스타트업의 특성상 관리를 최소화하기 위해 serverless하게(완전 serverless가 아님) 구성해보도록하자.
비 회귀 단순 알고리즘의 경우 완전한 serverless 구성
비회귀 단순 알고리즘 중 대표적인 jaccard index는 두 집합 사이의 유사도를 측정하는 방법으로,
매우 간단하게, A, B집합의 교집합 / A, B 집합의 합집합 이란 식으로 유사도를 측정하는 방식이다.
그러니까 쇼핑몰의 경우에 A라는 아이템을 봤네? 이것과 비슷한 아이템으로 B라는게 있어! 이걸 추천해줄게!
라는 콘텐츠 기반 필터링 작업을 할 때, jaccard index 알고리즘에 의해 A와 B의 특징을 비교해야 할 수 있다는 겁니다.
코싸인 유사도를 기반으로 해도 상관은 없습니다만, 자카드 인덱스의 경우 고등학교 1학년 정도의 집합론으로도 이해할 수 있습니다 ㅎ
non regression 추천 모델 중 jaccard index를 활용한다면, serverless하게 구현할 수 있다는 발표가 있어서 서비스 관련 흐름을 첨부함.
의외로 구성 자체는 간단하다. 요약하자면 다음과 같다.
- kinesis firehose + lambda + s3로 데이터 수집
- athena로 필요한 관계 추출 => sql로 jaccard index 처리를 마친 값들을 s3에 저장해야 한다. (cronjob 하면 좋음)
- DB에 export된 s3 데이터 저장
- 필요할 때마다 lambda로 호출해서 서빙된 내용 받아오기
조금 더 세세하게 알아보자면,
[데이터 수집 과정]
유저의 액션 => api gateway => lambda => kinesis firehose => s3 => athena
- 유저가 하는 행동을 json포맷으로 보내보자. csv 같은 포맷도 괜찮긴한데 사실상 업계 통념이 json이니까 ㅋㅋ
- lambda에서는 일단 유저의 validation(올바른 유저? 올바른 시간? 올바른 json임?), 한 후 firehose로 보내야 함. 주의할 점으로 반드시 http connection keep-alive를 켜둬야 한다. 특히 node.js로 경우 필수인데, 왜냐면 node.js에서는 aws sdk랑 통신할 때 http 내부 모듈을 사용하는데 이 녀석은 connection 을 유지시켜 주지 않고 단박에 끊어버린다. 이걸 켜놔야 응답 속도가 빨라지고 최대 5배 정도 빨라질 수 있다고 함.
- firehose는 뭐하는 녀석이냐면 여러가지 소스에서 데이터를 string으로 넣어주면 알아서 하나의 파일로 정리해 줌. 여기에서 추가적으로, 최대 용량, 최대 몇 분 단위로, gzip할 것인지 등등 설정이 가능. gzip 을 반드시 켜서 올려서 firehose에서 알아서 압축해줌. 우리는 특정 s3에 올릴 거임.
- s3를 authena. athena로 뭘 하냐면, fully managed servereless service인데, 그냥 s3에 있는 데이터를 쿼리할 수 있다고 함. s3에 올라가있는 데이터를 이용하여 테이블을 만듦. 전체 데이터 스캔하니까 파티셔닝을 반드시 할 것.
[실제로 추천을 어떻게 해서 보여줄 것인가?]
athena => s3 => dynamoDB or Aurora Db => lambda => api gateway => 유저에게 제공
애지간한 계산은 athena에서 다 하고, (여기서는 item-item similarity) 결과물은 s3로 export.
이 결과물을 곧바로 받아 써도 되긴 하는데 size가 커지면 DB를 태워야 한다.
aurora는 그냥 LOAD DATA FROM S3 ‘s3://….’ 로 가져오면 된다.
dynamoDB는 dynamoDB onDemand + s3 streaming
db에 넣었다면 그럼 필요할 때마다 lambda요청해서 받아가면 된다 ㅇㅇ
[왜 athena씀?]
s3 glue 같은거 써도 되고, 뭐 방법은 많음. 근데 athena 쓰는 이유는 serverless이기 때문임.
그리고 athena는 data scan에 대해서만 과금됨. sql 쿼리 복잡도는 중요치 않고,
s3가 gzip된 경우 압축된 용량을 기준으로 요금이 과금됨. 요금 절약 매우 감사!
회귀 알고리즘을 사용해서 트레이닝을 시켜야 하는 경우
회귀 알고리즘은 이미 AWS에서 이미 managed하고 있는 서비스가 이미 많고, 특별한 관리를 요하지 않으므로 적극적으로 사용하고, 존재하지 않는다면 직접 트레이닝을 시켜야 한다.
aws에서 제공하는 툴(Rekognition, personalizae, polly 등)을 사용하는경우 아래와 같이 거의 serverless하게 구성할 수 있다.
직접 트레이닝 시키는 경우에도 학습할 데이터는 athena를 통해서 s3에 저장하는 것은 동일하다. 다른 점은, sageMaker로 training job을 생성하고 학습된 모델을 lambda에 올려서, 필요할 때마다 요청하면 된다.
aws 공식 문서에서 제공하는 aws personalize에서 첨부한 그림을 보면 아래와 같은 과정을 통해서 손쉽게 personalize된 추천값을 제공할 수 있다.
실시간이 아니라 이미 도출된 값을 단순히 뿌리기만 하면 되는 거라면, 모델을 통과시켜서 나온 값을 DB에 저장해놓고 요청이 올 때마다 단순히 정보를 주기만 하면 된다.
'Ops, Infra, etc > ⚡ serverless' 카테고리의 다른 글
이미지 서비스를 위한 리사이징 플로우 탐구 (0) | 2021.04.27 |
---|---|
[AWS] lambda에서의 DynamoDB 호출 및 제어 (sdk v2) + trouble shooting (0) | 2021.04.11 |
Killer Use Cases, Causion of AWS Lambda (0) | 2021.03.24 |
[serverless] Serverless 프레임워크 사용하기 (0) | 2020.06.15 |
[AWS] AWS Lambda + API gateway로 Serverless 만들어보기 (0) | 2020.06.14 |