[Recommendation system]Deep Learning 기반의 Recommendation System 구현 I

1 minute read

ML 기반 추천 엔진: SVD & 딥러닝 추천 엔진

SVD 알고리즘 소개

사용자/아이템 기반 협업 필터링의 문제점

  • 확장성(scalability): 큰 행렬 계산은 여러모로 쉽지 않음
    • 하지만 아이템 기반으로 가면 계산량이 줄어듬(아이템에 대한 평점은 생각보다 적기 때문에. 사람들이 생각보다 후기 잘 안씀)
    • Spark을 사용하면 큰 행렬 계산 쉽게 가능
  • 부족한 데이터(sparse data)
    • 많은 사용자들이 충분한 수의 리뷰를 남기지 않음
  • 해결책: 모델 기반 협업 필터링
    • 머신 러닝 기술을 사용해 평점 예측. 입력은 사용자-아이템 평점 행렬
      • 행렬분해 방식
      • 딥러닝 방식

행렬 분해 방식

  • 협업 필터링 문제를 사용자-아이템 평점 행렬을 채우는 문제로 재정의
    • 행이 사용자, 열이 아이템일때 유사도가 없는 빈칸들을 채우는 문제이다.
    • 사용자 또는 아이템을 적은 수의 차원으로 차원수 축소하여 문제를 간단화
  • 가장 많이 사용되는 행렬 분해 방식
    • PCA
    • SVD 또는 SVD++

PCA(Principal Component Analysis)

  • 차원을 축소하되 원래 의미는 최대한 그대로 간직

SVD(Singular Vector Decomposition)

  • 2개 혹은 3개의 작은 행렬의 곱으로 단순화(일종의 소인수분해)
    • PCA와 같은 차원축소 알고리즘이지만 다른 방식
  • SVD와 SVD++
    • 사용자 대 아이템 행렬(행: 사용자, 열: 아이템)을 훨씬 작은 3개의 행렬로 나눠 표현
    • $A = U \sum V^T$
      • $U$: 사용자를 나타내는 훨씬 작은 행렬
      • $\sum$: $U$의 특정 부분을 시그널을 증폭시켜주는 행렬(대각 행렬). 여길 보면 덜 중요한 부분 파악 가능
      • $V^T$: 아이템을 나타내는 훨씬 작은 행렬(치환)

SVD++

  • SVD++: 넷플릭스 컨테스트에서 고안된 추천방식
    • SVD나 PCA는 완전하게 채워져 있는 행렬의 차원수를 줄이는 방식
    • SVD++는 sparse 행렬이 주어졌을 때 비어있는 셀들을 채우는 방법을 배우는 알고리즘
      • 채워진 셀들의 값을 최대한 비슷하게 채우는 방식으로 학습(에려율을 최소화)
        • 보통 RMSE의 값을 최소화하는 방식으로 학습하면서 SGD를 사용
      • A(사용자 대 아이템 평점 행렬 u * n)를 입력으로 주면 $A = U \sum V^T$
        • $U$: 사용자 행렬(u * r)
        • $\sum$: 스케일 행렬(r * r)
        • $V^T$: 아이템 행렬(r * n)
        • r은 n보다 훨씬 작은 값
  • surprise 라이브러리 or 사이킷런의 TruncatedSVD 사용

오토인코더 소개

오토인코더란?

  • 대표적인 비지도학습을 위한 딥러닝 모델
    • 입력으로 들어간 것이 다시 출력이 된다. 입력 차원수 == 출력 차원수
    • input(입력 이미지) -> encoder(작은 차원의 수로 줄인다) -> latent space(압축된 데이터) -> decoder -> output(복원된 이미지)
    • 인코더를 통해 차원이 줄어들어도 정보양은 줄어들지 않아 학습 속도를 높일 수 있다!
    • 데이터의 숨겨진 구조를 발견하면서 노드의 수를 줄이는 것이 목표(데이터의 차원을 줄이는 것)
    • 입력 데이터에서 불필요한 특징들을 제거한 압축된 특징을 학습하려는 것
    • 오토인코더의 출력은 입력을 재구축한 것임
      • 최대한 비슷하게 나오도록 학습
      • 입력 데이터와 예상 출력 데이터가 동일
        • 입력 == 레이블
  • 오토인코더의 구조
    • 출력층의 노드 개수와 입력층의 노드 개수가 동일해야함
    • 은닉층(latent space)의 노드 개수가 출력층/입력층의 노드 개수보다 작아야함
  • 이렇게 학습된 은닉층의 출력을 입력을 대신하는 데이터로 사용
    • 데이터의 크기 축소.
  • 케라스의 임베딩을 이용해서 간편하게 사용할 수 있다.