Embarrassingly Shallow Autoencoders for Sparse Data: EASE 모델이 희소 데이터에 강한 이유
Embarrassingly Shallow AutoEncoders for Sparse Data

아이템과 유저에 대한 implicit feedback인 interaction matrix








- P_hat을 치환해서 다시 위의 B_hat에 대한 식 정리

- 위에서 라그랑주 승수의 근사값을 정의해서 정리했음

- 이 라그랑즈 승수 근사값은 **제약조건을 통해 결정 가능**


- 다시 B_hat에 치환하여 정리

- 찐막 정리하면

→ 즉 대각 원소가 아닌 원소들은 전부 P_hat에 의해 결정되므로, P_hat 수식을 살펴보면 람다는 하이퍼파라미터이므로 결국 G=X_T*X가 중요해진다.
→ 입력 데이터에 의해 B에 영향을 주는 것은 item-to-item matrix, gram matrix인 X_T*X
→ 이는 결국 co-occurence matrix가 되어서, **어떤 한 아이템이 유저에게 선택되었을 때, 다른 아이템도 같이 선택되었을 빈도가 어느 정도인지를 나타내는 행렬**
이 값이 두 가지 다른 요인에 의해 증가될 수 있다.
→ 유저 수가 증가하면 데이터의 sparsity가 보완될 수 있다.
X의 크기는 |U| | I | 이지만, G의 크기는 | I | | I | 이기 때문
### 학습 과정
import numpy as np
# 딥 러닝 모델이 아니므로 nn.Module을 상속받을 필요가 없다.
class EASE:
def __init__(self, _lambda):
self.B = None
self._lambda = _lambda
def train(self, X):
G = X.T @ X # G = X'X
diag_indices = list(range(G.shape[0]))
G[diag_indices, diag_indices] += self._lambda # X'X + λI
P = np.linalg.inv(G) # P = (X'X + λI)^(-1)
self.B = P / -np.diag(P) # - P_{ij} / P_{jj} if i ≠ j
min_dim = min(*self.B.shape)
self.B[range(min_dim), range(min_dim)] = 0 # 대각행렬 원소만 0으로 만들어주기 위해
def forward(self, user_row):
return user_row @ self.B### 입려 데이터에 대한 학습 과정
X = inputs # 학습 데이터
_lambda = 300
ease = EASE(_lambda)
ease.train(X)### 입력 데이터에서 각 유저별로 활동 이력에 없는 아이템 중 어떠한 아이템을 보여주는 것이 좋을지
### ranking을 구하는 inference 과정
result = ease.forward(X[:, :])
result[X.nonzero()] = -np.inf # 이미 어떤 한 유저가 클릭 또는 구매한 아이템 이력은 제외
잘봤습니다.