[Recommendation system]Deep Learning 기반의 Recommendation System 구현 I
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)의 노드 개수가 출력층/입력층의 노드 개수보다 작아야함
- 이렇게 학습된 은닉층의 출력을 입력을 대신하는 데이터로 사용
- 데이터의 크기 축소.
- 케라스의 임베딩을 이용해서 간편하게 사용할 수 있다.