Загрузка урока...
Изучите самые простые и эффективные рекомендательные модели, не требующие сложного ML. Реализуем «похожие товары» на основе косинусной близости и «с этим также покупают» на основе анализа транзакций. Готовый код на Python и примеры для внедрения.
Введение
Прежде чем погружаться в сложные алгоритмы машинного обучения, давайте реализуем простые, но очень эффективные модели. Они работают быстро, понятны бизнесу и не требуют больших вычислительных ресурсов. Более того, для многих магазинов этих моделей достаточно.
Модель 1. «Похожие товары» (Item-to-Item)
Идея: Если два товара часто покупают вместе или у них похожие характеристики, они «похожи». Когда пользователь смотрит один товар — покажите ему похожие.
Где используется:
Блок «Похожие товары» на карточке товара
«Вам также может понравиться»
Математическая основа: косинусная близость
Представьте каждый товар как вектор в многомерном пространстве. Чем меньше угол между двумя векторами, тем более похожи товары.
Косинусная близость (cosine similarity):
cosine_similarity(A, B) = (A·B) / (||A|| × ||B||)Значение от -1 до 1:
1 — векторы одинаковые (товары идентичны)
0 — нет связи
-1 — противоположные (редко бывает)
Пример: признаки товаров
Реализация на Python (код):
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
import pandas as pd
# Пример данных: пользователи и их оценки товаров (1 - просмотр, 2 - покупка)
ratings = pd.DataFrame([
# Пользователь 1
{'user_id': 1, 'item_id': 'джинсы_синие', 'rating': 2},
{'user_id': 1, 'item_id': 'джинсы_черные', 'rating': 1},
{'user_id': 1, 'item_id': 'футболка', 'rating': 2},
# Пользователь 2
{'user_id': 2, 'item_id': 'джинсы_синие', 'rating': 1},
{'user_id': 2, 'item_id': 'джинсы_черные', 'rating': 2},
# Пользователь 3
{'user_id': 3, 'item_id': 'футболка', 'rating': 2},
{'user_id': 3, 'item_id': 'кеды', 'rating': 2},
])
# Создаём матрицу пользователь-товар (user-item matrix)
matrix = ratings.pivot_table(
index='user_id',
columns='item_id',
values='rating',
fill_value=0
)
print("Матрица пользователь-товар:")
print(matrix)
# Вычисляем косинусную близость между товарами (item-item similarity)
item_similarity = cosine_similarity(matrix.T)
item_similarity_df = pd.DataFrame(
item_similarity,
index=matrix.columns,
columns=matrix.columns
)
print("\nПохожесть товаров:")
print(item_similarity_df)
# Функция для получения похожих товаров
def get_similar_items(item_id, top_n=3):
if item_id not in item_similarity_df.columns:
return []
similarities = item_similarity_df[item_id].sort_values(ascending=False)
# Убираем сам товар (похожесть с самим собой = 1)
similarities = similarities[similarities.index != item_id]
return similarities.head(top_n).index.tolist()
# Пример
print("\nТовары, похожие на 'джинсы_синие':")
print(get_similar_items('джинсы_синие', top_n=3))Результат работы:
Товары, похожие на 'джинсы_синие':
['джинсы_черные', 'футболка']Модель 2. «С этим также покупают» (Market Basket Analysis)
Идея: Анализируем все покупки и ищем товары, которые часто появляются вместе в одном заказе.
Где используется:
Блок «С этим товаром покупают» в корзине
Cross-sell рекомендации
Метрики для оценки связей товаров:
Пример расчёта:
Всего транзакций: 1000
Купили хлеб: 300
Купили масло: 200
Купили хлеб + масло: 150
Support(хлеб, масло) = 150 / 1000 = 0.15 (15%)
Confidence(хлеб → масло) = 150 / 300 = 0.5 (50%)
Lift(хлеб → масло) = 0.5 / (200/1000) = 0.5 / 0.2 = 2.5
Интерпретация: покупка хлеба повышает вероятность покупки масла в 2.5 раза.Реализация на Python (Apriori алгоритм):
from itertools import combinations
from collections import Counter
# Данные: список корзин (каждая корзина — список товаров)
transactions = [
['хлеб', 'масло', 'молоко'],
['хлеб', 'масло'],
['хлеб', 'колбаса'],
['масло', 'молоко'],
['хлеб', 'масло', 'колбаса'],
['хлеб', 'молоко'],
['масло', 'колбаса'],
['хлеб', 'масло', 'молоко'],
['хлеб', 'масло'],
['колбаса', 'молоко'],
]
# Функция для поиска частых пар товаров
def find_frequent_pairs(transactions, min_support=0.2):
n_transactions = len(transactions)
pair_counts = Counter()
for basket in transactions:
# Все возможные пары в корзине
for pair in combinations(sorted(set(basket)), 2):
pair_counts[pair] += 1
# Фильтруем по минимальной поддержке
frequent_pairs = {
pair: count / n_transactions
for pair, count in pair_counts.items()
if count / n_transactions >= min_support
}
return frequent_pairs
# Функция для расчёта confidence
def get_recommendations(item, frequent_pairs, transactions, min_confidence=0.3):
recommendations = {}
for (a, b), support in frequent_pairs.items():
if a == item:
# Считаем confidence для a → b
a_count = sum(1 for t in transactions if item in t)
confidence = support * len(transactions) / a_count
if confidence >= min_confidence:
recommendations[b] = confidence
elif b == item:
# Считаем confidence для b → a
b_count = sum(1 for t in transactions if item in t)
confidence = support * len(transactions) / b_count
if confidence >= min_confidence:
recommendations[a] = confidence
# Сортируем по confidence
return sorted(recommendations.items(), key=lambda x: x[1], reverse=True)
# Запускаем
frequent_pairs = find_frequent_pairs(transactions, min_support=0.2)
print("Частые пары (поддержка > 0.2):")
for pair, support in frequent_pairs.items():
print(f" {pair}: {support:.2f}")
print("\nРекомендации для 'хлеб':")
recs = get_recommendations('хлеб', frequent_pairs, transactions, min_confidence=0.3)
for item, confidence in recs:
print(f" {item}: confidence = {confidence:.2f}")Результат:
Рекомендации для 'хлеб':
масло: confidence = 0.83
молоко: confidence = 0.50
колбаса: confidence = 0.33Внедрение в продакшен (простой API)
from flask import Flask, request, jsonify
app = Flask(__name__)
# Предзагруженные данные (пример)
similar_items = {
'джинсы_синие': ['джинсы_черные', 'футболка', 'ремень'],
'футболка': ['носки', 'кеды', 'джинсы_синие'],
'кеды': ['носки', 'футболка', 'шнурки'],
}
@app.route('/recommend', methods=['GET'])
def recommend():
item_id = request.args.get('item_id')
top_n = int(request.args.get('top_n', 5))
if item_id not in similar_items:
return jsonify({'error': 'Item not found'}), 404
recommendations = similar_items[item_id][:top_n]
return jsonify({
'item': item_id,
'recommendations': recommendations
})
if __name__ == '__main__':
app.run(port=5000)
# Пример запроса:
# GET http://localhost:5000/recommend?item_id=джинсы_синие&top_n=3
# Ответ: {"item": "джинсы_синие", "recommendations": ["джинсы_черные", "футболка", "ремень"]}Сравнение моделей
Когда какую использовать:
Резюме урока
Простые модели — это не «плохие» модели. Для многих бизнесов они дают 80% эффекта при 20% усилий:
«Похожие товары» — на основе косинусной близости. Нужны векторы товаров.
«С этим также покупают» — на основе анализа корзин (Apriori). Нужны транзакции.
Обе модели легко реализовать на Python и быстро внедрить в продакшен.
Контрольные вопросы
Что такое косинусная близость и как она используется в рекомендациях?
Чем Support отличается от Confidence?
Как интерпретировать Lift = 2.5?
Какой алгоритм используется для поиска частых пар товаров?
Какую модель вы выберете для нового магазина без истории?
В этом материале нет файлов для просмотра.