Условие
Сравните collaborative filtering и content-based recsys. Когда каждый подходит, как гибридить?
Решение
Подход
| Collaborative (CF) | Content-based (CB) | |
|---|---|---|
| Сигнал | Юзер-юзер / айтем-айтем интеракции | Атрибуты айтемов |
| Cold start (новый user) | Плохо | OK, если есть атрибуты профиля |
| Cold start (новый item) | Плохо | OK |
| Серендипити | Высокая (новые жанры) | Низкая (similar to prev) |
| Качество для warm user | Высокое | Среднее |
| Filter bubble | Иногда | Часто |
Collaborative
Базовая идея: «Юзеры, которые лайкали A, также лайкали B». Реализации:
- User-User memory-based: cosine между users по их рейтингам.
- Item-Item memory-based: cosine между items по их получателям.
- Matrix Factorization (SVD, ALS): разложение rating matrix R ≈ U·V^T.
- Neural CF / Two-tower: embeddings user/item через NN.
# Item-item на implicit feedback (clicks, views) через cosine
import numpy as np
from scipy.sparse import csr_matrix
from sklearn.metrics.pairwise import cosine_similarity
R = csr_matrix((interactions, (user_ids, item_ids))) # n_users × n_items
sim = cosine_similarity(R.T) # item × item
def recommend(user_id, k=10):
user_items = R[user_id].toarray().flatten()
scores = sim @ user_items
scores[user_items > 0] = -1 # уже видел
return np.argsort(scores)[::-1][:k]Content-based
Recommendation by similarity in item features:
# Item features = tags + text embedding + categorical
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer(max_features=5000)
item_feat = tfidf.fit_transform(item_descriptions)
user_profile = item_feat[user_liked_items].mean(axis=0) # центроид
scores = cosine_similarity(np.asarray(user_profile), item_feat)[0]Hybrid
- Weighted:
score = α · CF_score + (1−α) · CB_score. - Switching: новый user → CB, warm → CF.
- Feature combining: item features + user-item interactions в одну модель (Wide&Deep, DeepFM).
- Cascade: CB сужает кандидаты до 1000, CF ранжирует.
Two-tower (modern hybrid)
User tower: user features + history embedding → user_emb.
Item tower: item features + meta → item_emb.
Score: dot(user_emb, item_emb).
Решает cold start (через side features) + CF signal (через history).
Подводные камни
- Popularity bias в CF: топовые items получают больше interactions → ещё чаще рекомендуются. Лечится IPS reweighting или explicit diversity term.
- Sparsity: 0.001% interactions заполненности — у user-user memory cosine почти 0 везде. MF справляется лучше.
- Implicit feedback: clicks ≠ likes. Negative samples нужны явные (random sampling из не-clicked).
- CB Echo chamber: рекомендует похожее → user только то и видит. Diversity injection нужна.
- Evaluation off-policy: A/B на production обязателен; offline metrics (NDCG, MAP) часто не коррелируют с online CTR.
Эталонный ответ
CF (collaborative): на интеракциях, лучшее качество для warm users, страдает от cold start. CB (content-based): на атрибутах items, работает для cold start, низкая серендипити. Hybrid: weighted blend, switching, two-tower с side features (решает cold start + CF signal). Offline NDCG плохо коррелирует с online CTR — A/B обязателен.