Все статьи

Как построить рекомендательную систему: от простых правил до машинного обучения

Как работают рекомендации на сайтах, какие алгоритмы используют и как создать рекомендательную систему на Python для реального продукта

27 минут чтения

Представим образовательную платформу, на которой опубликованы сотни курсов. Пользователь заканчивает вводный курс по Python, возвращается в каталог и видит предложение изучить FastAPI. Другому человеку, который интересуется анализом данных, система предлагает машинное обучение и визуализацию.

Оба пользователя открывают один и тот же сайт, но получают разные рекомендации. При этом никто из них не вводил поисковый запрос. Именно так работает рекомендательная система для сайта: она помогает человеку обнаруживать материалы, товары или функции, которые могут оказаться полезными с учётом его интересов, действий и контекста.

На крупных платформах рекомендации могут включать сложные модели машинного обучения, обработку миллионов событий и постоянные эксперименты. Но для первого IT-продукта такая инфраструктура не нужна. Полезную систему можно построить с помощью нескольких правил, SQL-запросов и небольшого Python-сервиса.

В этой статье разберём, как создать рекомендательную систему с нуля, какие данные ей нужны, как работают популярные алгоритмы и в какой момент действительно стоит переходить от простой логики к ML.

Чем рекомендации отличаются от поиска

Поиск начинается с явного запроса пользователя. Человек вводит «курс по FastAPI», а приложение пытается найти подходящие материалы. Рекомендательная система решает другую задачу: она предлагает варианты даже тогда, когда пользователь ещё не знает, что именно хочет найти. Например, после завершения курса по основам Python платформа может показать: Следующий шаг — создание Backend-приложений на FastAPI.

Это не результат текстового поиска. Система использует информацию о пройденном курсе и предполагаемом образовательном маршруте. Разница между поиском и рекомендациями заключается в источнике пользовательского намерения. Поиск опирается прежде всего на сформулированный запрос, а рекомендации — на контекст, характеристики объектов и доступные сигналы интереса.

В реальном продукте эти механизмы дополняют друг друга. Поиск помогает найти известное, а рекомендации — открыть новое.

Зачем рекомендательная система небольшому продукту

Рекомендации часто ассоциируются с крупными видеосервисами и маркетплейсами. Однако они полезны и для небольших приложений. В образовательном сервисе можно рекомендовать следующий курс. В интернет-магазине — сопутствующий товар. В приложении для чтения — статьи на похожие темы. В сервисе управления задачами — шаблоны, соответствующие деятельности пользователя.

Персонализация контента на сайте помогает сократить время выбора и сделать продукт удобнее. Но важно определить конкретную цель. Если пользователь получает десять случайных карточек, формально система рекомендаций существует, однако пользы от неё мало. Для образовательной платформы хорошей целью может стать увеличение доли пользователей, которые начинают следующий подходящий курс после завершения предыдущего.

Сначала определяем, что именно рекомендуем

Прежде чем выбирать алгоритм, нужно определить объект рекомендации. Для образовательной платформы это может быть курс, отдельный урок, практическое задание или образовательная траектория. Представим каталог: Если пользователь завершил курс №1, какие материалы стоит показать?

Возможны разные ответы. Если человек хочет стать Backend-разработчиком, логичным продолжением будут SQL и FastAPI. Если его интересует анализ данных, лучше предложить соответствующее направление. Поэтому проектирование рекомендательной системы начинается не с выбора библиотеки, а с понимания пользовательского пути.

Какие данные нужны для рекомендаций

Данные можно разделить на несколько групп. Первая — характеристики объектов. Для курса это название, описание, категория, уровень сложности, продолжительность и необходимые предварительные знания. Вторая — информация о взаимодействиях пользователя: просмотры, сохранения, начало обучения, завершение курса и оценки. Третья — контекст. Например, выбранная образовательная цель или текущий этап обучения.

Данные для рекомендательной системы не обязательно должны включать всю историю поведения человека. На старте достаточно нескольких полезных признаков. При этом данные следует собирать для понятных целей, с учётом применимых требований к приватности и с возможностью корректного управления пользовательскими предпочтениями.

Явные и неявные сигналы интереса

Не все действия пользователя одинаково информативны. Явный сигнал — когда человек сам сообщает о предпочтении. Например, ставит оценку курсу или выбирает направление «Backend-разработка». Неявный сигнал — когда интерес предполагается на основании поведения. Например, пользователь несколько раз открывает описание курса или сохраняет его в избранное.

Явная и неявная обратная связь в рекомендациях требуют разной интерпретации. Оценка «5 из 5» достаточно прямо выражает отношение к материалу. А просмотр страницы может означать как интерес, так и случайный переход. Поэтому нельзя автоматически считать любое взаимодействие положительной оценкой.

Почему лучше начать с правил

Представим, что образовательная платформа только запустилась. В каталоге 30 курсов, а зарегистрированных пользователей пока немного. Для сложной ML-модели недостаточно качественной истории взаимодействий. Но полезные рекомендации уже можно показывать. Например:

  • после вводного курса предлагать материалы следующего уровня;
  • рекомендовать курсы той же категории;
  • исключать уже завершённые курсы;
  • учитывать предварительные требования;
  • показывать популярные материалы новым пользователям.

Так работает рекомендательная система на основе правил. Её преимущество — предсказуемость. Разработчик понимает, почему конкретный курс появился в рекомендациях, и может легко изменить логику.

Как реализовать рекомендации через SQL

Предположим, пользователь интересуется Backend-разработкой. Простой запрос может выглядеть так: SELECT id, title, category, level FROM courses WHERE category = 'Backend' AND is_published = TRUE ORDER BY created_at DESC LIMIT 5; Это ещё не полноценная персонализация, но уже полезный механизм отбора. Если добавить таблицу завершённых курсов, можно исключать пройденные материалы: SELECT c.id, c.title FROM courses AS c

WHERE c.category = 'Backend' AND c.is_published = TRUE AND NOT EXISTS ( SELECT 1 FROM course_completions AS cc WHERE cc.course_id = c.id AND cc.user_id = :user_id ) ORDER BY c.created_at DESC LIMIT 5; Так создаются рекомендации на основе SQL-запросов. Для небольшого продукта подобная логика может оставаться основной довольно долго. Переход к машинному обучению не является обязательным этапом развития.

Как учитывать образовательную последовательность

Для учебной платформы недостаточно рекомендовать просто похожие курсы. Представим, что человек прошёл основы Python. Ему может быть интересна сложная программа по распределённым системам, но она пока не соответствует его уровню. Поэтому полезно учитывать предварительные знания. Например: Основы Python ↓ SQL и базы данных ↓ FastAPI ↓ Создание Full Stack приложения

Рекомендации образовательных курсов должны учитывать не только интересы, но и последовательность освоения навыков. Для этого можно хранить связи между курсами: какой материал рекомендуется пройти раньше другого. Такая модель часто даёт более понятный результат, чем попытка угадать интересы исключительно по истории просмотров.

Что такое content-based filtering

Следующий подход — рекомендации на основе характеристик объектов. Представим, что пользователь сохранил курс «Машинное обучение на Python». Система анализирует его категорию, описание, темы и уровень сложности, после чего находит похожие материалы. Это называется content-based filtering. Принцип можно представить так: Курс, который понравился ↓ Его характеристики ↓ Поиск похожих курсов ↓ Рекомендации

Преимущество подхода заключается в том, что для поиска похожих объектов не обязательно иметь большое количество пользователей. Достаточно качественных описаний самих материалов.

Как представить курс в виде признаков

Модель машинного обучения не работает напрямую с абстрактным понятием «интересный курс». Нужно преобразовать информацию об объекте в признаки. Например: course = { "title": "FastAPI для Backend", "category": "Backend", "level": "intermediate", "tags": [ "python", "api", "fastapi", "backend" ] } Такие данные можно преобразовать в числовое представление.

Признаки объектов для рекомендаций могут быть категориальными, числовыми или текстовыми. На практике выбор признаков зависит от того, какие свойства действительно помогают определить сходство материалов.

Как работает TF-IDF

Для текстовых описаний можно использовать TF-IDF — метод преобразования текста в числовые признаки. Он учитывает, насколько слово характерно для конкретного документа по сравнению с набором документов. Например, если слово «курс» встречается почти в каждом описании, оно мало помогает различать материалы. А сочетание терминов «FastAPI», «эндпоинты» и «асинхронный Backend» может быть более информативным.

TF-IDF для рекомендательной системы позволяет построить простой механизм текстового сходства без обучения большой нейросети. Это хороший учебный пример, который помогает понять основу content-based рекомендаций.

Создадим рекомендательную систему на Python

Используем scikit-learn. Установим библиотеку: pip install scikit-learn Подготовим небольшой каталог: courses = [ { "id": 1, "title": "Основы Python", "description": ( "Python программирование " "переменные функции циклы" ) }, { "id": 2, "title": "FastAPI для Backend", "description": ( "Python FastAPI Backend " "REST API разработка" ) }, { "id": 3, "title": "SQL и PostgreSQL", "description": (

"SQL PostgreSQL базы данных " "Backend разработка" ) }, { "id": 4, "title": "Машинное обучение", "description": ( "Python машинное обучение " "модели классификация" ) }, { "id": 5, "title": "Анализ данных", "description": ( "Python анализ данных " "pandas визуализация" ) } ] Теперь преобразуем описания в TF-IDF-векторы: from sklearn.feature_extraction.text import TfidfVectorizer descriptions = [ course["description"]

for course in courses ] vectorizer = TfidfVectorizer() vectors = vectorizer.fit_transform( descriptions ) Каждый курс теперь представлен числовым вектором. Так начинается создание рекомендательной модели на Python. Важно понимать, что качество результата зависит от качества описаний. Если два совершенно разных курса содержат одинаковые общие слова, алгоритм может посчитать их похожими.

Что такое косинусное сходство

После преобразования текстов в векторы нужно измерить их сходство. Один из распространённых способов — cosine similarity, или косинусное сходство. Оно оценивает направление двух векторов, а не просто разницу между отдельными числами. Для TF-IDF-векторов это удобный способ сравнения документов. Косинусное сходство в рекомендательной системе позволяет определить, какие описания наиболее похожи друг на друга.

Используем scikit-learn: from sklearn.metrics.pairwise import cosine_similarity similarity_matrix = cosine_similarity( vectors ) Теперь similarity_matrix[i][j] содержит оценку сходства между двумя курсами. Для неотрицательных TF-IDF-векторов значения обычно находятся в диапазоне от 0 до 1, где более высокое значение означает большее сходство по выбранным текстовым признакам.

Как получить похожие курсы

Напишем функцию, которая принимает идентификатор курса и возвращает несколько наиболее похожих материалов. def recommend_similar_courses( course_id: int, limit: int = 3 ): index_by_id = { course["id"]: index for index, course in enumerate(courses) } if course_id not in index_by_id: return [] source_index = index_by_id[course_id] scores = list( enumerate( similarity_matrix[source_index] ) ) scores = [ (index, score)

for index, score in scores if index != source_index ] scores.sort( key=lambda item: item[1], reverse=True ) return [ { "id": courses[index]["id"], "title": courses[index]["title"], "score": float(score) } for index, score in scores[:limit] ] Теперь можно вызвать: recommend_similar_courses(course_id=2) Функция вернёт курсы, текстовые описания которых наиболее похожи на описание FastAPI.

Так работает поиск похожих товаров и курсов на основе текстовых признаков. Однако этот пример демонстрирует именно сходство материалов. Он ещё не учитывает личную историю конкретного пользователя.

Как превратить похожие курсы в персональные рекомендации

Представим, что пользователь завершил три курса. Можно получить похожие материалы для каждого из них, объединить кандидатов и вычислить итоговую оценку. Например, система может учитывать среднее или максимальное сходство с уже изученными курсами. При этом необходимо исключить материалы, которые пользователь уже завершил. Так появляются персональные рекомендации на Python.

Но здесь возникает важный вопрос: все ли завершённые курсы действительно отражают интересы человека? Возможно, пользователь прошёл обязательный вводный материал, который ему не понравился. Поэтому полезно учитывать не только факт завершения, но и дополнительные сигналы — оценки, сохранения или выбранную образовательную цель.

Что такое collaborative filtering

Content-based подход использует свойства объектов. Collaborative filtering опирается на взаимодействия пользователей с объектами. Идея заключается в том, что люди с похожей историей интересов могут находить полезными похожие материалы. Например, два пользователя завершили курсы по Python и SQL. Один из них затем прошёл FastAPI и поставил высокую оценку. Система может предложить FastAPI второму пользователю.

Так работает коллаборативная фильтрация рекомендаций. Её преимущество в том, что она может находить неочевидные связи между объектами, даже если их текстовые описания не очень похожи. Но для этого нужна достаточно информативная история взаимодействий.

Как выглядит матрица пользовательских оценок

Представим небольшую таблицу: Знак «—» означает, что оценки нет. Матрица взаимодействий пользователей и объектов является основой многих алгоритмов collaborative filtering. Система пытается использовать известные взаимодействия, чтобы оценить вероятность интереса к ещё не изученным объектам. Важно не путать отсутствие оценки с нулевой оценкой. Пользователь мог просто не видеть курс.

User-based collaborative filtering

Один из подходов — искать пользователей с похожими предпочтениями. Например, Анна и Олег высоко оценили Python и SQL. Если Олег также оценил FastAPI, система может учитывать это при рекомендациях Анне. Это называется user-based collaborative filtering. Однако на больших платформах постоянный поиск похожих пользователей может быть дорогим, а сами предпочтения — быстро меняться.

Поэтому такой подход полезен для понимания идеи, но не всегда является лучшим production-решением.

Item-based collaborative filtering

Другой вариант — находить объекты, которые часто интересуют одних и тех же пользователей. Например, люди, изучавшие Python, часто переходят к SQL и FastAPI. Система вычисляет сходство между курсами на основе пользовательских взаимодействий. Это item-based collaborative filtering. Такой подход может быть удобен, когда каталог относительно стабилен, а пользователей значительно больше, чем объектов.

Но качество рекомендаций всё равно зависит от объёма и структуры собранных данных.

Что такое матричная факторизация

Когда пользователей и объектов становится много, матрица взаимодействий обычно содержит множество пропусков. Матричная факторизация пытается представить пользователей и объекты в пространстве скрытых факторов. Например, один фактор может приблизительно соответствовать интересу к Backend, другой — к анализу данных. Но эти факторы не обязательно имеют простую человеческую интерпретацию.

Матричная факторизация для рекомендаций позволяет оценивать предпочтения на основе скрытых закономерностей взаимодействий. К этой группе относятся разные подходы, включая методы, связанные с SVD и обучением латентных представлений. Однако конкретный алгоритм нужно выбирать с учётом того, какие данные доступны: явные оценки или неявные взаимодействия.

Почему рекомендации плохо работают для новых пользователей

Представим, что человек только зарегистрировался. Он ещё ничего не просмотрел, не сохранил и не оценил. Система collaborative filtering практически не знает о его интересах. Это называется проблема холодного старта в рекомендациях. Она возникает не только для новых пользователей, но и для новых объектов.

Если курс только появился в каталоге, у него ещё нет истории взаимодействий, поэтому алгоритмы, основанные исключительно на поведении пользователей, могут редко его рекомендовать.

Как решить проблему холодного старта

Для нового пользователя можно использовать несколько простых источников информации. Например, при регистрации предложить выбрать направление обучения: Backend, Frontend, AI или Data Science. Также можно показывать популярные курсы для начинающих и материалы, рекомендованные редакцией платформы. Для нового курса полезны content-based признаки: категория, описание, уровень сложности и необходимые знания.

Так создаются рекомендации для новых пользователей. Необязательно требовать от человека заполнения длинной анкеты. Иногда достаточно одного вопроса о цели обучения.

Что такое гибридная рекомендательная система

Представим, что у нас есть три источника рекомендаций. Первый — правила образовательной последовательности. Второй — сходство описаний курсов. Третий — история поведения похожих пользователей. Вместо выбора одного подхода можно объединить их. Так работает гибридная рекомендательная система. Например, итоговая оценка может учитывать несколько факторов:

[S = 0.4S_{\text{content}} + 0.3S_{\text{behavior}} + 0.3S_{\text{learning}}] Здесь коэффициенты приведены только для иллюстрации. Их нельзя считать универсальными. Кроме того, перед объединением оценки разных алгоритмов обычно нужно привести к сопоставимым шкалам. Гибридный подход полезен тем, что позволяет компенсировать слабые стороны отдельных методов.

Почему не стоит рекомендовать только самое популярное

Представим, что курс «Основы Python» — самый популярный на платформе. Если показывать его каждому пользователю, рекомендации будут выглядеть логично только для новичков. Человеку, который уже разрабатывает Backend-приложения, вводный курс может быть не нужен. Поэтому рекомендации на основе популярности подходят прежде всего как базовый вариант, особенно для новых пользователей.

Но по мере накопления данных популярность полезно сочетать с контекстом. Например, можно показывать популярные курсы внутри выбранного направления и подходящего уровня сложности.

Как избежать однообразных рекомендаций

Представим, что пользователь однажды посмотрел курс по FastAPI. Система решила, что ему интересен только Backend, и теперь постоянно показывает исключительно серверные технологии. Такие рекомендации могут быть релевантными, но слишком узкими. Поэтому разнообразие рекомендательной выдачи — важная характеристика качества.

Иногда полезно включать в подборку смежные темы: базы данных, тестирование, DevOps или архитектуру приложений. Для образовательной платформы это особенно важно, поскольку развитие навыков редко ограничивается одной узкой темой.

Что такое exploration и exploitation

В рекомендательных системах существует баланс между двумя стратегиями. Exploitation — показывать то, что с высокой вероятностью понравится пользователю на основании уже известных предпочтений. Exploration — иногда предлагать новые или менее изученные варианты, чтобы узнать больше об интересах человека.

Exploration и exploitation в рекомендациях помогают избежать ситуации, когда система постоянно повторяет один и тот же тип контента. Например, пользователю, изучающему Python, можно преимущественно рекомендовать Backend-материалы, но иногда предлагать вводные курсы по анализу данных. Однако экспериментировать с рекомендациями следует аккуратно, особенно если неправильный выбор может серьёзно повлиять на пользователя.

Как оценивать качество рекомендательной системы

Представим, что алгоритм предлагает пять курсов. Пользователь открывает один из них. Можно ли считать систему успешной? Частично да, но клик ещё не означает, что рекомендация оказалась полезной. Поэтому метрики качества рекомендательной системы должны соответствовать цели продукта.

Для образовательной платформы можно измерять не только клики, но и начало обучения, завершение курса или продвижение по выбранной траектории. В интернет-магазине метрики будут другими.

Precision@K и Recall@K

Для offline-оценки часто используют метрики ранжирования. Precision@K показывает, какая доля объектов среди первых K рекомендаций оказалась релевантной по выбранному определению. Recall@K показывает, какую долю всех релевантных объектов система смогла включить в первые K рекомендаций. Например, если среди пяти рекомендованных курсов три считаются релевантными, Precision@5 составляет: [Precision@5 = \frac{3}{5} = 0.6]

Precision@K и Recall@K для рекомендаций полезны при сравнении алгоритмов на исторических данных. Но результат зависит от того, как определяется релевантность и как сформирован тестовый набор. Отсутствие взаимодействия не всегда означает, что курс неинтересен.

Что такое NDCG

Не менее важно положение релевантных объектов. Представим два алгоритма. Оба нашли три подходящих курса, но первый разместил их на первых позициях, а второй — в конце списка. Для пользователя первый вариант обычно удобнее. Метрика NDCG учитывает порядок рекомендаций и степень их релевантности. NDCG для оценки рекомендаций помогает сравнивать качество ранжирования, а не только наличие подходящих объектов в выдаче.

Однако сложная метрика не заменяет понимание пользовательского сценария. Если система оптимизирует неправильную цель, высокий NDCG сам по себе не сделает продукт полезнее.

Почему offline-метрик недостаточно

Алгоритм может показывать хорошие результаты на исторических данных, но хуже работать с реальными пользователями. Например, система научилась рекомендовать курсы, которые люди часто открывают, но редко завершают. Поэтому оценка рекомендаций на реальных пользователях требует продуктовых метрик.

Можно измерять долю переходов по рекомендациям, начало обучения, завершение материалов и долгосрочное возвращение пользователей. Важно также следить, чтобы оптимизация одного показателя не ухудшала другие. Например, увеличение количества кликов не должно достигаться за счёт вводящих в заблуждение заголовков.

Как проводить A/B-тест рекомендаций

Представим две версии алгоритма. Версия A показывает популярные курсы. Версия B учитывает завершённые материалы и выбранное направление. Пользователей случайным образом распределяют между вариантами и сравнивают заранее выбранную метрику. Так работает A/B-тестирование рекомендательной системы. Перед экспериментом нужно определить основную метрику, минимально значимый эффект и достаточную продолжительность наблюдения.

Для маленького проекта статистической мощности может не хватать. В таком случае полезнее начать с качественной обратной связи и анализа отдельных пользовательских сценариев, чем делать уверенные выводы по нескольким кликам.

Как хранить взаимодействия пользователей

Для перехода от правил к ML нужна история действий. Например, можно создать таблицу: CREATE TABLE course_interactions ( id BIGSERIAL PRIMARY KEY, user_id BIGINT NOT NULL, course_id BIGINT NOT NULL, event_type VARCHAR(40) NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); События могут включать: course_viewed course_saved course_started course_completed course_rated

Хранение взаимодействий для рекомендаций позволяет анализировать интересы пользователей и готовить данные для моделей. Но собирать каждое движение мыши не требуется. Лучше начать с небольшого набора событий, имеющих понятный продуктовый смысл. Также необходимо учитывать согласие, сроки хранения и возможность удаления данных там, где это требуется.

Как подготовить данные для ML-рекомендаций

Исторические события редко подходят для модели без предварительной обработки. Например, один пользователь может открыть страницу курса десять раз, а другой — один раз и сразу начать обучение. Простой подсчёт просмотров может ошибочно посчитать первого человека более заинтересованным. Поэтому подготовка данных для рекомендательной модели включает очистку событий, обработку повторов и определение весов разных действий.

Например, завершение курса может считаться более сильным сигналом, чем просмотр страницы. Но конкретные веса необходимо проверять на данных и пользовательских сценариях.

Почему важно разделять обучение и тестирование по времени

Представим, что модель обучается на истории взаимодействий пользователей. Если случайным образом перемешать все события, в обучающую выборку могут попасть действия, произошедшие позже событий из тестовой выборки. Это создаёт риск использования информации из будущего. Поэтому временное разделение данных для рекомендаций часто ближе к реальному сценарию.

Например, модель обучается на взаимодействиях до определённой даты, а затем проверяется на более поздних действиях. Так можно лучше оценить, насколько алгоритм способен предлагать полезные материалы в будущем.

Как подключить рекомендации к FastAPI

Теперь представим, что у нас уже есть функция recommend_similar_courses. Создадим endpoint: from fastapi import FastAPI, HTTPException app = FastAPI() @app.get("/courses/{course_id}/recommendations") def get_course_recommendations( course_id: int ): course_exists = any( course["id"] == course_id for course in courses ) if not course_exists: raise HTTPException( status_code=404, detail="Course not found" )

recommendations = recommend_similar_courses( course_id=course_id, limit=5 ) return { "course_id": course_id, "items": recommendations } Так создаётся API рекомендаций на FastAPI. Для демонстрационного каталога можно хранить векторы в памяти приложения. Но если курсы регулярно добавляются и изменяются, нужно организовать обновление признаков и индекса.

Также важно учитывать, что пример не содержит авторизации и проверки доступности отдельных курсов. В реальном приложении рекомендации должны соблюдать правила доступа к контенту.

Как выглядит персональный endpoint

Для персональной выдачи можно использовать маршрут: GET /users/me/recommendations Backend определяет текущего пользователя через авторизацию, получает его историю и формирует рекомендации. Персонализированные рекомендации через API не должны принимать произвольный user_id без проверки прав.

Например, если система использует историю обучения, один пользователь не должен получать доступ к личным данным другого через параметр запроса. В ответе обычно достаточно вернуть идентификаторы и публичные характеристики рекомендованных материалов.

Нужно ли обучать модель при каждом запросе

Нет. В большинстве случаев это нецелесообразно. Представим, что построение модели занимает несколько минут. Если запускать обучение при каждом открытии главной страницы, Backend будет работать крайне медленно. Поэтому обучение рекомендательной модели в фоне обычно отделяют от выдачи результатов. Например, модель можно обновлять по расписанию или после накопления определённого объёма новых данных.

Сам API должен быстро получать готовые признаки, оценки или список кандидатов.

Как устроена архитектура рекомендаций в production

Для небольшого приложения схема может быть следующей: PostgreSQL ↓ Подготовка данных ↓ Обучение модели ↓ Сохранение артефактов ↓ Recommendation Service ↓ FastAPI ↓ Frontend Так выглядит архитектура рекомендательной системы в production в упрощённом виде. При росте продукта могут появиться отдельные сервисы, хранилища признаков и системы обработки событий.

Но для первого проекта достаточно одного Backend, PostgreSQL и фонового процесса обновления модели.

Как кэшировать рекомендации

Представим, что пользователь открывает главную страницу несколько раз в течение часа. Если его интересы и каталог почти не изменились, нет необходимости каждый раз заново вычислять одинаковые рекомендации. Поэтому кэширование персональных рекомендаций может уменьшить нагрузку. Например, готовый список идентификаторов курсов можно временно хранить в Redis. Но важно определить, когда кэш становится устаревшим.

Если пользователь завершил курс, его не следует продолжать рекомендовать только потому, что старая выдача ещё находится в кэше.

Как учитывать новые курсы

Представим, что на платформе появился новый курс по AI-агентам. У него нет просмотров и оценок, поэтому collaborative filtering может редко включать его в рекомендации. Но у курса уже есть описание, категория и уровень сложности. Поэтому рекомендации для новых объектов можно формировать через content-based признаки и редакционные правила.

Это помогает новым материалам получать первые показы и постепенно накапливать историю взаимодействий.

Почему рекомендации могут усиливать перекосы

Представим, что система постоянно показывает самые популярные курсы. Они получают ещё больше просмотров, а новые материалы остаются незамеченными. Постепенно разница между популярными и менее известными курсами увеличивается. Так возникает популярностный перекос в рекомендательной системе.

Чтобы уменьшить его влияние, можно учитывать разнообразие выдачи, выделять место для новых материалов и проверять, как рекомендации распределяют внимание пользователей. Но любые изменения нужно соотносить с качеством и полезностью контента.

Как объяснять рекомендации пользователю

Человек может лучше воспринимать рекомендацию, если понимает её причину. Например: Рекомендуем после курса «Основы Python». Или: Похоже на материалы, которые вы сохранили. Такие объяснения делают систему прозрачнее. Объяснимость рекомендательной системы особенно важна в образовательных продуктах, где человеку полезно понимать логику следующего шага.

Но объяснение должно соответствовать реальному алгоритму. Не стоит писать «Подобрано специально для вас», если система просто показывает одинаковый список всем пользователям.

Как добавить рекомендации на Frontend

Представим, что пользователь открыл страницу курса. Frontend запрашивает: async function loadRecommendations(courseId) { const response = await fetch( `/courses/${courseId}/recommendations` ); if (!response.ok) { throw new Error( "Failed to load recommendations" ); } const data = await response.json(); return data.items; } После получения данных интерфейс показывает блок: Вам также может понравиться

FastAPI для Backend SQL и PostgreSQL Тестирование Python-приложений Отображение рекомендаций на Frontend должно учитывать загрузку, отсутствие результатов и ошибки API. Если система пока не может сформировать персональную выдачу, лучше показать понятную альтернативу, например популярные курсы подходящего уровня.

Как выбрать место для рекомендаций

Рекомендации можно показывать на главной странице, после завершения урока, в карточке курса или внутри личного кабинета. Но один и тот же алгоритм не обязательно подходит всем этим местам. Например, после завершения курса полезно предложить следующий шаг. На главной странице — материалы, соответствующие общей цели пользователя. В карточке курса — похожие программы.

Поэтому размещение рекомендательных блоков на сайте должно соответствовать контексту. Чем точнее система понимает задачу пользователя в конкретный момент, тем полезнее может оказаться рекомендация.

Как тестировать рекомендательную систему

Начать стоит с простых технических проверок. Алгоритм не должен рекомендовать несуществующие курсы, возвращать один объект несколько раз или включать недоступные материалы. Для персональных рекомендаций нужно проверять исключение уже завершённых курсов и соблюдение прав доступа.

Тестирование рекомендательной системы Python также включает проверку корректности обработки пустой истории пользователя и отсутствующих признаков. Отдельно полезно тестировать качество рекомендаций на небольшом наборе заранее подготовленных примеров. Например, после курса по Python система должна предлагать логичное продолжение, а не случайные материалы из другой категории.

Как оценить скорость рекомендаций

Для пользователя важна не только точность, но и скорость появления карточек. Если блок рекомендаций загружается десять секунд, человек может уйти со страницы раньше. Поэтому оптимизация скорости рекомендательной системы включает измерение времени ответа API, стоимости получения данных и вычисления оценок. На небольшом каталоге простые расчёты могут выполняться непосредственно в Backend.

На большом — полезно заранее рассчитывать похожие объекты, кэшировать результаты или использовать специализированные структуры поиска.

Когда нужны векторные рекомендации

TF-IDF хорошо работает с текстовыми признаками, но не всегда способен уловить смысловую близость. Например, описания «создание серверных приложений» и «разработка Backend-сервисов» могут быть близки по смыслу, даже если содержат разные слова. Для таких сценариев можно использовать embeddings — векторные представления текста, полученные с помощью моделей машинного обучения.

Векторные рекомендации по embeddings позволяют искать объекты по сходству их представлений. Однако качество зависит от выбранной модели, данных и способа поиска. Embeddings не гарантируют, что найденный курс соответствует уровню пользователя или его образовательной цели. Поэтому семантическое сходство полезно сочетать с обычными фильтрами и бизнес-правилами.

Чем рекомендательная система отличается от AI-агента

Иногда любые персональные предложения называют AI-рекомендациями. Но рекомендательная система не обязательно использует большую языковую модель или AI-агента. Она может работать на SQL, правилах, статистических алгоритмах или классических ML-моделях. Рекомендательная система без нейросетей способна решать реальные продуктовые задачи.

Большие языковые модели могут помогать анализировать описания, объяснять рекомендации или учитывать сложные текстовые предпочтения. Но они не являются обязательной частью архитектуры. Выбирать технологию нужно по требованиям, а не по популярности термина AI.

Практический пример: образовательная платформа

Представим пользователя, который выбрал направление Full Stack и завершил основы Python. На первом этапе система использует правила и предлагает SQL, FastAPI и основы Frontend. Когда пользователь начинает сохранять и оценивать курсы, приложение накапливает данные об интересах. Позже можно добавить content-based рекомендации по описаниям материалов.

Когда аудитория и история взаимодействий станут достаточно большими, появится возможность экспериментировать с collaborative filtering. Так поэтапная разработка рекомендательной системы позволяет развивать продукт без преждевременной сложности. Каждый следующий этап должен решать конкретную проблему предыдущего, а не просто добавлять новую технологию.

Практический пример: рекомендации в интернет-магазине

Представим магазин компьютерных аксессуаров. Пользователь открывает страницу ноутбука. На первом этапе можно рекомендовать совместимые аксессуары по заранее заданным правилам. Позже — похожие товары по характеристикам. Затем — товары, которые часто покупают вместе. Так рекомендации товаров в интернет-магазине могут сочетать бизнес-правила и анализ пользовательских взаимодействий.

Но здесь особенно важно учитывать совместимость. Алгоритм, основанный только на статистическом сходстве, может предложить неподходящий аксессуар. Поэтому правила предметной области должны оставаться частью системы.

Частые ошибки при создании рекомендаций

Первая ошибка — начинать со сложной нейросети, когда нет достаточных данных и понятной цели. Вторая — считать каждый просмотр страницы положительным сигналом интереса. Третья — рекомендовать пользователю материалы, которые он уже завершил. Четвёртая — игнорировать уровень сложности и предварительные требования. Пятая — показывать только самые популярные объекты.

Шестая — не учитывать холодный старт новых пользователей и материалов. Седьмая — оценивать алгоритм только по кликам. Восьмая — использовать данные из будущего при offline-тестировании. Девятая — не обновлять модель после изменения каталога. Десятая — забывать о приватности и правах доступа.

Эти ошибки разработки рекомендательных систем часто возникают из-за попытки решить задачу алгоритмом до того, как определены продуктовые требования.

Чек-лист рекомендательной системы

Перед запуском полезно проверить несколько вещей. Понятно ли, какую пользовательскую задачу решают рекомендации? Какие объекты система предлагает? Какие данные используются? Есть ли простой базовый алгоритм для сравнения?

Что увидит новый пользователь без истории? Как обрабатываются новые курсы? Исключаются ли уже изученные материалы? Соблюдаются ли ограничения доступа? Есть ли понятная причина, почему объект попал в выдачу? Нужно также определить, как часто обновляются рекомендации, как измеряется их качество и что происходит при недоступности ML-компонента.

Такой чек-лист разработки рекомендаций помогает сохранить фокус на пользе продукта, а не на сложности алгоритма.

FAQ

Можно начать с правил и SQL-запросов, а затем добавить scikit-learn для поиска похожих объектов по текстовым признакам. Для более сложных рекомендаций понадобятся данные о взаимодействиях пользователей. Нет. Многие полезные рекомендательные системы работают на правилах, статистике и классических алгоритмах машинного обучения.

Content-based filtering использует характеристики объектов. Collaborative filtering опирается на историю взаимодействий пользователей с объектами. Можно использовать выбранную образовательную цель, популярные материалы подходящего уровня и правила последовательности обучения.

Начать с простого алгоритма и постепенно собирать качественные события. Сложная модель на небольшом количестве данных не обязательно будет лучше правил. Нужно создать endpoint, который получает контекст пользователя или идентификатор объекта, вызывает рекомендательный алгоритм и возвращает список подходящих материалов.

Да. PostgreSQL подходит для хранения характеристик объектов, истории взаимодействий и реализации простых рекомендательных правил. Для offline-оценки подходят Precision@K, Recall@K и NDCG. Для продуктовой оценки — клики, начало обучения, завершение курсов и другие показатели, соответствующие цели сервиса.

Это ситуация, когда о новом пользователе или объекте ещё недостаточно информации для рекомендаций на основе истории взаимодействий. Когда смысловое сходство текстов важно и простые текстовые признаки недостаточны. При этом embeddings следует сочетать с фильтрами и правилами продукта.

Заключение

Рекомендательная система — это инструмент, который помогает пользователю находить полезные материалы без необходимости каждый раз формулировать поисковый запрос. Но её качество определяется не сложностью модели, а тем, насколько хорошо она решает конкретную задачу.

Для небольшого образовательного сервиса полезные рекомендации можно построить на SQL и простых правилах. По мере роста каталога можно добавить поиск похожих материалов через TF-IDF и косинусное сходство. Когда накопится достаточная история взаимодействий, появится возможность использовать collaborative filtering и более сложные модели.

Важно помнить, что персонализация — не самоцель. Пользователь должен получать материалы, соответствующие его интересам, уровню знаний и текущему этапу обучения. Поэтому хорошая рекомендательная система сочетает технические алгоритмы с пониманием продукта. Она учитывает качество данных, корректно работает с новыми пользователями, соблюдает права доступа и постоянно проверяется на реальной пользе.

Главный принцип прост: сначала создайте рекомендации, которые действительно помогают человеку, и только затем усложняйте алгоритм.

Наверх