Сегодня в электронной коммерции успех бизнеса во-многом зависит от способности предугадывать потребности клиентов и предлагать им именно то, что они ищут. И, как показал опыт, правильно реализованные модели могут значительно повысить конверсию, увеличить средний чек и улучшить лояльность клиентов.
В этой статье я поделюсь своим опытом и знаниями о том, как создать ML-модель прогноза действий пользователей интернет-магазина и разработать рекомендательную систему. Мы рассмотрим весь процесс: от сбора и анализа данных до внедрения готового решения, обсудим различные алгоритмы и подходы, а также разберем практические примеры с использованием популярных библиотек машинного обучения.
Понимание поведения пользователей интернет-магазина
Прежде чем приступить к созданию ML-модели, необходимо глубоко понять, как пользователи взаимодействуют с интернет-магазином. Это ключевой этап, который определит успех всего проекта.
Анализ пользовательских сессий
Каждый визит пользователя на сайт – это уникальная история, которую мы должны научиться читать.
Анализируя пользовательские сессии, мы можем выявить паттерны поведения, которые впоследствии лягут в основу нашей модели. Важно отслеживать такие параметры, как:
- Длительность сессии;
- Количество просмотренных страниц;
- Путь пользователя по сайту;
- Взаимодействие с элементами интерфейса;
- Время, проведенное на каждой странице.
Для анализа сессий я обычно использую комбинацию инструментов веб-аналитики и собственных скриптов на Python. Например, вот фрагмент кода, который помогает агрегировать данные о сессиях из логов веб-сервера:
import pandas as pd
from collections import defaultdict
def analyze_sessions(log_data):
sessions = defaultdict(lambda: {'pages': [], 'duration': 0, 'interactions': 0})
for entry in log_data:
user_id = entry['user_id']
timestamp = pd.to_datetime(entry['timestamp'])
page = entry['page']
interaction = entry['interaction']
if not sessions[user_id]['pages']:
sessions[user_id]['start_time'] = timestamp
sessions[user_id]['pages'].append(page)
sessions[user_id]['interactions'] += interaction
sessions[user_id]['end_time'] = timestamp
for user_id, session in sessions.items():
session['duration'] = (session['end_time'] - session['start_time']).total_seconds()
session['page_count'] = len(session['pages'])
return pd.DataFrame.from_dict(sessions, orient='index')
# Пример использования
log_data = [
{'user_id': '001', 'timestamp': '2024-09-27 10:00:00', 'page': 'home', 'interaction': 2},
{'user_id': '001', 'timestamp': '2024-09-27 10:01:30', 'page': 'product', 'interaction': 5},
# ... другие записи лога
]
session_df = analyze_sessions(log_data)
print(session_df.head())
Этот код позволяет получить структурированные данные о сессиях пользователей, которые мы можем использовать для дальнейшего анализа и построения моделей.
Выявление ключевых метрик и KPI
После анализа сессий важно определить ключевые метрики и KPI, которые будут индикаторами успешности нашей модели. В контексте интернет-магазина такими метриками могут быть:
- Конверсия (отношение числа покупок к числу посещений);
- Средний чек;
- Частота повторных покупок;
- Время до совершения первой покупки;
- Коэффициент отказов (bounce rate);
- Глубина просмотра (среднее количество просмотренных страниц за сессию).
Эти метрики не только помогут нам оценить эффективность нашей будущей модели, но и лягут в основу признаков (features), которые мы будем использовать для обучения.
Сегментация пользователей
Одним из важных шагов в понимании поведения пользователей является их сегментация. Разделение клиентской базы на группы со схожими характеристиками позволяет нам создавать более точные и персонализированные прогнозы и рекомендации.
Для сегментации я часто использую алгоритм k-means или его более продвинутые версии, такие как Mini-Batch K-Means для больших объемов данных. Вот пример реализации сегментации с использованием библиотеки scikit-learn:
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import numpy as np
def segment_users(user_data, n_clusters=5):
# Выбираем признаки для сегментации
features = ['avg_session_duration', 'avg_order_value', 'purchase_frequency', 'total_spent']
# Нормализуем данные
scaler = StandardScaler()
scaled_features = scaler.fit_transform(user_data[features])
# Применяем K-Means
kmeans = KMeans(n_clusters=n_clusters, random_state=42)
user_data['Segment'] = kmeans.fit_predict(scaled_features)
# Анализируем центроиды для интерпретации сегментов
centroids = scaler.inverse_transform(kmeans.cluster_centers_)
segment_profiles = pd.DataFrame(centroids, columns=features)
return user_data, segment_profiles
# Пример использования
user_data = pd.DataFrame({
'user_id': range(1000),
'avg_session_duration': np.random.randint(60, 3600, 1000),
'avg_order_value': np.random.randint(10, 500, 1000),
'purchase_frequency': np.random.randint(1, 20, 1000),
'total_spent': np.random.randint(100, 10000, 1000)
})
segmented_users, segment_profiles = segment_users(user_data)
print(segment_profiles)
Этот код позволяет нам разделить пользователей на сегменты и получить профили каждого сегмента, что в дальнейшем может быть использовано для создания более точных моделей прогнозирования и рекомендаций.
Сбор и подготовка данных для ML-модели
После того как мы разобрались с основами поведения пользователей, следующим критическим шагом является сбор и подготовка данных для нашей ML-модели. Это фундамент, на котором будет строиться вся наша система прогнозирования и рекомендаций.
Источники данных
Для создания эффективной модели нам понадобится информация из различных источников. Основными из них являются:
- Логи веб-сервера: содержат информацию о каждом запросе к сайту, включая IP-адрес, время запроса, запрошенный URL и user-agent;
- База данных интернет-магазина: хранит информацию о продуктах, заказах, пользователях и их профилях;
- Данные систем аналитики (например, Google Analytics или Яндекс.Метрика): предоставляют агрегированную информацию о поведении пользователей, источниках трафика и конверсиях;
- CRM-система: содержит данные о взаимодействии с клиентами, истории коммуникаций и дополнительную информацию о пользователях;
- Clickstream данные: последовательность действий пользователя на сайте, включая клики, прокрутку страницы и другие микровзаимодействия.
Объединение данных из всех этих источников позволяет создать полную картину поведения пользователя и его взаимодействия с интернет-магазином.
Предобработка и очистка данных
Собранные данные редко бывают идеальными для непосредственного использования в ML-моделях. Поэтому важным этапом является их предобработка и очистка. Вот несколько ключевых шагов, которые я обычно выполняю:
- Удаление дубликатов и аномалий;
- Обработка пропущенных значений;
- Нормализация и стандартизация числовых данных;
- Кодирование категориальных переменных;
- Обработка временных рядов и создание временных признаков.
Вот пример кода на Python, демонстрирующий некоторые из этих шагов:
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
def preprocess_data(df):
# Удаление дубликатов
df = df.drop_duplicates()
# Обработка пропущенных значений
numeric_features = df.select_dtypes(include=[np.number]).columns
categorical_features = df.select_dtypes(include=['object']).columns
numeric_imputer = SimpleImputer(strategy='mean')
categorical_imputer = SimpleImputer(strategy='most_frequent')
df[numeric_features] = numeric_imputer.fit_transform(df[numeric_features])
df[categorical_features] = categorical_imputer.fit_transform(df[categorical_features])
# Нормализация числовых данных
scaler = StandardScaler()
df[numeric_features] = scaler.fit_transform(df[numeric_features])
# Кодирование категориальных переменных
encoder = OneHotEncoder(sparse=False, handle_unknown='ignore')
encoded_features = encoder.fit_transform(df[categorical_features])
encoded_feature_names = encoder.get_feature_names(categorical_features)
encoded_df = pd.DataFrame(encoded_features, columns=encoded_feature_names, index=df.index)
# Объединение обработанных данных
processed_df = pd.concat([df.drop(columns=categorical_features), encoded_df], axis=1)
return processed_df
# Пример использования
raw_data = pd.DataFrame({
'age': [25, 30, np.nan, 40],
'income': [50000, 60000, 75000, np.nan],
'category': ['A', 'B', 'A', 'C']
})
processed_data = preprocess_data(raw_data)
print(processed_data)
Этот код демонстрирует базовые шаги предобработки данных, включая обработку пропущенных значений, нормализацию числовых данных и кодирование категориальных переменных.
Создание признаков (feature engineering)
Создание признаков – это искусство и наука извлечения полезной информации из сырых данных. Для прогнозирования действий пользователей интернет-магазина я обычно создаю следующие типы признаков:
Временные признаки:
- День недели и время суток последнего посещения;
- Количество дней с момента последней покупки;
- Сезонность покупательской активности.
Поведенческие признаки:
- Среднее время, проведенное на сайте;
- Частота посещений определенных категорий товаров;
- Количество добавлений в корзину без покупки.
Транзакционные признаки:
- Средняя сумма заказа;
- Общая сумма покупок за определенный период;
- Количество уникальных товаров в заказах.
Признаки взаимодействия с контентом:
- Частота просмотра отзывов;
- Активность в оставлении комментариев;
- Участие в акциях и использование промокодов.
Социально-демографические признаки:
- Возраст и пол;
- Географическое расположение;
- Тип устройства, с которого чаще всего заходит пользователь.
Вот пример кода, демонстрирующий создание некоторых из этих признаков:
import pandas as pd
from datetime import datetime
def create_features(df):
# Предполагаем, что у нас есть колонка 'timestamp' с датой и временем действия
df['timestamp'] = pd.to_datetime(df['timestamp'])
# Временные признаки
df['day_of_week'] = df['timestamp'].dt.dayofweek
df['hour_of_day'] = df['timestamp'].dt.hour
df['is_weekend'] = df['day_of_week'].isin([5, 6]).astype(int)
# Признаки, основанные на истории покупок
df['days_since_last_purchase'] = (datetime.now() - df.groupby('user_id')['timestamp'].transform('max')).dt.days
# Поведенческие признаки
df['session_duration'] = df.groupby('session_id')['timestamp'].transform(lambda x: (x.max() - x.min()).total_seconds())
df['pages_viewed'] = df.groupby('session_id')['page_id'].transform('count')
# Транзакционные признаки
df['avg_order_value'] = df.groupby('user_id')['order_value'].transform('mean')
df['total_purchases'] = df.groupby('user_id')['order_id'].transform('count')
# Признаки взаимодействия с контентом
df['review_views'] = df['page_type'].eq('review').groupby(df['user_id']).transform('sum')
df['promo_usage'] = df['used_promo'].groupby(df['user_id']).transform('sum')
# Признаки категорий товаров
category_views = pd.get_dummies(df['product_category'], prefix='view')
df = pd.concat([df, category_views.groupby(df['user_id']).transform('sum')], axis=1)
return df
# Пример использования
sample_data = pd.DataFrame({
'user_id': [1, 1, 2, 2, 3],
'session_id': ['a', 'a', 'b', 'b', 'c'],
'timestamp': ['2024-09-27 10:00:00', '2024-09-27 10:15:00',
'2024-09-27 11:00:00', '2024-09-27 11:30:00',
'2024-09-27 12:00:00'],
'page_id': [1, 2, 3, 4, 5],
'page_type': ['product', 'review', 'product', 'cart', 'checkout'],
'product_category': ['electronics', 'electronics', 'clothing', 'clothing', 'books'],
'order_id': [None, None, None, 1, 2],
'order_value': [None, None, None, 100, 50],
'used_promo': [0, 0, 1, 1, 0]
})
enriched_data = create_features(sample_data)
print(enriched_data.head())
Этот код демонстрирует создание различных типов признаков, которые могут быть полезны для прогнозирования поведения пользователей интернет-магазина. Обратите внимание, что это упрощенный пример. В реальном проекте набор признаков может быть значительно шире и зависит от специфики конкретного бизнеса и доступных данных.
Выбор и обучение ML-модели для прогнозирования действий пользователей
После того, как мы подготовили данные и создали информативные признаки, следующим шагом является выбор и обучение ML-модели для прогнозирования действий пользователей. Это ключевой этап, от которого во многом зависит успех всего проекта.
Постановка задачи машинного обучения
Прежде чем выбирать конкретный алгоритм, важно четко сформулировать задачу. В контексте прогнозирования действий пользователей интернет-магазина мы можем столкнуться с несколькими типами задач:
- Классификация: предсказание вероятности совершения определенного действия (например, покупки) в ближайшее время;
- Регрессия: прогнозирование числовых показателей, таких как сумма следующей покупки или время до следующего визита;
- Ранжирование: определение наиболее вероятных товаров для покупки или рекомендации.
В рамках этой статьи мы сосредоточимся на задаче классификации – прогнозировании вероятности совершения покупки в течение следующей недели.
Классификация: Выбор алгоритма машинного обучения
Для решения задачи классификации существует множество алгоритмов. Вот некоторые из наиболее популярных и эффективных:
- Логистическая регрессия: простая и интерпретируемая модель, хорошо работает на линейно разделимых данных;
- Случайный лес (Random Forest): ансамблевый метод, устойчивый к переобучению и способный захватывать нелинейные зависимости;
- Градиентный бустинг (например, XGBoost, LightGBM): обычно показывает наилучшие результаты на табличных данных;
- Нейронные сети: мощный инструмент, особенно эффективный при наличии большого количества данных и сложных зависимостей.
Для нашего примера мы будем использовать градиентный бустинг, а именно XGBoost, так как он часто показывает отличные результаты на практике и хорошо работает с разнородными данными.
Подготовка данных для обучения
Перед обучением модели необходимо разделить наши данные на обучающую и тестовую выборки. Это позволит нам оценить качество модели на данных, которые она не видела в процессе обучения.
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
import xgboost as xgb
from sklearn.metrics import roc_auc_score, accuracy_score
# Предполагаем, что у нас есть датафрейм 'df' с подготовленными признаками
# и целевой переменной 'made_purchase' (1 - совершил покупку, 0 - не совершил)
# Разделяем признаки и целевую переменную
X = df.drop('made_purchase', axis=1)
y = df['made_purchase']
# Кодируем категориальные переменные
for column in X.select_dtypes(include=['object']).columns:
le = LabelEncoder()
X[column] = le.fit_transform(X[column])
# Разделяем данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Создаем матрицы DMatrix для XGBoost
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)
Обучение модели и оценка ее качества
Теперь мы готовы обучить нашу модель и оценить ее качество. Важно выбрать правильные метрики оценки, которые соответствуют нашей бизнес-задаче. Для задачи классификации часто используются такие метрики, как точность (accuracy), полнота (recall), точность (precision) и AUC-ROC.
# Задаем параметры модели
params = {
'max_depth': 6,
'eta': 0.3,
'objective': 'binary:logistic',
'eval_metric': 'auc'
}
# Обучаем модель
num_round = 100
bst = xgb.train(params, dtrain, num_round)
# Делаем прогнозы на тестовой выборке
y_pred = bst.predict(dtest)
y_pred_binary = [1 if p > 0.5 else 0 for p in y_pred]
# Оцениваем качество модели
auc = roc_auc_score(y_test, y_pred)
accuracy = accuracy_score(y_test, y_pred_binary)
print(f"AUC-ROC: {auc:.4f}")
print(f"Accuracy: {accuracy:.4f}")
# Выводим важность признаков
importance = bst.get_score(importance_type='gain')
importance = sorted(importance.items(), key=lambda x: x[1], reverse=True)
print("\nTop 10 important features:")
for feature, score in importance[:10]:
print(f"{feature}: {score}")
Этот код обучает модель XGBoost на наших данных, делает прогнозы на тестовой выборке и оценивает качество модели по метрикам AUC-ROC и accuracy. Также мы выводим список наиболее важных признаков, что может быть полезно для понимания факторов, влияющих на поведение пользователей.
Тонкая настройка модели
Для улучшения производительности модели мы можем провести тонкую настройку гиперпараметров. Это можно сделать с помощью методов поиска по сетке (grid search) или случайного поиска (random search). Вот пример использования случайного поиска для оптимизации параметров XGBoost:
from sklearn.model_selection import RandomizedSearchCV
# Определяем пространство поиска параметров
param_dist = {
'max_depth': range(3, 10),
'min_child_weight': range(1, 6),
'subsample': [i/10.0 for i in range(6, 10)],
'colsample_bytree': [i/10.0 for i in range(6, 10)],
'eta': [0.01, 0.1, 0.3]
}
# Создаем объект XGBClassifier
xgb_model = xgb.XGBClassifier(objective='binary:logistic', eval_metric='auc')
# Инициализируем случайный поиск
random_search = RandomizedSearchCV(xgb_model, param_distributions=param_dist, n_iter=100, cv=3, scoring='roc_auc', n_jobs=-1, random_state=42)
# Проводим поиск
random_search.fit(X_train, y_train)
# Выводим лучшие параметры
print("Best parameters:", random_search.best_params_)
print("Best AUC-ROC score:", random_search.best_score_)
# Оцениваем модель на тестовой выборке
best_model = random_search.best_estimator_
y_pred = best_model.predict_proba(X_test)[:, 1]
auc = roc_auc_score(y_test, y_pred)
print(f"AUC-ROC on test set: {auc:.4f}")
Этот процесс может занять некоторое время, но он позволяет найти оптимальные параметры для нашей модели, что часто приводит к значительному улучшению ее производительности.
Разработка рекомендательной системы
Теперь, когда у нас есть модель для прогнозирования действий пользователей, мы можем перейти к разработке рекомендательной системы. Рексистемы играют ключевую роль в увеличении продаж и улучшении пользовательского опыта в интернет-магазинах.
Типы рекомендательных систем
Существует несколько основных подходов к построению рекомендательных систем:
- Коллаборативная фильтрация: основана на предположении, что пользователи, которые согласились на что-то в прошлом, согласятся на это и в будущем;
- User-based: рекомендует товары, которые понравились похожим пользователям;
- Item-based: рекомендует товары, похожие на те, которые пользователь уже оценил положительно;
- Контентная фильтрация: основана на характеристиках товаров и профиле предпочтений пользователя;
- Гибридные подходы: комбинируют различные методы для достижения лучших результатов.
Для нашего интернет-магазина мы разработаем гибридную систему, сочетающую коллаборативную и контентную фильтрацию.
Реализация коллаборативной фильтрации
Начнем с реализации коллаборативной фильтрации на основе товаров (item-based). Для этого мы будем использовать метрику косинусного сходства для определения похожести товаров.
import pandas as pd
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
def item_based_recommendations(user_item_matrix, item_id, n_recommendations=5):
# Вычисляем косинусное сходство между товарами
item_similarity = cosine_similarity(user_item_matrix.T)
# Получаем индекс заданного товара
item_index = user_item_matrix.columns.get_loc(item_id)
# Сортируем товары по сходству с заданным товаром
similar_items = sorted(list(enumerate(item_similarity[item_index])), key=lambda x: x[1], reverse=True)
# Исключаем сам товар из рекомендаций и выбираем top-n
recommendations = [user_item_matrix.columns[i] for i, _ in similar_items[1:n_recommendations+1]]
return recommendations
# Пример использования
# Предполагаем, что у нас есть матрица покупок пользователей
user_item_matrix = pd.DataFrame({
'item1': [1, 0, 1, 1, 0],
'item2': [0, 1, 1, 0, 1],
'item3': [1, 1, 0, 1, 0],
'item4': [0, 0, 1, 0, 1],
'item5': [1, 0, 0, 1, 1]
}, index=['user1', 'user2', 'user3', 'user4', 'user5'])
recommended_items = item_based_recommendations(user_item_matrix, 'item1')
print("Рекомендованные товары:", recommended_items)
Этот код реализует простую систему рекомендаций на основе товаров, используя косинусное сходство для определения похожих товаров.
Реализация контентной фильтрации
Теперь добавим контентную фильтрацию, основанную на характеристиках товаров. Для этого мы будем использовать TF-IDF для векторизации описаний товаров и косинусное сходство для определения похожести.
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
def content_based_recommendations(item_descriptions, item_id, n_recommendations=5):
# Создаем TF-IDF векторизатор
tfidf = TfidfVectorizer(stop_words='english')
# Преобразуем описания товаров в TF-IDF матрицу
tfidf_matrix = tfidf.fit_transform(item_descriptions.values())
# Вычисляем косинусное сходство между товарами
cosine_sim = cosine_similarity(tfidf_matrix, tfidf_matrix)
# Получаем индекс заданного товара
idx = list(item_descriptions.keys()).index(item_id)
# Получаем оценки сходства для заданного товара со всеми товарами
sim_scores = list(enumerate(cosine_sim[idx]))
# Сортируем товары по убыванию сходства
sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)
# Получаем индексы n наиболее похожих товаров (исключая сам товар)
sim_scores = sim_scores[1:n_recommendations+1]
item_indices = [i[0] for i in sim_scores]
# Возвращаем ID рекомендованных товаров
return [list(item_descriptions.keys())[i] for i in item_indices]
# Пример использования
item_descriptions = {
'item1': 'Blue cotton t-shirt',
'item2': 'Red wool sweater',
'item3': 'Black leather jacket',
'item4': 'Green cotton polo shirt',
'item5': 'Brown leather boots'
}
recommended_items = content_based_recommendations(item_descriptions, 'item1')
print("Рекомендованные товары:", recommended_items)
Этот код реализует систему рекомендаций на основе контента, используя описания товаров для определения их схожести.
Создание гибридной рекомендательной системы
Теперь мы можем объединить коллаборативную и контентную фильтрацию в гибридную систему рекомендаций. Мы будем использовать взвешенное среднее результатов обоих методов.
def hybrid_recommendations(user_item_matrix, item_descriptions, user_id, n_recommendations=5, collaborative_weight=0.7):
# Получаем товары, которые пользователь еще не купил
user_items = user_item_matrix.loc[user_id]
candidate_items = user_items[user_items == 0].index
# Инициализируем словарь для хранения оценок товаров
item_scores = {item: 0 for item in candidate_items}
# Вычисляем оценки на основе коллаборативной фильтрации
for item in candidate_items:
similar_items = item_based_recommendations(user_item_matrix, item, n_recommendations=len(user_item_matrix.columns))
item_scores[item] += collaborative_weight * sum([1 / (i + 1) for i, sim_item in enumerate(similar_items) if user_items[sim_item] == 1])
# Вычисляем оценки на основе контентной фильтрации
content_weight = 1 - collaborative_weight
for item in candidate_items:
similar_items = content_based_recommendations(item_descriptions, item, n_recommendations=len(item_descriptions))
item_scores[item] += content_weight * sum([1 / (i + 1) for i, sim_item in enumerate(similar_items) if user_items[sim_item] == 1])
# Сортируем товары по убыванию оценки
sorted_items = sorted(item_scores.items(), key=lambda x: x[1], reverse=True)
# Возвращаем top-n рекомендаций
return [item for item, score in sorted_items[:n_recommendations]]
# Пример использования
user_item_matrix = pd.DataFrame({
'item1': [1, 0, 1, 1, 0],
'item2': [0, 1, 1, 0, 1],
'item3': [1, 1, 0, 1, 0],
'item4': [0, 0, 1, 0, 1],
'item5': [1, 0, 0, 1, 1]
}, index=['user1', 'user2', 'user3', 'user4', 'user5'])
item_descriptions = {
'item1': 'Blue cotton t-shirt',
'item2': 'Red wool sweater',
'item3': 'Black leather jacket',
'item4': 'Green cotton polo shirt',
'item5': 'Brown leather boots'
}
recommended_items = hybrid_recommendations(user_item_matrix, item_descriptions, 'user2')
print("Рекомендованные товары:", recommended_items)
Эта гибридная система объединяет преимущества обоих подходов: коллаборативная фильтрация учитывает поведение пользователей, а контентная фильтрация позволяет рекомендовать новые или малопопулярные товары на основе их характеристик.
Оценка качества рекомендательной системы
Оценка качества рекомендательной системы – важный этап, который позволяет понять, насколько хорошо система выполняет свою задачу. Существует несколько метрик, которые обычно используются для этой цели:
- Точность (Precision@k): доля релевантных товаров среди топ-k рекомендаций;
- Полнота (Recall@k): доля релевантных товаров, которые были рекомендованы в топ-k, от общего числа релевантных товаров;
- Mean Average Precision (MAP): средняя точность для всех пользователей;
- Normalized Discounted Cumulative Gain (NDCG): метрика, учитывающая порядок рекомендаций.
Вот пример реализации функции для вычисления Precision@k и Recall@k:
def evaluate_recommendations(true_items, recommended_items, k):
true_set = set(true_items)
recommended_set = set(recommended_items[:k])
n_relevant = len(true_set.intersection(recommended_set))
precision = n_relevant / k if k > 0 else 0
recall = n_relevant / len(true_set) if len(true_set) > 0 else 0
return precision, recall
# Пример использования
true_items = ['item1', 'item3', 'item5']
recommended_items = ['item1', 'item2', 'item3', 'item4', 'item5']
precision, recall = evaluate_recommendations(true_items, recommended_items, k=3)
print(f"Precision@3: {precision:.2f}")
print(f"Recall@3: {recall:.2f}")
При оценке рекомендательной системы важно использовать кросс-валидацию и тестировать на данных, которые не использовались при обучении модели.
Внедрение ML-модели и рекомендательной системы в интернет-магазин
После того как мы разработали и оценили нашу ML-модель прогнозирования действий пользователей и рекомендательную систему, следующим важным шагом является их внедрение в инфраструктуру интернет-магазина.
Архитектура системы
Для эффективного функционирования нашей системы предлагается следующая архитектура:
- База данных: хранит информацию о пользователях, товарах, транзакциях и взаимодействиях;
- Сервис предобработки данных: подготавливает данные для ML-модели и рекомендательной системы;
- ML-сервис: обрабатывает запросы на прогнозирование действий пользователей;
- Рекомендательный сервис: генерирует персонализированные рекомендации;
- API-шлюз: обрабатывает запросы от фронтенда и распределяет их между сервисами;
- Фронтенд: отображает прогнозы и рекомендации пользователям.
Как видите, задача – не тривиальная, и требует навыков не только data science, но и веб-разработки. Вот пример простой реализации API с использованием Flask:
from flask import Flask, request, jsonify
import joblib
app = Flask(__name__)
# Загружаем предобученную модель
model = joblib.load('xgboost_model.pkl')
@app.route('/predict', methods=['POST'])
def predict():
data = request.json
features = [data['feature1'], data['feature2'], ...] # Предполагаем, что данные приходят в нужном формате
prediction = model.predict_proba([features])[0][1] # Вероятность положительного класса
return jsonify({'probability': prediction})
@app.route('/recommend', methods=['POST'])
def recommend():
data = request.json
user_id = data['user_id']
recommendations = hybrid_recommendations(user_item_matrix, item_descriptions, user_id)
return jsonify({'recommendations': recommendations})
if __name__ == '__main__':
app.run(debug=True)
Этот код создает два эндпоинта: один для прогнозирования действий пользователя, другой для получения рекомендаций.
Интеграция с фронтендом
Для интеграции наших сервисов с фронтендом можно использовать AJAX-запросы. Вот пример на JavaScript с использованием fetch API:
// Функция для получения прогноза
async function getPrediction(userData) {
const response = await fetch('/predict', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(userData)
});
return await response.json();
}
// Функция для получения рекомендаций
async function getRecommendations(userId) {
const response = await fetch('/recommend', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ user_id: userId })
});
return await response.json();
}
// Пример использования
document.getElementById('predictButton').addEventListener('click', async () => {
const userData = {
feature1: 10,
feature2: 'category_A',
// ... другие признаки
};
const prediction = await getPrediction(userData);
console.log('Вероятность покупки:', prediction.probability);
});
document.getElementById('recommendButton').addEventListener('click', async () => {
const userId = 'user123';
const recommendations = await getRecommendations(userId);
console.log('Рекомендованные товары:', recommendations.recommendations);
});
Обновление модели и рекомендаций
Важно регулярно обновлять нашу ML-модель и рекомендательную систему, чтобы они оставались актуальными. Для этого можно использовать следующий подход:
- Настроить систему логирования для сбора данных о взаимодействии пользователей с рекомендациями;
- Периодически (например, раз в неделю) переобучать модель на новых данных;
- Использовать A/B-тестирование для сравнения эффективности новой и старой версий модели;
- Автоматически развертывать новую версию модели, если она показывает лучшие результаты.
Вот пример простого скрипта для переобучения модели:
import schedule
import time
import joblib
from sklearn.model_selection import train_test_split
from xgboost import XGBClassifier
def retrain_model():
# Загружаем новые данные
new_data = load_new_data() # Предполагаем, что у нас есть функция для загрузки новых данных
# Подготавливаем данные
X = new_data.drop('target', axis=1)
y = new_data['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Обучаем новую модель
model = XGBClassifier()
model.fit(X_train, y_train)
# Оцениваем производительность
accuracy = model.score(X_test, y_test)
print(f"New model accuracy: {accuracy}")
# Если новая модель лучше, сохраняем ее
if accuracy > current_model_accuracy:
joblib.dump(model, 'xgboost_model.pkl')
print("New model saved")
else:
print("Keeping current model")
# Запланируем переобучение раз в неделю
schedule.every().monday.at("02:00").do(retrain_model)
while True:
schedule.run_pending()
time.sleep(1)
Этот скрипт автоматически переобучает модель раз в неделю, используя новые данные, и сохраняет новую модель, если она показывает лучшие результаты.
Выводы
В этой статье мы рассмотрели процесс создания ML-модели для прогноза действий пользователей интернет-магазина и разработки рекомендательной системы. Мы прошли через все этапы: от сбора и подготовки данных до внедрения готового решения в инфраструктуру интернет-магазина.
Основные выводы:
- Прогнозирование действий пользователей и персонализированные рекомендации могут значительно улучшить пользовательский опыт и увеличить продажи в интернет-магазине;
- Важно тщательно подходить к сбору и подготовке данных, так как качество данных напрямую влияет на эффективность модели;
- Гибридные подходы, сочетающие различные методы рекомендаций, часто показывают лучшие результаты, чем отдельные методы;
- Регулярное обновление модели и рекомендательной системы необходимо для поддержания их актуальности и эффективности;
- Интеграция ML-модели и рекомендательной системы в существующую инфраструктуру интернет-магазина требует тщательного планирования и может потребовать значительных изменений в архитектуре системы;
- Оценка качества модели и рекомендаций должна проводиться регулярно, с использованием релевантных метрик и A/B-тестирования;
- Персонализация рекомендаций может значительно повысить конверсию и удовлетворенность пользователей, но важно соблюдать баланс между персонализацией и разнообразием рекомендаций.
В целом, применение машинного обучения и рекомендательных систем в электронной коммерции открывает огромные возможности для бизнеса. Однако важно помнить, что это не магическое решение всех проблем. Успех во многом зависит от качества данных, правильного выбора алгоритмов и тщательной настройки системы под конкретные бизнес-задачи.