Tae Hyun Kim (Lowell)

DeepFM

정의

DeepFM (Guo et al., 2017)은 FM component와 Deep component를 병렬로 결합해, 저차 특성 상호작용(low-order feature interaction, explicit)과 고차 특성 상호작용(high-order feature interaction, implicit)을 동시에 학습하는 CTR 예측 모델이다.

y^=σ(yFMlow-order+yDNNhigh-order)\hat{y} = \sigma\big(\underbrace{y_{\text{FM}}}_{\text{low-order}} + \underbrace{y_{\text{DNN}}}_{\text{high-order}}\big)

FM Component (Wide)

Factorization Machine과 동일한 2차 특성 상호작용을 학습한다.

yFM=w0+i=1nwixi+i=1nj=i+1nvi,vjxixjy_{\text{FM}} = w_0 + \sum_{i=1}^{n} w_i x_i + \sum_{i=1}^{n} \sum_{j=i+1}^{n} \langle \mathbf{v}_i, \mathbf{v}_j \rangle x_i x_j

Deep Component

밀집 임베딩(dense embedding)을 입력으로 받는 순방향 신경망(feed-forward neural network)이다.

a(0)=[e1,e2,,em]\mathbf{a}^{(0)} = [\mathbf{e}_1, \mathbf{e}_2, \ldots, \mathbf{e}_m] a(l)=ReLU(W(l)a(l1)+b(l))\mathbf{a}^{(l)} = \text{ReLU}(\mathbf{W}^{(l)} \mathbf{a}^{(l-1)} + \mathbf{b}^{(l)}) yDNN=wTa(L)+by_{\text{DNN}} = \mathbf{w}^T \mathbf{a}^{(L)} + b

핵심: 공유 임베딩(shared embedding)

FM component의 잠재 벡터(latent vector) vi\mathbf{v}_i와 Deep component의 임베딩(embedding) ei\mathbf{e}_i가 동일한 파라미터를 공유한다. 이렇게 하면 세 가지 이점이 따라온다.

  • 두 component가 서로의 학습 신호를 강화한다.
  • 특성 공학(feature engineering) 없이 원시 특성(raw feature)만으로 end-to-end 학습한다.
  • 파라미터 수를 줄인다.

직관적 이해

CTR 예측에서 특성 상호작용은 두 종류로 나뉜다.

  • 저차(low-order): “남성 + 슈팅게임 → 클릭 확률 높음”처럼 명시적이고 해석 가능한 2차 조합이다.
  • 고차(high-order): “20대 남성 + 금요일 저녁 + 모바일 + 신작 RPG → 클릭”처럼 여러 특성이 복합적으로 얽힌 상호작용이다.

Google의 Wide & Deep은 Wide(암기, memorization)와 Deep(일반화, generalization)을 결합하자고 제안했지만, Wide 부분에 수동 특성 공학(cross-product)이 필요했다. DeepFM은 Wide를 FM으로 대체해 2차 상호작용을 자동으로 학습하고, Deep이 고차 상호작용을 보완한다.

DeepFM

Mermaid source (click to expand)
> flowchart LR
>     Input["Sparse Input"] --> Emb["Shared Embedding Layer"]
>     Emb --> FM_comp["FM Component<br/>(2nd-order interaction)"]
>     Emb --> DNN["Deep Component<br/>(high-order interaction)"]
>     FM_comp --> Add(("+"))
>     DNN --> Add
>     Add --> Sigmoid["σ(·)"] --> Output["CTR"]
>

Wide & Deep과의 비교

기준Wide & DeepDeepFM
Wide 부분Cross-product (수동 설계)FM (자동 학습)
Feature engineering필수 (전문가 지식)불필요
Embedding 공유Wide/Deep 별도공유
Low-order interaction수동 정의된 조합만모든 2차 조합

FM 계보에서의 위치

모델구조Interaction
Factorization MachineFM onlyexplicit 2차
DeepFMFM + DNN (parallel)explicit 2차 + implicit high-order
xDeepFMCIN + DNNexplicit high-order + implicit high-order
AutoIntSelf-attention + DNNattention-weighted high-order

DeepFM의 한계는 고차 상호작용이 DNN의 implicit 학습에만 의존한다는 점이다. xDeepFM은 CIN(Compressed Interaction Network)으로 explicit 고차 상호작용을 더해 이 한계를 보완했다.

장단점

장점:

  • 특성 공학이 불필요하다. 원시 특성만으로 end-to-end 학습한다.
  • 공유 임베딩 덕분에 FM과 DNN이 서로 보완하며 학습한다.
  • Wide & Deep보다 일관되게 성능이 향상된다(Criteo, Company 데이터셋).
  • 구현이 비교적 단순해 산업계에서 CTR baseline으로 널리 쓰인다.

단점:

  • 고차 상호작용이 DNN의 implicit 학습에 의존하므로 explicit하지 않다.
  • DNN의 깊이와 너비에 따라 하이퍼파라미터 튜닝이 필요하다.
  • 임베딩 차원이 모든 특성에 동일하다(field별 최적 차원이 다를 수 있다).
  • 순차 패턴(user behavior sequence)을 직접 모델링하지 못한다.

구현

DeepFM의 핵심 구조다(PyTorch).

import torch
import torch.nn as nn

class DeepFM(nn.Module):
    def __init__(self, field_dims: list[int], embed_dim: int, mlp_dims: list[int]):
        super().__init__()
        num_fields = len(field_dims)
        total_dims = sum(field_dims)

        # Shared Embedding
        self.embedding = nn.Embedding(total_dims, embed_dim)
        self.offsets = torch.tensor([0] + field_dims[:-1]).cumsum(0)

        # FM: 1차 + 2차
        self.linear = nn.Embedding(total_dims, 1)
        self.bias = nn.Parameter(torch.zeros(1))

        # Deep
        mlp_input = num_fields * embed_dim
        layers = []
        for dim in mlp_dims:
            layers += [nn.Linear(mlp_input, dim), nn.ReLU(), nn.Dropout(0.2)]
            mlp_input = dim
        layers.append(nn.Linear(mlp_input, 1))
        self.mlp = nn.Sequential(*layers)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        # x: (batch, num_fields) — field별 feature index
        x = x + self.offsets.to(x.device)
        embed = self.embedding(x)  # (batch, fields, embed_dim)

        # FM component
        linear_out = self.linear(x).sum(dim=1)      # 1차항
        sum_sq = embed.sum(dim=1) ** 2               # (Σe_i)²
        sq_sum = (embed ** 2).sum(dim=1)             # Σe_i²
        fm_out = 0.5 * (sum_sq - sq_sum).sum(dim=1, keepdim=True)  # 2차항

        # Deep component
        deep_out = self.mlp(embed.view(embed.size(0), -1))  # flatten → MLP

        return torch.sigmoid(self.bias + linear_out + fm_out + deep_out).squeeze(1)

관련 개념

  • Factorization Machine - DeepFM의 Wide 부분; 2차 feature interaction 기초
  • Wide and Deep - DeepFM이 개선한 선행 모델; Wide에 feature engineering 필요
  • FNN - FM pre-training + DNN; DeepFM과 달리 end-to-end 학습 불가
  • PNN - Product layer로 interaction 학습; low-order 항 부재
  • Hybrid-Expert Adaptor - KAR에서 DeepFM을 backbone 추천 모델로 사용
  • Multi-Task Learning - FM/Deep의 병렬 학습을 multi-task 관점으로 해석 가능

참고 논문

  • guoDeepFMFactorizationMachineBased2017 - DeepFM 원논문
  • rendleFactorizationMachines2010 - FM 원논문; DeepFM의 이론적 기반
  • Cheng, H., et al. (2016). Wide & deep learning for recommender systems. DLRS 2016. — DeepFM이 개선한 선행 연구
  • Lian, J., et al. (2018). xDeepFM: Combining explicit and implicit feature interactions. KDD 2018. — DeepFM의 후속 발전

연결 그래프