(광고아님) 유독 스포티파이가 노래 추천을 잘한다는 평이 많은 이유

서론: 음악 추천이 영화 추천보다 어려운 이유

음악 추천은 영화 추천보다 본질적으로 훨씬 복잡한 문제다. 영화는 최소 1시간에서 3시간 이상의 러닝타임을 가지며, 썸네일과 줄거리만으로도 대략적인 선호도를 예측할 수 있다. 반면 음악은 3-4분에 불과하며, 전 세계에서 매일 수만 곡이 쏟아져 나온다. 여기서 발생하는 대표적인 문제가 바로 **Cold Start Problem(콜드 스타트 문제)**이다.

오늘 막 데뷔한 인디 밴드의 신곡은 재생 수 0, 좋아요 0, 플레이리스트 추가 0의 상태에서 시작한다. 데이터가 전무한 상황에서는 추천 자체가 불가능하고, 추천되지 않으면 영원히 묻히는 악순환이 발생한다. 스포티파이 엔지니어들은 이 문제를 해결하기 위해 근본적인 질문을 던졌다. “사람들이 듣기도 전에 노래 자체를 보고 어떤 취향의 사람에게 맞을지 먼저 예측할 수는 없을까?” 이 질문에서 시작된 것이 바로 AI에게 사람의 귀를 이식하는 작업이다.

1. Raw Audio Analysis: CNN으로 소리의 지문 읽기

Mel-Spectrogram을 통한 오디오의 시각화

스포티파이의 핵심 기술 중 하나는 **Raw Audio Analysis(원본 오디오 분석)**이다. AI에게 음원을 단순 음파 신호로만 전달하는 것이 아니라, **Mel-Spectrogram(멜 스펙트로그램)**이라는 일종의 ‘소리의 지문’ 이미지로 변환한다.

Mel-Spectrogram은 소리를 시간에 따라 펼쳐 그린 2차원 이미지다:

  • 가로축: 시간의 흐름
  • 세로축: 음의 높낮이(주파수)
  • 색깔의 진하기: 해당 순간 해당 음의 크기(진폭)

음악 플레이어에서 볼 수 있는 이퀄라이저의 막대기가 춤추는 것을 고해상도로 확장한 히트맵(Heat Map)이라고 이해하면 된다. 앞에 붙은 ‘Mel’은 사람 귀가 느끼는 음 높낮이 간격에 맞춰 주파수 축을 비선형적으로 조정한 것으로, 기계가 아닌 인간의 청각 특성에 맞춰 재배열된 스펙트로그램이다.

CNN을 활용한 패턴 인식

스포티파이는 이 Mel-Spectrogram을 **Convolutional Neural Network(합성곱 신경망, CNN)**에 입력한다. CNN은 원래 이미지 분류를 위해 개발된 모델로, 고양이와 강아지를 구별하는 등 시각적 패턴 인식에 특화되어 있다. 스포티파이 엔지니어들의 발상은 단순하면서도 강력했다. “어차피 Mel-Spectrogram도 이미지잖아? 그럼 그냥 CNN에 넣어보자.”

이렇게 학습된 CNN은 가수 이름도, 가사도 모르는 상태에서 오직 소리의 시각적 패턴만으로 다음과 같은 특징들을 추출한다:

  • 고음역대가 날카롭게 솟아 있으면 → 디스토션 기타 사용 가능성
  • 저음이 두껍고 지속적이면 → 힙합 베이스 느낌
  • 리듬 패턴이 기계적으로 일정하면 → 일렉트로닉 장르 가능성
  • BPM(Beats Per Minute), 에너지, 어쿠스틱 느낌 등

이는 마치 눈을 가린 절대미각 셰프에게 “요리 이름은 몰라도 되니 매운 정도, 기름진 정도, 바삭한 정도만 숫자로 표현해달라”고 요청하는 것과 같다. 셰프는 요리 이름을 모르지만 “매운맛 8점, 기름진맛 6점, 바삭함 9점” 같은 수치화된 특징을 제공한다. 스포티파이도 마찬가지로 곡마다 템포(Tempo), 에너지(Energy), 발렌스(Valence, 밝고 어두운 정도), 댄서빌리티(Danceability), 어쿠스틱니스(Acousticness) 등의 특징을 **수백 차원짜리 벡터(Vector)**로 만들어 저장한다.

이 덕분에 오늘 막 발매된 무명 아티스트의 신곡이라도, 그 곡의 오디오 특징 벡터가 기존 인기곡들과 유사하다면 즉시 추천 리스트에 올라갈 수 있게 된다. 이것이 Cold Start Problem의 핵심 해결책이다.

2. NLP & Text Embedding: 플레이리스트 제목이 곧 감정 지도

소리만으로는 감성을 완전히 포착할 수 없다

CNN 기반 오디오 분석만으로는 한계가 있다. 음악은 결국 감성이며, “새벽 감성”, “비 오는 날”, “전 여친 생각날 때” 같은 맥락은 Mel-Spectrogram만 봐서는 포착하기 어렵다. 그래서 스포티파이는 귀 대신 사람들의 입과 손을 데이터로 가져온다. 바로 텍스트 데이터다.

스포티파이의 NLP(Natural Language Processing, 자연어 처리) 모델이 분석하는 텍스트는 다음과 같다:

  • 곡 제목, 앨범 설명, 아티스트 소개
  • 가사(Lyrics)
  • 사용자가 직접 작성한 플레이리스트 제목 ← 핵심 데이터

Word Embedding을 통한 감정의 수치화

NLP 모델은 이러한 텍스트를 읽고 각 단어와 문장을 **벡터로 변환(Embedding)**한다. Word2Vec, BERT와 같은 임베딩 기법을 사용하면, 컴퓨터가 이해할 수 있는 숫자 공간에서 단어 간의 의미적 유사성이 거리로 표현된다:

  • “슬픈”, “비”, “새벽”, “이별” 같은 단어들은 벡터 공간에서 서로 가까운 곳에 모인다.
  • “헬스장”, “3대 500”, “PR 갱신” 같은 단어들은 BPM이 빠르고 에너지가 높은 곡들 근처에 위치한다.

이렇게 생성된 텍스트 임베딩과 앞서 오디오에서 추출한 오디오 특징 벡터를 결합하면, AI는 다음과 같은 기가 막힌 수식을 만들어낼 수 있다:

"흐린 날 + 발라드" ≈ "소주 한 잔 생각나는 노래"

즉, 사용자가 무심코 지은 플레이리스트 제목(“새벽 감성”, “비 오는 날 듣는 노래”, “실연의 아픔”)이 실제로는 AI에게 인간 감정 지도를 가르쳐주는 최고급 레이블 데이터셋이었던 것이다.

3. User Modeling: 장기 취향 vs. 단기 기분

스포티파이는 사용자를 크게 두 가지 축으로 모델링한다:

(1) 장기 취향 (Long-term Preference)

지난 몇 년간 사용자가 반복해서 듣고, 좋아요를 누르고, 플레이리스트에 저장한 곡들을 종합하여 **취향 벡터(Preference Vector)**를 구성한다:

  • 락(Rock): 0.7
  • 발라드(Ballad): 0.5
  • 재즈(Jazz): 0.2
  • 평균 선호 BPM: 115

이는 일종의 음악 DNA로, 사용자의 기본적인 음악적 정체성을 나타낸다.

(2) 단기 기분 (Short-term Context)

문제는 락을 좋아하는 사람도 연인과 싸운 새벽 2시에는 락보다 감성적인 발라드를 듣고 싶을 수 있다는 점이다. 그래서 스포티파이는 **세션 기반 단기 기분(Session-based Context)**도 함께 분석한다:

  • 현재 어떤 기기에서 듣는지 (스마트폰, PC, 차량 등)
  • 직전에 어떤 곡들을 연속으로 들었는지
  • 각 곡을 얼마나 길게 들었는지 (스킵 여부)
  • 현재 시각 (아침 출근길, 저녁 퇴근길, 새벽 시간대)

이러한 시퀀스 데이터를 RNN(Recurrent Neural Network) 또는 Transformer 모델에 입력하여 “지금 이 순간의 상태 벡터”를 추출한다. 알고리즘은 다음과 같이 판단한다:

"원래 이 사람은 락 선호도가 높은데, 지금은 새벽 감성 모드로 스위치됐네?"

4. Candidate Generation & Ranking: 2단계 추천 파이프라인

스포티파이의 추천 시스템은 대부분 2단계 파이프라인으로 구성된다:

1단계: Candidate Generation (후보 생성)

목표는 “완전히 정확할 필요는 없고, 대충 쓸만한 곡 수천 개를 빠르게 모으는 것”이다. 다음과 같은 방식으로 후보를 수집한다:

  • 사용자 취향 벡터와 유사한 곡들
  • 취향이 비슷한 다른 사용자들이 자주 듣는 곡들 (Collaborative Filtering)
  • 사용자가 팔로우한 아티스트의 신곡
  • 현재 국가/전 세계에서 트렌딩 중인 곡들

이 단계는 마치 마트에서 카트에 일단 대충 담아오는 과정과 비슷하다. 속도와 다양성이 우선이다.

2단계: Ranking (순위 매기기)

이제 진짜 심사가 시작된다. 후보로 모인 수천 곡 각각에 대해 **“이 사람에게 지금 이 상황에서 이 곡이 얼마나 잘 맞을까?”**를 점수로 매긴다.

입력 요소는 크게 3가지:

  1. User(사용자): 장기 취향 벡터
  2. Item(곡): 오디오 특징 벡터 + 텍스트 임베딩
  3. Context(상황): 현재 세션 상태, 시간대, 기기

점수 계산 시 고려하는 요소:

  • 사용자 장기 취향 vs. 곡 특징의 벡터 거리
  • 현재 세션 상태 vs. 곡 무드(Mood)의 적합성
  • 과거 유사한 곡을 얼마나 오래 들었는지
  • 곡의 전체 인기도 및 최근 트렌드
  • Exploration-Exploitation Balance: 너무 새롭지 않으면서도 살짝 모험적인 정도

이 점수대로 정렬한 결과가 바로 사용자가 앱을 켰을 때 보게 되는 홈 화면, 자동 재생, 데일리 믹스(Daily Mix), 라디오 등이다. 엔지니어 관점에서 보면, UI는 모두 이 점수로 정렬된 결과물의 나열에 불과하다.

5. Collaborative Filtering & ANN: 수억 명의 취향을 0.0몇 초 만에 검색하기

30초 Rule: 유효 청취의 기준

스포티파이가 사용자-곡 행렬을 구성할 때 매우 중요하게 보는 기준이 있다. 바로 30초다:

  • 30초 미만 재생: 관심 없거나 별로였을 가능성 높음 → 강한 마이너스 신호
  • 30초 이상 재생: 최소한 한 번은 끝까지 들어볼 만하다고 판단 → Valid Play(유효 청취)

30초는 아티스트 정산 기준이기도 하며, 추천 시스템에서도 핵심 기준점으로 활용된다. 여기에 반복 재생, 플레이리스트 추가, 좋아요 등의 행동이 추가 점수로 반영된다.

Matrix Factorization & Embedding

이 점수판(User-Item Matrix)을 가지고 행렬 분해(Matrix Factorization) 또는 딥러닝 임베딩을 수행하면, 각 사용자와 각 곡이 잠재 취향 공간(Latent Factor Space) 위에 좌표를 갖게 된다.

ANN(Approximate Nearest Neighbor): 속도의 마법

문제는 계산 복잡도다. 전 세계 5억 명의 사용자를 전부 비교하려면 시간이 너무 오래 걸린다. 여기서 스포티파이가 꺼낸 무기가 Annoy(Approximate Nearest Neighbors Oh Yeah) 라이브러리다.

Annoy는 “가장 정확한 이웃”을 찾는 대신, “대충 매우 비슷하면서 개빨리 찾을 수 있는 이웃”을 골라준다. 스포티파이는 이런 ANN(Approximate Nearest Neighbor) 기법을 활용해 취향이 비슷한 사용자들을 0.0몇 초 만에 찾아낸다.

그래서 사용자가 앱을 켜자마자 지구 반대편 브라질의 Carlos가 듣고 있던 그 곡이 순식간에 홈 화면에 뜨게 되는 것이다.

6. Multi-Armed Bandit & Reinforcement Learning: 슬롯머신 도박꾼 AI

여기까지 오면 추천을 “잘하는” 앱은 이미 완성됐다. 그러나 스포티파이의 목표는 다르다. **“오늘 한 곡 더 듣게 만드는 것”이 아니라 “다음 달에도 이 앱을 켜게 만드는 것”**이다.

Multi-Armed Bandit 알고리즘

여기서 등장하는 것이 Multi-Armed Bandit(다중 슬롯머신) 알고리즘이다. 쉽게 말해 “슬롯머신 여러 대가 있을 때, 어디에 동전을 넣어야 장기적으로 딴지를 가장 많이 딸 수 있을까?”를 푸는 문제다.

스포티파이는 여기서 슬롯머신을 노래로 바꾼다:

  • 이미 검증된 인기곡, 사용자가 항상 좋아하던 곡 → 안전한 슬롯머신 (Exploitation)
  • 데이터는 아직 부족하지만 모델이 보기에 가능성 있는 신곡, 인디곡 → 모험 슬롯머신 (Exploration)

Bandit의 역할은 단순하다: **“이번 재생리스트에 안전빵을 몇 곡, 모험을 몇 곡 섞을까?”**를 결정하는 것이다.

사용자가 김치찌개를 좋아한다고 해서 365일 내내 김치찌개만 추천하면 처음엔 좋다가 나중에 질려서 떠난다. 반대로 맨날 처음 보는 똠양꿍만 추천하면 짜증나서 바로 앱을 끈다. 그래서 비율을 섞는다:

  • 오늘: 안전빵 8곡, 모험 2곡
  • 내일: 안전빵 7곡, 모험 3곡

이 비율을 계속 바꿔가며 실험을 돌리고 통계를 쌓는다. 사용자가 낯선 곡을 스킵하지 않고 끝까지 들으면, 그 순간 AI는 “오케이, 이 사람 취향 영토가 이 방향으로 한 칸 확장됐다”고 기록한다.

Reinforcement Learning: 장기 보상 최적화

실험 단계에서는 강화학습(Reinforcement Learning) 계열 알고리즘을 얹어 “어떤 조합의 추천이 장기적으로 더 좋은지”를 계속 탐색한다.

강화학습을 한 줄로 정리하면:

“내 행동에 따라 보상이 달라질 때, 그 보상을 최대화하는 방향으로 정책(Policy)을 업데이트하는 알고리즘”

여기서 보상(Reward)은:

  • 지금 곡을 끝까지 들었냐 (단기 보상)
  • 오늘 세션 시간 (중기 보상)
  • 일주일 뒤 재방문 여부 (장기 보상)
  • 한 달 뒤 유료 구독 유지 여부 (최종 보상)

즉, **“지금 이 타이밍에 어떤 곡을 틀어줘야 장기적으로 이 사람이 앱을 안 끊을까?”**를 계속 실험하고 학습하는 구조다.

7. Discover Weekly: 매주 월요일의 음악 오마카세

이 모든 기술이 가장 예쁘게 드러나는 기능이 바로 **Discover Weekly(새 위클리 추천곡)**이다. 로직을 단순화하면 다음과 같다:

  1. 최근 몇 주 동안 사용자가 반복 재생하고, 저장하고, 좋아요를 누른 곡들을 본다.
  2. 그 곡들을 좋아하는 다른 사용자 집단을 찾는다. (Collaborative Filtering)
  3. 그 집단은 자주 듣지만 나만 아직 안 들어본 곡들을 뽑는다.
  4. 그 중에서 오디오 특징과 감성 맥락이 내 취향과 너무 동떨어지지 않은 곡들만 남긴다.
  5. 이렇게 골라낸 곡들을 30곡 정도로 압축해 월요일마다 한 번에 포장해서 보내준다.

말 그대로 **알고리즘이 차려주는 음악 오마카세(Omakase)**다.

8. 사용자를 위한 실전 팁

그렇다면 도대체 어떻게 해야 알고리즘이 나를 덜 괴롭히고 더 잘 추천해줄까?

Tip 1: 싫은 곡은 빠르게 스킵하라

어차피 스킵할 곡이라면 2초 안에 넘기는 편이 낫다. 30초를 넘기면 “최소한 한 번은 유효하게 들은 곡”으로 기록될 수 있다.

Tip 2: 좋아하는 곡은 꼭 저장 또는 좋아요를 누르라

그냥 듣기만 하고 아무 행동도 하지 않으면 “나쁘진 않은데 엄청 좋아하는 건 아닐 수도”로 애매하게 남는다. 명확한 신호가 명확한 추천을 만든다.

Tip 3: 플레이리스트를 직접 만들어라

플레이리스트 제목은 생각보다 강한 신호다. 같은 곡이라도 어떤 제목의 리스트에 넣느냐에 따라 그 곡의 감성 좌표가 달라진다.

Tip 4: 마구잡이로 틀어놓지 마라

카페에서 여러 사람이 내 계정으로 이것저것 막 틀어버리면, 알고리즘 입장에서는 “이 사람 취향이 갑자기 여러 조각으로 쪼개졌다”고 보일 수 있다.

알고리즘이 무서운 점은 우리가 아무 생각 없이 하는 행동도 모두 데이터로 쌓인다는 점이다. 좋은 점은 우리가 의식적으로 행동을 조금만 조절해도 알고리즘이 꽤 빠르게 방향을 바꾼다는 점이다.

결론: 세상을 벡터로 바꾸는 시스템

스포티파이는 단순히 노래를 틀어주는 앱이 아니다. 엔지니어 관점에서 보면 다음과 같은 복합 시스템이다:

  • CNN으로 소리의 물리적 특징을 추출
  • NLP 임베딩으로 가사와 플레이리스트 맥락을 숫자로 변환
  • **협업 필터링(Collaborative Filtering)**과 ANN(Approximate Nearest Neighbor) 기법으로 전 세계 수억 명의 취향 좌표를 빠르게 검색
  • Multi-Armed Bandit을 포함한 강화학습 아이디어로 탐색(Exploration)과 활용(Exploitation) 사이의 균형을 조절하며 추천 전략을 계속 실험·최적화

스포티파이가 하는 일을 두 줄로 요약하면:

  1. 세상의 모든 노래와 사람을 벡터(숫자)로 바꾸는 것
  2. 새로운 데이터가 들어올 때마다 그 벡터들 사이의 거리를 끊임없이 다시 정의해 나가는 것

우리는 그냥 “오늘 추천 괜찮네?” 정도로 넘기고 말지만, 백엔드 서버에서는 모델이 계속 재학습되고, 수억 개의 벡터가 매일 재배열되고 있다.