[토이 프로젝트] ML 영화 추천 플랫폼

2025. 3. 27. 17:07토이 프로젝트

시작

2023년 1학기.

우리학교는 신기하게 3학년, 4학년 때 2번의 졸업작품을 만들고 통과해야 졸업을 할 수 있다.

이게 나의 첫번째 졸업작품 프로젝트였다.


구성

팀은 3명으로 구성되었고, 백엔드 1, ML 1, 프론트 1로 구성되었지만 나는 ML을 전반적으로 맡고 백엔드에도 약간 참여했다.

 

개요

우리가 평소 쉽게 접할 수 있는 여러 가지 OTT서비스에는 방대한 양의 영화들이 존재한다. 매번 OTT 서비스를 이용할때면 방대한 양의 영화들 중 어떤 영화를 선택해야할지 고민하는 과정에서 사용자 피로도가 증가한다. 메인페이지에서 협업필터링을 통해 영화가 추천되지만 최근 내가 봐왔던 장르에 대해서만 추천해준다는 한계점도 존재했다.

 

이 점을 고려해 ML을 이용한 영화추천 플랫폼을 만들고자 했다. 하지만 Spring을 제대로 처음 다뤄보는 프로젝트였고 ML에 대해선 무지한 상태라 가능할까? 라는 의문점에서 시작하게 된 프로젝트이다.

 

많은 타협과 라이브러리를 사용했지만, 전체 성적 1등으로 3학년의 졸업작품을 끝낼 수 있었던 뜻깊은 프로젝트였다.

내가 주로 맡았던 부분은 ML이기 때문에 ML만 좀 구체적으로 설명하도록 하겠다.

 


프론트엔드 / 백엔드 간단 소개

프론트와 백엔드는 팀원들이 주로 담당해줬고 전반적인 구조도 완성도를 높이기 위해 정말 많은 노력을 해줬다.

 

  • 프론트엔드 :
    • TMDB와 KOFIC API를 활용해 영화 데이터를 수집하고 검색 기능, 페이징, 트레일러 조회까지 구현했다. 영화 검색 시 장르/키워드/제작사 필터도 가능하고 영화 상세 페이지에서는 댓글과 평점을 입력할 수 있도록 만들었다.
  • 백엔드 :
    • Java Spring Boot로 구현되었으며 JWT 기반 인증, 사용자 정보 관리, 평점/댓글 저장 및 조회 API, 머신러닝 추천 결과를 전달하는 API 등을 구헝했다. 추천 기능은 파이썬 Flask 서버와 통신하는 구조로 되어 있다.

👉 위 두 영역은 저희 팀원들이 주로 구현했고 저는 머신러닝 알고리즘을 내가 담당하게 되었다


ML

내용 기반 + 키워드 기반 추천

- 사용자가 재밌게 본 영화의 내용을 기반으로 유사한 다른 영화를 추천하는 방식이다. 각 영화의 줄거리 및 키워드를 전처리한 후 TF-IDF를 적용해 문서 간 가중치를 벡터화하고 코사인 유사도를 통해 유사도를 측정했다.

더보기

사용 기술 : TF-IDF, 코사인 유사도, 형태소 분석(Mecab)

형태소 분석

KoNLPy 기반 분석기를 테스트했는데.. 윈도우 환경에서 문제가 있어 대신 Mecab-ko를 사용했다. 명사/형용사 위주로 핵심 단어만 남기고 불용어를 제거해 전처리를 수행했다.

 

추천 로직

  1. 장르가 하나라도 겹치는 영화를 유사 영화 후보군으로 설정
  2. 유사도 상위 10개 영화를 백엔드로 전달해 화면에 출력

성능 평가

★ 내용 기반 추천 정확도 : 약 91%

★ 키워드 기반 추천 정확도 : 약 51%

 


협업 필터링

- 사용자의 평가 데이터를 기반으로 비슷한 취향의 사용자들이 높게 평가한 영화를 추천하는 방식이다.

더보기

사용 기술 : SVD (Surprise 라이브러리), 피어슨 상관계수, 멀티스레딩

문제와 해결

  • 기본 SVD는 영화 평점 자체에 편향되어 있어 취향 유사성을 더 반영하고자 했다.
  • 그래서 피어슨 상관계수 기반의 사용자 유사도를 추가로 계산해 예측 평점에 보정값으로 반영했다.

추천 로직

  1. Surprise 패키지로 SVD 기반 예측 평점 생성
  2. 사용자 간 피어슨 유사도 계산 (유사 사용자일수록 높은 가중치)
  3. 특정 영화에 대해 추천한 사용자들의 유사도 평균을 예측 평점에 더함
  4. 최종 점수가 높은 영화 3편을 메인화면에 추천

속도 문제 해결

추천 시 계산량이 많아 멀티스레드 기반 병렬 처리를 적용 -> 연산 시간이 약 5분 -> 10초로 단축

 

성능 평가

직접 엑셀로 비교하며 정확도는 약 98%로 측정되었다.

 

 


개념정리

TF-IDF

TF-IDF는 문서 안에서 특정 단어의 중요도를 수치로 나타내는 방법이다.

  • TF (Term Frequency) : 해당 단어가 문서 내에서 얼마나 자주 등장했는지 계산한다.
  • IDF (Inverse Document Frequency) : 그 단어가 전체 문서에서 얼마나 희귀한 단어인지 계산한다.

즉, 문서 내에서 자주 등장하고 전체 문서에서 자주 등장하지 않아야 가중치가 높아진다. 그, 그리고, 그래서 와 같은 접속부사나 접속어 등은 문서 내에서도 자주 등장하지만 단어 전체에서도 자주 등장해 가중치가 낮아야한다. 이런 경우때문에 TF-IDF를 사용한다. 

 

코사인 유사도

두 벡터 사이의 각도를 기준으로 얼마나 유사한지 판단하는 것이다. 그래서 TF-IDF로 문서를 벡터화한 후 사용해야한다. 각도가 작을수록, 즉 코사인 값이 1에 가까울수록 두 문서의 내용은 비슷하다고 본다

 

형태소 분석

한국어 문장을 다룰 때는 띄어쓰기만으로 의미 단위를 분리하기 어렵다. 그래서 텍스트를 분석할 때는 "형태소"라는 최소 단위로 문장을 나누는 작업이 필요하다.

 

더보기

바나나를 좋아한다 -> ["바나나", "좋아", "하", "ㄴ다"]

 

이런식으로 단어의 어간, 어미를 나눠 의미를 보존한 채 처리할 수 있도록 만드는 것이 형태소 분석이다.

 

Mecab-ko로 명사/형용사 중심으로 핵심 단어를 추출하고 조사/접속사 등 의미 없는 불용어는 제거했다.

 

SVD

행렬 분해 기반 협업 필터링 알고리즘

 

예를 들어 사용자가 여러 영화에 대해 남긴 평점이 있다고 가정한다면 이 데이터를 행렬 형태(사용자 x 영화)로 정리할 수 있다. 이 행렬을 SVD로 분해하면 사용자의 취향과 영화의 특징을 숫자 벡터로 표현할 수 있게 된다.

 

SVD는 이렇게 분해된 정보를 바탕으로 보지 않은 영화의 평점을 예측한다. 즉, 이 사용자는 이런 취향을 가졌으니 이 영화도 좋아할 것 같다는 식으로 판단하는 것이다.

 

  • 장점 : 데이터가 많을수록 정확도가 높아지고 사용자와 아이템의 잠재 요인을 학습할 수 있음
  • 단점 : 단순히 평점 평균이 높은 영화에 추천이 집중되는 경향이 있음

 

피어슨 상관계수

사용자들 간의 취향 유사도를 수치로 나타내는 방법

 

  • 범위 : -1.0 ~ 1.0
    • 1.0에 가까울수록 -> 매우 비슷한 평가 경향
    • -1.0에 가까울수록 -> 완전 반대의 평가 경향
    • 0에 가까울수록 -> 관계 없음

이 프로젝트에서는 같은 영화를 본 사용자들 간의 평점 패턴 유사도를 측정하기 위해 사용했다. SVD가 영화 자체에 편향되는 경우가 많기 때문에 피어슨 유사도를 함께 고려하면 나와 비슷한 취향의 사용자들이 좋아한 영화에 더 높은 점수를 줄 수 있다고 생각했다.

 

 

SVD와 피어슨 유사도를 같이 사용하면

 

SVD -> 전체적인 평점 예측

피어슨 유사도 -> 개인 취향 반영을 위한 보정값

 

이렇게 개인화 정확도를 높여 보다 신뢰도 높은 추천 시스템을 만들 수 있었다.

 


느낀점

머신러닝을 따로 배워본 적 없지만 스스로 학습하면서 이 정도까지 구현해냈다는 점에 자부심을 느꼈다.. 단순히 작동하는 시스템이 아니라 정확도와 효율성을 고민하고 수차례 구조를 수정해가며 만들어낸 결과물이다.

 

진짜 처음하는거라 너무 힘들었고 머리가 깨질것 같았지만..ㅎㅎ 가장 재미있고 가장 힘들었기에 가장 기억에 남는 프로젝트 중 하나이다.