---
id: wiki-2026-0508-collaborative-filtering
title: Collaborative Filtering
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [CF, recommender system, matrix factorization, ALS, two-tower, neural CF, hybrid recommender]
duplicate_of: none
source_trust_level: A
confidence_score: 0.93
verification_status: applied
tags: [recommender-system, collaborative-filtering, matrix-factorization, als, embedding, two-tower, cold-start]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: Python
  framework: implicit / Surprise / TensorFlow Recommenders / PyTorch
---

# Collaborative Filtering

## 매 한 줄
> **"매 비슷한 사람의 취향 → 매 추천"**. 매 user-item interaction 의 mining. 매 matrix factorization (Netflix prize) 가, 매 modern: 매 two-tower NN + 매 embedding + 매 graph + 매 transformer (BERT4Rec, SASRec). 매 cold start + sparsity 의 핵심 challenge.

## 매 핵심

### 매 type

#### Memory-based
- **User-based**: 매 similar user 의 like.
- **Item-based**: 매 같이 consume 된 item.
- 매 cosine / Pearson similarity.

#### Model-based
- **Matrix Factorization** (SVD, ALS): 매 latent factor.
- **Neural CF**: 매 NN embedding.
- **Two-Tower**: 매 user + 매 item encoder.
- **Sequence model** (SASRec, BERT4Rec).
- **Graph NN** (LightGCN).

#### Hybrid
- **Content + collaborative**.
- **Multi-stage ranking**.

### 매 evaluation
- **MAP / NDCG**: 매 ranking quality.
- **Recall@k / Hit@k**.
- **Coverage**: 매 catalog 의 portion.
- **Diversity**: 매 result variation.
- **Novelty**: 매 new discovery.
- **Serendipity**: 매 surprising relevance.
- **Online**: A/B 의 CTR / conversion.

### 매 challenge

#### Cold start
- 매 new user / item 의 history X.
- 매 mitigation: 매 content feature.

#### Sparsity
- 매 most user-item pair 의 unrated.
- 매 mitigation: 매 implicit feedback (click, view).

#### Filter bubble
- 매 echo chamber.
- 매 mitigation: 매 exploration / diversity.

#### Popularity bias
- 매 head item 의 dominate.
- 매 mitigation: 매 inverse propensity score.

#### Position bias
- 매 top result 의 click ↑ regardless.
- 매 mitigation: 매 position-aware learning.

### 매 modern stack
- **Candidate generation**: 매 ANN (Faiss, ScaNN).
- **Ranking**: 매 deep model (DeepFM, DCN-V2, transformer).
- **Re-ranking**: 매 diversity / business rule.
- **Multi-task**: 매 click + dwell + conversion.

### 매 응용
1. **E-commerce**: 매 product.
2. **Streaming**: 매 video / music.
3. **Social**: 매 friend / content.
4. **Job**: 매 candidate / posting.
5. **Education**: 매 course.
6. **Search**: 매 click model.

## 💻 패턴

### Implicit ALS (matrix factorization)
```python
from implicit.als import AlternatingLeastSquares
from scipy.sparse import csr_matrix

# 매 user-item interaction (count or implicit)
data = csr_matrix(user_item_matrix)

model = AlternatingLeastSquares(factors=128, regularization=0.01, iterations=20, use_gpu=True)
model.fit(data)

# 매 recommend for user
user_id = 42
recs, scores = model.recommend(user_id, data[user_id], N=10)
```

### Two-Tower (TensorFlow Recommenders)
```python
import tensorflow as tf
import tensorflow_recommenders as tfrs

class UserModel(tf.keras.Model):
    def __init__(self, embedding_dim=64):
        super().__init__()
        self.user_emb = tf.keras.layers.Embedding(n_users, embedding_dim)
    def call(self, user_id):
        return self.user_emb(user_id)

class ItemModel(tf.keras.Model):
    def __init__(self, embedding_dim=64):
        super().__init__()
        self.item_emb = tf.keras.layers.Embedding(n_items, embedding_dim)
    def call(self, item_id):
        return self.item_emb(item_id)

class TwoTower(tfrs.Model):
    def __init__(self):
        super().__init__()
        self.user = UserModel()
        self.item = ItemModel()
        self.task = tfrs.tasks.Retrieval(
            metrics=tfrs.metrics.FactorizedTopK(candidates=item_dataset),
        )
    def compute_loss(self, batch, training=False):
        u = self.user(batch['user_id'])
        i = self.item(batch['item_id'])
        return self.task(u, i)

model = TwoTower()
model.compile(optimizer='adam')
model.fit(train_ds, epochs=10)
```

### ANN (Faiss) for serving
```python
import faiss
import numpy as np

# 매 item embedding 의 build (after train)
item_emb = item_model.predict(all_item_ids)  # (N, D)

index = faiss.IndexFlatIP(item_emb.shape[1])  # 매 inner product
index.add(item_emb.astype('float32'))

def serve(user_id, k=10):
    user_emb = user_model.predict([user_id])
    scores, indices = index.search(user_emb.astype('float32'), k)
    return indices[0]
```

### Sequence (SASRec / BERT4Rec)
```python
import torch
import torch.nn as nn

class SASRec(nn.Module):
    def __init__(self, n_items, dim=128, max_seq=50, n_layers=2):
        super().__init__()
        self.item_emb = nn.Embedding(n_items + 1, dim, padding_idx=0)
        self.pos_emb = nn.Embedding(max_seq, dim)
        self.transformer = nn.TransformerEncoder(
            nn.TransformerEncoderLayer(d_model=dim, nhead=2, dim_feedforward=dim*4),
            num_layers=n_layers,
        )
    
    def forward(self, seq):
        pos = torch.arange(seq.size(1)).unsqueeze(0).to(seq.device)
        x = self.item_emb(seq) + self.pos_emb(pos)
        # 매 causal mask (left-to-right)
        mask = torch.triu(torch.ones(seq.size(1), seq.size(1)), diagonal=1).bool()
        x = self.transformer(x, mask=mask)
        return x  # 매 last position → 매 next item prediction
```

### Cold start (content fallback)
```python
def recommend(user_id, n=10):
    history = get_user_history(user_id)
    
    if len(history) < 5:
        # 매 cold start: 매 popular + 매 content profile
        if user_features.get(user_id):
            return content_based(user_features[user_id], n)
        else:
            return popular_items(n)
    
    # 매 normal: collaborative
    return cf_model.recommend(user_id, n)
```

### Diversity (MMR)
```python
def diverse_rerank(candidates, user_profile, lambda_=0.5):
    """매 Maximal Marginal Relevance."""
    selected = []
    while candidates and len(selected) < 10:
        best_score = -float('inf')
        best_item = None
        for c in candidates:
            relevance = score(user_profile, c)
            if not selected:
                novelty_penalty = 0
            else:
                max_sim = max(similarity(c, s) for s in selected)
                novelty_penalty = max_sim
            mmr = lambda_ * relevance - (1 - lambda_) * novelty_penalty
            if mmr > best_score:
                best_score, best_item = mmr, c
        selected.append(best_item)
        candidates.remove(best_item)
    return selected
```

### Position bias correction (counterfactual)
```python
def ips_train(model, X, y, position):
    """매 inverse propensity score weighting."""
    propensity = position_propensity(position)  # 매 P(click | position) for any item
    weights = 1 / propensity
    # 매 weighted loss
    return F.cross_entropy(model(X), y, weight=weights)
```

### Online evaluation (A/B)
```python
def ab_test(variant, user_id):
    bucket = hash(user_id) % 100
    return {
        'control': bucket < 50,
        'variant': bucket >= 50,
    }[variant]

# 매 metric: CTR, conversion, dwell time, retention.
```

## 🤔 결정 기준
| 상황 | Approach |
|---|---|
| Implicit data | ALS / two-tower |
| Sequential | SASRec / BERT4Rec |
| Graph (social) | LightGCN |
| Cold start | Content + popular |
| Real-time | ANN serving |
| Multi-task | Multi-objective NN |
| Long-tail | IPS + diversity |

**기본값**: Two-Tower + Faiss + diversity rerank. 매 sequence-heavy = SASRec.

## 🔗 Graph
- 부모: [[Recommender-System]] · [[Machine-Learning]]
- 변형: [[Matrix-Factorization]] · [[ALS]] · [[Two-Tower]]
- 응용: [[Faiss]] · [[Embedding]]
- Adjacent: [[Cognitive Biases]] · [[Algorithmic Fairness]] · [[CLIP]] (multimodal)

## 🤖 LLM 활용
**언제**: 매 recommendation system. 매 personalization. 매 search ranking. 매 cold-start design.
**언제 X**: 매 small data (<10K interaction). 매 deterministic ranking.

## ❌ 안티패턴
- **Popularity bias 무시**: 매 head item 의 dominate.
- **Cold start 의 ignore**: 매 new user 의 fail.
- **Filter bubble 의 ignore**: 매 user 의 stuck.
- **Single metric (CTR)**: 매 long-term harm.
- **Position bias 무시**: 매 model 의 distort.
- **No A/B**: 매 offline metric trust.
- **No diversity**: 매 monoculture.

## 🧪 검증 / 중복
- Verified (Netflix Prize, Koren ALS paper, SASRec / BERT4Rec).
- 신뢰도 A.
- Related: [[Cognitive Biases]] · [[Algorithmic Fairness]] · [[CLIP]] · [[Anthropomorphism]] (over-trust).

## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — type + 매 ALS / two-tower / SASRec / Faiss / MMR / IPS code |
