Что такое collaborative filtering и content-based filtering?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое collaborative filtering и content-based filtering?
Collaborative Filtering (CF) и Content-Based Filtering (CBF) - это две основные парадигмы для построения систем рекомендаций. Collaborative filtering использует информацию о поведении пользователей для поиска похожих пользователей или товаров, в то время как content-based filtering использует атрибуты самих товаров. Рассмотрим оба подхода и различия между ними.
1. Collaborative Filtering (Фильтрация на основе сотрудничества)
Основная идея: если пользователи давали одинаковые оценки товарам в прошлом, они, вероятно, согласятся и в будущем.
Виды Collaborative Filtering
A. User-Based CF
Находит похожих пользователей и рекомендует товары, которые нравились им.
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
import pandas as pd
# Матрица оценок: пользователи x товары
ratings = np.array([
[5, 0, 3, 0, 4], # User 0
[0, 4, 0, 5, 0], # User 1
[4, 0, 3, 0, 5], # User 2
[0, 3, 0, 4, 0], # User 3
[3, 0, 4, 0, 4] # User 4
])
def user_based_cf(ratings, user_id, n_neighbors=2, n_recommendations=2):
"""
User-based Collaborative Filtering
"""
# Вычисляем сходство между пользователями
user_similarity = cosine_similarity(ratings)
# Находим похожих пользователей (исключая самого себя)
similarities = user_similarity[user_id].copy()
similarities[user_id] = -1
similar_users = np.argsort(similarities)[::-1][:n_neighbors]
# Товары, которые пользователь еще не оценивал
user_rated = np.where(ratings[user_id] > 0)[0]
unrated_items = np.where(ratings[user_id] == 0)[0]
# Вычисляем рекомендуемые оценки
recommendations = {}
for item in unrated_items:
weighted_sum = 0
similarity_sum = 0
for similar_user in similar_users:
if ratings[similar_user, item] > 0:
weighted_sum += ratings[similar_user, item] * user_similarity[user_id, similar_user]
similarity_sum += user_similarity[user_id, similar_user]
if similarity_sum > 0:
recommendations[item] = weighted_sum / similarity_sum
# Возвращаем top-N рекомендаций
sorted_recs = sorted(recommendations.items(), key=lambda x: x[1], reverse=True)
return [item for item, score in sorted_recs[:n_recommendations]]
# Рекомендуем товары для User 0
recs = user_based_cf(ratings, user_id=0, n_neighbors=2, n_recommendations=2)
print(f"Рекомендации для User 0: {recs}")
B. Item-Based CF
Находит похожие товары на основе того, как пользователи их оценивали.
def item_based_cf(ratings, user_id, n_recommendations=2):
"""
Item-based Collaborative Filtering
"""
# Вычисляем сходство между товарами
item_similarity = cosine_similarity(ratings.T)
# Товары, которые пользователь оценил
rated_items = np.where(ratings[user_id] > 0)[0]
unrated_items = np.where(ratings[user_id] == 0)[0]
# Вычисляем рекомендуемые оценки
recommendations = {}
for item in unrated_items:
weighted_sum = 0
similarity_sum = 0
for rated_item in rated_items:
weighted_sum += ratings[user_id, rated_item] * item_similarity[item, rated_item]
similarity_sum += item_similarity[item, rated_item]
if similarity_sum > 0:
recommendations[item] = weighted_sum / similarity_sum
sorted_recs = sorted(recommendations.items(), key=lambda x: x[1], reverse=True)
return [item for item, score in sorted_recs[:n_recommendations]]
recs = item_based_cf(ratings, user_id=0, n_recommendations=2)
print(f"Item-based рекомендации для User 0: {recs}")
Matrix Factorization
Популярный метод для CF, разлагает матрицу оценок на произведение низкоранговых матриц.
from sklearn.decomposition import TruncatedSVD
# Заполняем нули для удобства
ratings_filled = ratings.copy()
ratings_filled[ratings_filled == 0] = ratings_filled.mean()
# SVD разложение
svd = TruncatedSVD(n_components=2)
U = svd.fit_transform(ratings_filled)
V = svd.components_.T
# Восстанавливаем матрицу оценок
recovered_ratings = U @ V.T
print("Восстановленные оценки User 0:")
print(recovered_ratings[0])
2. Content-Based Filtering (Фильтрация на основе содержания)
Основная идея: рекомендуем товары, похожие на те, которые пользователь уже оценил.
Пример: рекомендация фильмов
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
# Матрица товаров и их атрибутов
movies = pd.DataFrame({
'title': ['Action Hero', 'Love Story', 'Action Battle', 'Drama', 'Sci-Fi Action'],
'genre': ['action', 'romance', 'action', 'drama', 'sci-fi action'],
'director': ['Dir1', 'Dir2', 'Dir1', 'Dir3', 'Dir4'],
'rating': [7.5, 6.0, 7.8, 8.2, 7.9]
})
# Объединяем атрибуты
movies['features'] = movies['genre'] + ' ' + movies['director']
# TF-IDF векторизация
tfidf = TfidfVectorizer()
feature_vectors = tfidf.fit_transform(movies['features'])
# Вычисляем сходство между фильмами
movie_similarity = cosine_similarity(feature_vectors)
print("Матрица сходства фильмов:")
print(movie_similarity)
# Рекомендуем фильмы
def content_based_recommendation(movie_id, n_recommendations=2):
"""
Рекомендует фильмы похожие на понравившийся
"""
similar_movies = movie_similarity[movie_id]
# Исключаем сам фильм
similar_movies[movie_id] = -1
# Берем top-N похожих
recommended_indices = np.argsort(similar_movies)[::-1][:n_recommendations]
return recommended_indices
recs = content_based_recommendation(0, n_recommendations=2)
print(f"\nРекомендации похожие на '{movies.iloc[0].title}':")
for idx in recs:
print(f" - {movies.iloc[idx].title} (сходство: {movie_similarity[0, idx]:.3f})")
Сравнение CF и CBF
| Характеристика | Collaborative Filtering | Content-Based Filtering |
|---|---|---|
| Основано на | Поведение пользователей | Атрибуты товаров |
| Холодный старт | Проблема с новыми пользователями/товарами | Хорошо работает |
| Требует разметку | Только матрица оценок | Описание товаров |
| Неоценённые товары | Может рекомендовать | Не поможет |
| Разнообразие | Обнаруживает новые интересы | Ограничено известными атрибутами |
| Масштабируемость | Сложнее при большом числе пользователей | Масштабируется хорошо |
Гибридный подход
Объединяет CF и CBF для преодоления недостатков каждого:
def hybrid_recommendation(user_id, alpha=0.5):
"""
Гибридная система рекомендаций
alpha - вес для CF (1-alpha для CBF)
"""
# CF рекомендации
cf_scores = {}
for item in range(ratings.shape[1]):
if ratings[user_id, item] == 0:
weighted_sum = 0
similarity_sum = 0
for similar_user in range(ratings.shape[0]):
if similar_user != user_id and ratings[similar_user, item] > 0:
sim = cosine_similarity([ratings[user_id]], [ratings[similar_user]])[0][0]
weighted_sum += ratings[similar_user, item] * sim
similarity_sum += sim
if similarity_sum > 0:
cf_scores[item] = weighted_sum / similarity_sum
else:
cf_scores[item] = 0
# CBF рекомендации (пример упрощенный)
cb_scores = {item: np.random.random() for item in range(ratings.shape[1])}
# Объединяем
hybrid_scores = {}
for item in cf_scores:
hybrid_scores[item] = alpha * cf_scores[item] + (1 - alpha) * cb_scores[item]
# Исключаем уже оцененные товары
rated_items = np.where(ratings[user_id] > 0)[0]
for item in rated_items:
if item in hybrid_scores:
del hybrid_scores[item]
# Возвращаем top-N
sorted_recs = sorted(hybrid_scores.items(), key=lambda x: x[1], reverse=True)
return [item for item, score in sorted_recs[:2]]
recs = hybrid_recommendation(0, alpha=0.6)
print(f"Гибридные рекомендации: {recs}")
Практическое применение
Netflix, Amazon, YouTube используют:
- Комбинацию CF и CBF
- Deep Learning (Neural Collaborative Filtering)
- Context-aware рекомендации
- Мультиоб'ектное моделирование (пользователь, товар, контекст)
Выводы
- Collaborative Filtering мощна для открытия новых интересов, но требует большого набора данных о поведении
- Content-Based Filtering хороша для холодного старта и понимания атрибутов товаров
- Гибридные системы дают лучшие результаты на практике
- Выбор метода зависит от типа данных, масштаба и требований системы