
목표: 모델에게 '취향의 순서'를 가르치기
이 손실 함수의 최종 목표는 간단합니다. 모델이 사용자의 상품 선호도를 점수로 예측할 때, "당연히 더 좋아할 상품"의 점수를 "덜 좋아할 상품"이나 "싫어할 상품"의 점수보다 '충분한 격차'를 두고 더 높게 예측하도록 훈련시키는 것입니다.
Step 1. 상황 설정: 이커머스 쇼핑몰 데이터
온라인 패션 쇼핑몰 '스타일허브'의 한 사용자, '김민준' 님의 구매 기록을 예시로 들어보겠습니다.
- 사용자(User): 김민준
- 상품 데이터:
- Positive (긍정): '나이키 에어포스' (5회 구매)
- Low Rank Positive (낮은 순위 긍정): '무지 반팔티' (1회 구매)
- 구매한 적은 있지만, '나이키 에어포스'만큼 자주 찾지는 않았습니다. 선호도가 있긴 하지만 상대적으로 낮습니다.
- Negative (부정): '등산용 스틱' (구매 이력 없음)
- 김민준 님은 이 상품에 전혀 관심이 없거나, 아직 발견하지 못했습니다.
Step 2. 데이터의 벡터화 (Embedding)
컴퓨터는 '나이키 에어포스'라는 텍스트를 직접 이해하지 못합니다. 따라서 우리는 사용자 '김민준'과 각 상품을 숫자로 이루어진 벡터(Vector)로 변환해야 합니다. 이 과정을 임베딩(Embedding)이라고 합니다.
모델이 학습을 통해 이 벡터 값들을 스스로 찾아내지만, 여기서는 설명을 위해 임의의 2차원 벡터 값을 가정해 보겠습니다.
- 사용자 U (김민준): zu=[1.0,0.8]
- Positive P (나이키 에어포스): zv=[0.9,0.7]
- Low Rank Positive LRP (무지 반팔티): zl=[0.5,0.4]
- Negative N (등산용 스틱): zn=[0.1,−0.2]
직관적 이해: 벡터의 방향과 크기가 비슷할수록 '취향이 잘 맞는다'고 해석할 수 있습니다. 현재 김민준 님의 벡터는 '나이키 에어포스' 벡터와 가장 유사하고, '등산용 스틱'과는 가장 다릅니다.
Step 3. 손실 함수와 하이퍼파라미터 설정
이제 우리가 사용할 손실 함수를 다시 살펴보겠습니다.
L=αnmax(0,−zuTzv+zuTzn+Δn)+αlmax(0,−zuTzv+zuTzl+Δl)
계산을 위해 우리가 직접 정해줘야 하는 값들(하이퍼파라미터)을 설정합니다.
- Negative 마진 (Δn): 1.0 (Positive와 Negative의 점수 차이는 최소 1.0 이상 나야 한다)
- LRP 마진 (Δl): 0.3 (Positive와 Low Rank Positive의 점수 차이는 최소 0.3 이상 나야 한다)
- 핵심: Δl<Δn 입니다. 즉, '전혀 관심 없는 상품'과의 격차를 '가끔 사는 상품'과의 격차보다 더 크게 만들도록 요구하는 것입니다.
- 가중치 (αn,αl): 계산의 편의를 위해 둘 다 1로 설정합니다.
Step 4. 단계별 손실(Loss) 계산
이제 위에서 설정한 값들을 수식에 하나씩 대입하여 손실 값을 계산해 보겠습니다.
Part 1: Negative 샘플과의 손실 계산
먼저 수식의 첫 번째 부분, 즉 Positive 샘플과 Negative 샘플 간의 순위를 제대로 매기고 있는지 확인합니다.
LNegative=max(0,−zuTzv+zuTzn+Δn)
1. 선호도 점수 계산 (벡터 내적)
- 김민준 ❤️ 나이키 에어포스 (Positive 점수):
zuTzv=(1.0×0.9)+(0.8×0.7)=0.9+0.56=1.46
- 김민준 ❤️ 등산용 스틱 (Negative 점수):
zuTzn=(1.0×0.1)+(0.8×−0.2)=0.1−0.16=−0.06
2. 수식에 대입하여 손실 계산
LNegative=max(0,−1.46+(−0.06)+1.0)
LNegative=max(0,−0.52)
LNegative=0
3. 결과 해석
손실 값이 0이 나왔습니다. 이것은 "모델이 이미 잘하고 있다"는 의미입니다.
왜냐하면 Positive 점수(1.46)가 Negative 점수(-0.06) + 마진(1.0) 보다 크기 때문입니다.
(1.46>−0.06+1.0⟹1.46>0.94)
모델은 이미 두 상품의 선호도 격차를 우리가 설정한 마진(1.0) 이상으로 벌려놓았기 때문에, 이 부분에 대해서는 페널티(손실)를 주지 않습니다.
Part 2: Low Rank Positive 샘플과의 손실 계산
이제 수식의 두 번째 부분, 즉 Positive 샘플과 Low Rank Positive 샘플 간의 미묘한 순위를 잘 맞추고 있는지 확인합니다.
LLRP=max(0,−zuTzv+zuTzl+Δl)
1. 선호도 점수 계산
- 김민준 ❤️ 나이키 에어포스 (Positive 점수): (위에서 계산) 1.46
- 김민준 ❤️ 무지 반팔티 (LRP 점수):
zuTzl=(1.0×0.5)+(0.8×0.4)=0.5+0.32=0.82
2. 수식에 대입하여 손실 계산
LLRP=max(0,−1.46+0.82+0.3)
LLRP=max(0,−0.34)
LLRP=0
3. 결과 해석
이 부분의 손실 값도 0이 나왔습니다.
Positive 점수(1.46)가 LRP 점수(0.82) + 마진(0.3) 보다 크기 때문입니다.
(1.46>0.82+0.3⟹1.46>1.12)
모델은 '나이키 에어포스'와 '무지 반팔티' 사이의 미묘한 선호도 차이도 우리가 설정한 마진(0.3) 이상으로 잘 구분하고 있습니다.
최종 손실:
L=(1×LNegative)+(1×LLRP)=0+0=0
이 경우, 모델은 이미 완벽하게 순위를 학습했으므로 벡터 값을 업데이트할 필요가 없습니다.
Step 5. 모델이 "틀렸을 때"는 어떻게 될까? (학습 과정)
만약 모델이 아직 학습이 덜 되어 벡터 값들이 아래와 같다고 가정해 봅시다. '무지 반팔티'의 벡터가 '나이키 에어포스'보다 김민준 님의 취향에 더 가깝게 잘못 설정된 상황입니다.
- 사용자 U (김민준): zu=[1.0,0.8]
- Positive P (나이키 에어포스): zv=[0.9,0.7]
- Low Rank Positive LRP (무지 반팔티): zl=[0.8,0.9] (수정된 값)
- Negative N (등산용 스틱): zn=[0.1,−0.2]
이때 손실을 다시 계산해 보겠습니다. (Part 1의 Negative 손실은 이전과 동일하게 0입니다.)
Part 2 (재계산): Low Rank Positive 샘플과의 손실
1. 선호도 점수 재계산
- 김민준 ❤️ 나이키 에어포스 (Positive 점수): 1.46
- 김민준 ❤️ 무지 반팔티 (LRP 점수):
zuTzl=(1.0×0.8)+(0.8×0.9)=0.8+0.72=1.52
문제 발생! 모델이 LRP 상품('무지 반팔티')의 점수를 Positive 상품('나이키 에어포스')보다 더 높게 예측했습니다. 이것은 명백한 오류입니다.
2. 수식에 대입하여 손실 계산
LLRP=max(0,−1.46+1.52+0.3)
LLRP=max(0,0.36)
LLRP=0.36
3. 결과 해석 및 학습 방향
드디어 0이 아닌 손실 값 0.36이 발생했습니다!
- 최종 손실: L=(1×0)+(1×0.36)=0.36
- 학습 신호: 이 0.36이라는 숫자는 모델에게 "너 지금 틀렸어! 이만큼의 오류가 있으니 수정해!"라고 알려주는 강력한 신호가 됩니다.
- 업데이트 방향:
- 모델은 이 손실을 줄이기 위해(0으로 만들기 위해) 벡터 값들을 조정합니다.
- zu (김민준)와 zv (나이키) 벡터를 서로 더 가깝게 만들어 zuTzv 점수를 높입니다.
- zu (김민준)와 zl (반팔티) 벡터를 서로 더 멀게 만들어 zuTzl 점수를 낮춥니다.
이 과정을 수많은 사용자-상품 데이터에 대해 반복하면서, 모델은 점차 모든 상품에 대한 사용자의 상대적인 선호도 순위를 정확하게 예측하는 능력을 갖추게 됩니다. 이것이 바로 Max Margin Loss가 추천 시스템의 성능을 향상시키는 핵심 원리입니다.