Загрузка урока...
Изучите контентную фильтрацию — подход, который рекомендует товары, похожие на те, что уже понравились пользователю. Разберём TF-IDF для текстовых описаний, one-hot encoding для категорий и создание пользовательских профилей. Реализация на scikit-learn.
Введение
Контентная фильтрация — это подход, который не требует данных о других пользователях. Она анализирует свойства самих товаров и предпочтения конкретного пользователя. Если пользователь купил джинсы синего цвета, система найдёт другие синие джинсы.
Как работает контентная фильтрация
Шаг 1. Создаём вектор каждого товара (из его признаков)
Шаг 2. Создаём профиль пользователя (сумма векторов товаров, которые ему понравились)
Шаг 3. Сравниваем профиль пользователя с векторами новых товаров
Шаг 4. Рекомендуем товары с максимальной близостьюТипы признаков товаров
Шаг 1. One-hot encoding для категорий
Превращаем категории в бинарные векторы.
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
# Данные о товарах
products = pd.DataFrame({
'product_id': [1, 2, 3, 4, 5],
'name': ['Джинсы синие', 'Джинсы чёрные', 'Футболка белая', 'Кеды белые', 'Куртка кожаная'],
'category': ['джинсы', 'джинсы', 'футболки', 'кеды', 'куртки'],
'color': ['синий', 'чёрный', 'белый', 'белый', 'чёрный'],
'price': [3990, 3990, 1990, 4990, 8990],
'rating': [4.5, 4.3, 4.7, 4.2, 4.8]
})
# One-hot encoding для категории и цвета
encoder = OneHotEncoder(sparse_output=False)
category_encoded = encoder.fit_transform(products[['category']])
color_encoded = encoder.fit_transform(products[['color']])
print("Категории (one-hot):")
print(category_encoded[:3])Шаг 2. Нормализация числовых признаков
from sklearn.preprocessing import MinMaxScaler
# Нормализуем цену
scaler = MinMaxScaler()
products['price_norm'] = scaler.fit_transform(products[['price']])
print("Нормализованные цены:")
print(products[['name', 'price', 'price_norm']])Шаг 3. Создание полного вектора товара
import numpy as np
# Функция для создания вектора товара
def create_product_vector(row):
vector = []
# One-hot категории
cat_idx = ['джинсы', 'футболки', 'кеды', 'куртки'].index(row['category'])
cat_vector = [0, 0, 0, 0]
cat_vector[cat_idx] = 1
vector.extend(cat_vector)
# One-hot цвета
color_idx = ['синий', 'чёрный', 'белый'].index(row['color'])
color_vector = [0, 0, 0]
color_vector[color_idx] = 1
vector.extend(color_vector)
# Нормализованная цена
vector.append(row['price_norm'])
return np.array(vector)
# Создаём векторы для всех товаров
product_vectors = {}
for idx, row in products.iterrows():
product_vectors[row['product_id']] = create_product_vector(row)
print("Вектор для товара 1 (джинсы синие):")
print(product_vectors[1])Шаг 4. Создание профиля пользователя
Профиль пользователя — это сумма векторов всех товаров, которые ему понравились.
# Данные о действиях пользователя
user_actions = pd.DataFrame([
{'user_id': 1, 'product_id': 1, 'action': 'purchase', 'weight': 3}, # покупка
{'user_id': 1, 'product_id': 2, 'action': 'view', 'weight': 1}, # просмотр
{'user_id': 1, 'product_id': 5, 'action': 'like', 'weight': 2}, # лайк
])
# Веса действий
action_weights = {
'purchase': 3,
'like': 2,
'view': 1,
'click': 0.5,
}
def create_user_profile(user_id, user_actions, product_vectors):
profile = np.zeros(len(product_vectors[1])) # размер как у вектора товара
for _, action in user_actions[user_actions['user_id'] == user_id].iterrows():
product_id = action['product_id']
weight = action_weights[action['action']]
profile += product_vectors[product_id] * weight
return profile
# Создаём профиль пользователя 1
user_profile = create_user_profile(1, user_actions, product_vectors)
print("Профиль пользователя 1:")
print(user_profile)Шаг 5. Рекомендация товаров
from sklearn.metrics.pairwise import cosine_similarity
def recommend_for_user(user_id, user_actions, product_vectors, products_df, top_n=5):
# Создаём профиль пользователя
profile = create_user_profile(user_id, user_actions, product_vectors)
# Товары, которые пользователь уже взаимодействовал
interacted_products = set(
user_actions[user_actions['user_id'] == user_id]['product_id']
)
# Вычисляем близость со всеми товарами
similarities = []
for pid, vector in product_vectors.items():
if pid in interacted_products:
continue # не рекомендуем уже виденные
sim = cosine_similarity([profile], [vector])[0][0]
similarities.append((pid, sim))
# Сортируем и возвращаем топ-N
similarities.sort(key=lambda x: x[1], reverse=True)
recommended_ids = [pid for pid, _ in similarities[:top_n]]
return products_df[products_df['product_id'].isin(recommended_ids)]
# Рекомендации для пользователя 1
recommendations = recommend_for_user(1, user_actions, product_vectors, products)
print("\nРекомендации для пользователя 1:")
print(recommendations[['product_id', 'name', 'category', 'price']])Продвинутый подход: TF-IDF для текстовых описаний
from sklearn.feature_extraction.text import TfidfVectorizer
# Текстовые описания товаров
descriptions = [
"удобные синие джинсы из хлопка классический крой",
"стильные чёрные джинсы скинни с эластаном",
"белая хлопковая футболка классический воротник",
"белые кеды на толстой подошве из натуральной кожи",
"кожаная куртка чёрная с подкладкой мужская"
]
# Создаём TF-IDF векторы
vectorizer = TfidfVectorizer(max_features=10)
tfidf_matrix = vectorizer.fit_transform(descriptions)
print("TF-IDF матрица (первые 5 товаров, 10 признаков):")
print(tfidf_matrix.toarray()[:2])
# Ключевые слова для каждого товара
feature_names = vectorizer.get_feature_names_out()
for i, desc in enumerate(descriptions):
print(f"\nТовар {i+1}:")
scores = tfidf_matrix[i].toarray()[0]
top_features = sorted(zip(feature_names, scores), key=lambda x: x[1], reverse=True)[:3]
print(f" Ключевые слова: {[f[0] for f in top_features]}")Преимущества и недостатки контентной фильтрации
Когда использовать контентную фильтрацию:
Новый магазин (мало пользователей)
Медиа-платформы (статьи, новости)
Товары с богатыми метаданными (одежда, электроника)
Бизнес с сезонными товарами
Практическое задание
Создайте контентную фильтрацию для книжного магазина. Признаки книг: жанр, год издания, количество страниц, рейтинг. Реализуйте:
One-hot encoding для жанров
Нормализацию для числовых признаков
Профиль пользователя на основе его покупок
Рекомендацию 5 книг
Резюме урока
Контентная фильтрация — это мощный подход для персонализации, который:
Не требует данных о других пользователях
Использует свойства товаров (категории, цена, описание)
Работает даже с новыми товарами
Легко интерпретируется
Реализация на scikit-learn занимает около 50 строк кода.
Контрольные вопросы
Чем контентная фильтрация отличается от коллаборативной?
Как создать профиль пользователя в контентной фильтрации?
Что такое one-hot encoding и зачем он нужен?
Какую проблему решает TF-IDF при работе с текстами?
В каком сценарии контентная фильтрация работает лучше других подходов?
В этом материале нет файлов для просмотра.