현재 진행하고 있는 프로젝트인 Filmeet에서 사용자 개인에 맞는 영화를 추천하는 기능을 맡았습니다.
이번 글에서는 이러한 추천 기능을 구현하면서 어떤식으로 로직을 짜고 구현을 했는지에 대해 이야기 하려 합니다.
목표
추천 기능을 구현하기 위해 자료를 검색하던 중, 넷플릭스의 영화 추천 알고리즘에 대한 자료를 접하게 되었습니다.
해당 자료에 따르면, 넷플릭스는 4개의 주요 추천 알고리즘을 활용한다고 합니다:
- 유사 사용자 기반 알고리즘
- 유사 아이템 기반 알고리즘
- 잠재 모델 기반 알고리즘
- 콘텐츠 기반 알고리즘
넷플릭스는 이 4개의 알고리즘을 포함한 여러 알고리즘을 조합해 하이브리드 추천 시스템을 구현했다고 합니다.
(출처: 브런치 자료)
이 자료를 참고하며 저 역시 2개의 추천 알고리즘을 결합한 하이브리드 추천 시스템을 설계하기로 했습니다.
이를 통해 사용자에게 더 정확하고 맞춤화된 추천을 제공하고,
'나를 위한 서비스'처럼 느껴지는 개인화된 경험을 제공하자는 목표를 세웠습니다."
하이브리드 추천 시스템
하이브리드 추천 시스템에서 사용한 2가지 추천 방식입니다.
콘텐츠 기반 추천
- 사용자가 선호하는 영화의 장르나 특성을 분석하여 유사한 콘텐츠를 추천합니다.
- 예를 들어, 사용자가 액션 영화에 많이 반응 했다면 비슷한 장르의 영화를 추천합니다.
유사 사용자 기반 추천
- 나와 관심사가 비슷한 사용자들을 분석하고, 그들이 선호하는 영화를 추천합니다.
- 이를 통해 다양한 시각을 반영하고 더 폭넓은 추천 결과를 제공합니다.
하이브리드 추천의 장점
- 두 가지 방식을 결합해 각각의 단점을 보완하고 추천의 정확도와 다양성을 극대화했습니다.
- 콘텐츠 기반 추천은 사용자의 선호 패턴을 바탕으로 추천하지만, 취향이 고정적이거나 콘텐츠의 특성이 명확하지 않은 경우 추천의 한계가 발생할 수 있습니다.
- 유사 사용자 기반 추천은 비슷한 사용자들의 데이터를 활용하지만, 데이터가 부족하거나 특정 사용자 그룹의 편향된 추천이 발생할 수 있습니다.
하이브리드 방식은 두 추천 방식의 강점을 결합해 이러한 한계를 상호 보완합니다.
콘텐츠 기반 추천의 정확성과 유사 사용자 기반 추천의 다양성을 동시에 반영하여, 사용자에게 더 정교하고 풍부한 추천을 가능하게 합니다.
이를 통해 프로젝트 Filmeet은 하이브리드 추천 시스템을 통해 사용자에게 더 빠르고 정확한 영화 추천을 제공하며, 영화 탐색의 편의성을 높이고 서비스 만족도를 향상시킬 수 있습니다.
그럼 이제 세부적으로 콘텐츠 기반 추천과 유사 사용자 기반 추천을 어떻게 구현 했는지에 대해 이야기 하겠습니다.
콘텐츠 기반 추천
1. 사용자가 선호하는 영화 장르 파악
초기 추천
회원가입 후 로그인을 하면 영화 장르를 선택하게 했습니다.
그래서 초기에는 이렇게 선택한 선호 장르 중심으로 영화를 보여 줍니다.
사용자는 영화에 대해 게임, 좋아요, 별점, 컬렉션과 같은 다양한 행동을 할 수 있습니다.
이러한 행동 데이터를 기반으로, 각 영화의 장르와 관련된 점수가 사용자의 선호도에 더해지게 됩니다.
이를 통해 사용자가 선호하는 영화 장르를 파악할 수 있습니다.
초기 행동 점수 가중치
- 선호 장르 20
- 별점 1 ~ 5
- 좋아요 3
- 컬렉션 3
- 게임 결과 3
선호 장르 같은 경우에는 초기에 사용자에게 영화를 보여주기 위한 기준이라 상대적으로 높은 점수를 부여 했습니다.
별점 같은 경우에는 사용자가 0.5 ~ 5.0으로 동적으로 점수를 남기고 있어 해당 점수를 반영 했습니다.
반면 좋아요나 게임 같은 사용자 행동에 대해서는 고정된 점수를 부여했습니다.
예를 들어, 좋아요든 게임이든 장르 점수에 +3이 더해지도록 설정했는데,
이는 모든 사용자의 행동을 동일하게 간주하는 방식이었습니다.
하지만, 어떤 사용자는 좋아요를 많이 하는 패턴을 보이고,
다른 사용자는 별점을 자주 남기는 패턴을 보이는 등,
사용자별 행동 패턴이 서로 다르다는 점을 고려해야 했습니다.
따라서, 사용자 행동의 다양성을 반영하기 위해
사용자 행동의 가중치를 동적으로 조정하기로 했습니다.
행동 점수 동적 가중치
- 많이 반복된 행동에는 낮은 가중치를 부여해 특정 행동이 과도하게 영향을 미치는 것을 방지하고,
- 적게 반복된 행동에는 더 높은 가중치를 부여해 희소한 행동이 가진 중요도를 반영했습니다.
결국, 이러한 방식은 사용자 행동의 특성을 공정하게 반영하고,
더 정교하고 개인화된 추천 결과를 제공하기 위해 도입 했습니다.
만약 가중치를 고정한다면 어떻게 될까요?
좋아요를 과도하게 누르는 사용자
어떤 사용자가 모든 영화에 좋아요를 누르는 경우,
좋아요의 점수가 고정(+3)이라면 이 사용자의 선호도가 왜곡됩니다.
실제로는 특별히 선호하는 영화가 아닌데도 추천 결과에 과도한 영향을 미칠 수 있습니다.
별점을 드물게 주는 사용자
반대로, 어떤 사용자는 별점을 매우 신중하게 주는 경우,
별점 행동이 드문 행동임에도 고정 점수(+3)가 적용된다면,
이 사용자의 강한 선호가 제대로 반영되지 못하는 문제가 발생합니다.
특정 행동의 편중
한 사용자가 게임을 많이 하지만 별점은 거의 사용하지 않을 경우,
게임 점수가 고정되어 있으면 다른 행동의 중요도가 낮아져 균형이 깨질 수 있습니다.
사용자 활동 점수를 계산 및 업데이트 배치 작업
사용자들의 행동 점수를 업데이트하기 위해 Spring Batch와 Scheduler를 활용 했습니다.
매일 새벽 3시에 전체 사용자의 최대, 최소, 평균 통계 데이터를 활용해
각 사용자의 활동 점수를 계산하고 업데이트 하도록 했습니다.
step1
- 전체 사용자 활동 통계 데이터(최대, 최소, 평균)를 조회
step2
- 전체 사용자를 조회
- 통계를 바탕으로 각 사용자의 활동 점수를 계산
- 각 사용자들의 활동 점수 업데이트
2. 해당 장르에 속하는 영화 추천
앞서 사용자가 선호하는 영화 장르를 어떻게 파악하는지에 대해 설명 했습니다.
이번에는 이렇게 파악한 선호 장르를 바탕으로 어떻게 영화 추천을 하는지에 대해 설명 하겠습니다.
필터링 작업
우선 데이터를 더욱 정교하게 선별하기 위해 다양한 필터링 조건을 적용 했습니다.
- 사용자가 선호하는 장르에 속하는 영화만 가져오기
- 사용자가 리뷰, 좋아요, 별점, 컬렉션 등의 행동을 하지 않은 영화 가져오기
- TOP 10에 속하는 영화는 제외하기
필터링된 영화들에 대해 점수 계산을 통해 최종 추천 목록을 만듭니다.
- 먼저, 각 영화의 평균 별점과 좋아요 개수를 0~1 사이로 정규화합니다.
- 이후, 변환된 별점과 좋아요 점수에 가중치를 곱해 최종 점수를 계산합니다.
- 마지막으로, 계산된 점수를 기준으로 높은 점수 순으로 정렬하여 사용자에게 영화 목록을 제공합니다.
유사 사용자 기반 추천
이제 유사 사용자 기반 추천에 대해 설명드리겠습니다.
1. 사용자와 관심사가 비슷한 다른 사용자들 파악
먼저, 사용자와 관심사가 비슷한 다른 사용자들을 어떻게 파악하는지 설명드리겠습니다.
- 사용자는 본인이 팔로잉한 유저들을 기준으로 비교합니다.
- 이후, 나이, MBTI, 행동 점수(좋아요, 별점 등) 데이터를 활용해 유사도를 계산합니다.
- 유사도 계산에는 코사인 유사도를 사용했습니다.
코사인 유사도란?
코사인 유사도(Cosine Similarity)는 두 벡터 간의 각도를 기반으로 유사도를 측정하는 방법
벡터 간의 크기(길이)가 아닌, 방향(각도)에 초점을 맞추기 때문에, 데이터가 다양한 크기를 가지더라도 특성 간의 유사성을 계산할 수 있다.
코사인 유사도는 나이, MBTI, 행동 점수처럼 서로 다른 특성을 하나의 벡터로 결합하여
정확하고 균형 있게 유사도를 계산할 수 있는 방법입니다.
이러한 이유로 코사인 유사도를 채택했습니다.
코사인 유사도로 본인과 다른 사용자들간에 유사도를 계산하고
계산된 유사도 점수를 바탕으로 상위 5명의 유저를 유사 사용자로 선택합니다.
2. 다른 사용자들이 선호하는 영화 추천
이제 선택한 유사 사용자들을 바탕으로 어떻게 영화를 추천하는지 설명하겠습니다.
- 먼저 유사한 사용자들의 장르 점수를 장르별로 그룹화하고, 각 그룹의 점수를 합산하여 점수가 높은 순으로 정렬해 상위 5개 장르를 선정합니다.
- 선정된 각 장르에서 20개의 영화 데이터 조회합니다. 이때 콘텐츠 기반 추천에 선정된 영화는 제외합니다.
- 가져온 영화들의 평균 별점과 좋아요 개수를 정규화하여 0~1 사이의 값으로 변환하고 가중치 적용합니다.
- 가중치가 적용된 점수를 바탕으로 최종 영화 점수를 계산한 뒤, 상위 점수의 영화를 출력합니다.
영화 추천 최종 작업
최종 영화 추천
최종적으로 콘텐츠 기반 추천 60%와 유사 사용자 기반 추천 40%의 비율로 추천 영화를 구성합니다.
유사 사용자 기반 추천에서는 최대 8개의 영화를 가져오며, 팔로잉 데이터가 부족한 초기에는 부족한 부분을 콘텐츠 기반 추천으로 보완합니다. 이 과정을 통해 최종적으로 20개의 추천 영화를 출력합니다.
사용자 영화 추천 업데이트 배치 작업 & 스케줄러
모든 사용자를 대상으로 실시간으로 추천 영화를 생성하려면 시스템 리소스에 큰 부담이 될 수 있습니다.
이를 해결하기 위해 스케줄러와 배치 작업을 활용하여 매일 새벽 6시에 데이터를 일괄 처리하고, 각 사용자의 추천 영화를 업데이트하도록 했습니다.
마무리
지금까지 콘텐츠 기반 추천과 유사 사용자 기반 추천을 결합하여 하이브리드 추천 로직을 구현한 과정에 대해 이야기 했습니다. 결론적으로, 사용자 취향을 더 정확하게 반영하여 더 나은 추천 경험을 제공하기위해 두 추천 방식을 결합한 하이브리드 추천 로직을 구현했습니다.
넷플릭스, 왓챠와 같이 거대한 OTT 기업에서의 영화 추천과는 비교도 안되겠지만 나름 사용자들에게 나를 위한 서비스처럼 느껴지는 개인화된 경험을 제공하자는 목표로 하이브리드 추천 로직을 구현하는 좋은 경험이었습니다.
'프로젝트 > Filmeet' 카테고리의 다른 글
API 성능 테스트부터 최적화까지 – 15초에서 0.1초로, 병목 해결 여정 (0) | 2024.12.22 |
---|---|
Redis 분산 락을 활용하여 동시성 문제 해결하기 (0) | 2024.12.04 |
@Query with "not in" not work with empty List parameter (0) | 2024.12.02 |
MultipleBagFetchException - 두 개 이상의 OneToMany 관계에서 N+1 문제 최적화하기 (0) | 2024.11.22 |
동적 조건 처리를 위한 Querydsl 사용하기 (0) | 2024.11.21 |