Предлагаемые темы: предложения на основе заголовка и контента

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

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

6 лайков

Я создал похожую тему, но она закрыта.
В данный момент я отключил эту функцию и заменил её своей.

1 лайк

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

Я понимаю привлекательность использования ИИ для определения связанного контента — это может быть очень полезно для тем в категории #поддержка, которые почти можно сделать «самообслуживаемыми». Вы задаёте вопрос, ML отбирает 10 кандидатов и просто публикует их как ответ, который вы можете либо принять, либо удалить. Аналогично, когда аноним обращается за поддержкой, полезно показывать связанную информацию.

Тем не менее… это гигантская и огромная задача. Она не входит в наш план на следующий год. Но @eviltrout с энтузиазмом относится к экспериментам с ИИ/МО в будущем, и этот тип проекта мог бы быть связан с такими инициативами.

@codinghorror остаётся большим поклонником случайного выбора (DJ random), потому что он считает, что он может превзойти множество сложных алгоритмов (и часто так и происходит).

7 лайков

DJ Random — это фантастика, хотя мы и ограничиваем его по времени и категории/тегу — это важно.

3 лайка

Привет,

Я новичок здесь, так что извините, если я зря тратю время.

Я согласен с @sam, что есть глубокое погружение, но с другой стороны, технологии тематического моделирования сейчас довольно зрелые, и существуют готовые инструменты, которые работают очень хорошо. В одном из моих недавних проектов были проанализированы примерно 5 миллионов названий и аннотаций патентов; анализ порядка нескольких тысяч тем на моём новом и красивом форуме сайт был бы для меня детской игрой. Более того, у моего сообщества может быть достаточно энергии, чтобы это реализовать.

От экспертов: я хотел бы получить совет, стоит ли мне думать о создании плагина или лучше работать с исходным кодом Discourse (который я скачал с GitHub)?

Нашёл это про парсинг тем форума Discourse с помощью Python, но пока не смог заставить это работать. Что-то подобное должно позволить мне выгрузить данные в офлайн, построить модель и затем использовать её для запросов.

Большинство хороших инструментов написаны на Python, к слову…

4 лайка

По функциональности это лучше всего подходит для панели «Ваша тема похожа на…» при создании новой темы.

1 лайк

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

Существует множество вопросов, связанных с механизмами обучения и т. д. Можете ли вы описать механику, по которой будет происходить обучение? Какие именно модели вы рекомендуете использовать? Что произойдет, если в теме будет 100 сообщений? 1000 сообщений?

Что вы будете использовать в качестве сигнала и какую силу придадите каждому фактору (просмотры/категория/теги и так далее)?

Мне очень нравится этот проект, но я считаю, что это довольно масштабная задача.

3 лайка

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

Инструменты, которые в настоящее время использует моя команда, взяты из gensim. У него есть стандартный интерфейс модуля Python. Он хорошо протестирован на протяжении многих лет.

Схема, которая приходит мне на ум, выглядит так:

  • Сначала: выберите набор документов: это могут быть все корневые темы или все сообщения.

Периодически (например, раз в неделю? раз в месяц? в зависимости от трафика форума) создавайте модель doc2vec:

  • извлеките темы Discourse в файл (или файлы) в формате md-текста, заголовок + тело темы. Теперь рассматривайте каждую тему как документ, или «документ» для алгоритмов gensim.
  • запустите стандартные инструменты NLP для обработки документов: стемминг слов и т. д.
  • используйте doc2vec (из реализации gensim) для создания модели, которая отображает каждый документ в вектор в d-мерном пространстве. Вам нужно выбрать мета-параметр d методом экспериментов; Google использует d=40 для своих патентных моделей; не уверен, какое значение d используется Google Scholar. Я обычно использую d=200. Каждое измерение пространства можно рассматривать как «признак», связанный с семантическим содержанием.
    • (FYI: алгоритм doc2vec строит пространство признаков, обучая нейронную сеть, ориентированную на изучение последовательностей слов; у нейросети есть d-мерный скрытый слой; выходы скрытого слоя формируют латентное пространство признаков)
  • Построение модели — это ресурсоёмкая задача, зависящая от количества документов. 38 лет патентов = 5 миллионов документов; модель doc2vec строится за ночь на старом компьютере с 8 ядрами.
  • Опциональная интересная дополнительная задача: кластеризация облака документов в d-мерном пространстве признаков.
    • для кластеризации можно использовать готовые инструменты, например, из библиотеки Python sklearn.
    • кластеризация даёт эмерджентную классификацию; интересные исследовательские вопросы включают то, как эти классификации пересекаются с категориями ключевых слов (или тегов Discourse).

Это будет происходить в офлайн-режиме. Затем онлайн:

  • Модель будет загружена.
  • После загрузки модели относительно лёгкая задача — разобрать новый документ и запросить у модели его положение в d-мерном пространстве признаков.
    • обратите внимание, что этот новый документ не вызовет перестройку модели. Модель будет статичной для онлайн-запросов. Новый документ будет включён в следующую (например, еженедельную) сборку модели.
  • Затем последняя лёгкая задача — спросить, какие документы находятся рядом в пространстве признаков. В gensim есть инструменты для получения списка близких документов, но вы также можете напрямую использовать numpy, чтобы загрузить все векторы документов в структуру типа kd-дерева, что позволяет быстро запрашивать близкие точки.

Что происходит, когда у темы 100 сообщений? 1000 сообщений?

Офлайн-часть масштабируется примерно линейно с количеством документов, но должна быть вполне управляемой для 10–100 тысяч документов. Даже 1 миллион документов приемлем для еженедельной пакетной обработки.

Что вы будете использовать в качестве сигнала и какую силу придадите каждому фактору (просмотры/категория/тег и так далее)?

В данном контексте «сила сигнала» для новой темы напрямую интерпретируется как (обратное) расстояние от векторного представления новой темы до векторов существующих документов. Можно дополнить этот сигнал другими факторами (лайки, просмотры и т. д.), но это дополнительные опции к базовому алгоритму, который я описываю.

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

Сложная часть (для меня) — это онлайн-часть, которая потребует интеграции Rails-приложения Discourse с несколькими вызовами Python (например, к инструментам gensim). Любые примеры подобного интерфейса были бы полезны для моего изучения.

6 лайков

@Bcat: Мне было бы очень интересно посмотреть, как вы «заменяли на свои». У вас есть плагин или репозиторий, который я мог бы изучить?

Сложный аспект производительности здесь — это механизм RPC. Не стоит запускать новый процесс Python для каждого просмотра темы.

Даже HTTP-запрос может оказаться слишком медленным.

Может быть… создать таблицу related_topics (topic_id, related_topic_id, rank)? Тогда можно будет использовать WebHooks для быстрого обновления таблицы при создании новых тем, и Ruby не будет нуждаться в вызовах Python.

Сторона Discourse будет реализована довольно просто: вам нужно будет просто переписать этот метод, чтобы он искал информацию в вашей новой таблице related_topics.

2 лайка

Старый способ не сработал, поэтому я заменил его на Google Ads. Темы, которые предлагает Google, очень удачные.
Что касается старого подхода, я отключил стандартные предложения и заменил их JS-сниппетом, который делает запрос к /search, а затем возвращает список тем.

2 лайка

Спасибо за ссылку на реализацию таблицы. Однако не уверен, что табличный подход масштабируется. Для N тем нам понадобится таблица размером N^2. Так, для 10^4 тем таблица будет содержать 10^8 записей.

Не вижу способа избежать вызова Python для парсинга новой темы, её встраивания и поиска ближайших соседей. Ранее я уже создавал веб-интерфейс, но в данном случае, вероятно, предпочту запустить отдельный процесс Python и взаимодействовать с Discourse через сокет или канал, что будет выглядеть примерно как чтение и запись в файл, а не как прямой вызов Python. (В конце концов, всё работает на моём сервере…)

Извините, но, кажется, я полностью неправильно это понял?

Если у вас 100 тем и каждая тема показывает 5 связанных тем, почему таблица должна быть больше, чем 500?

1 лайк

N тем = N точек в векторном пространстве. Матрица расстояний между каждой точкой имеет размер N² (матрица симметрична, поэтому существует N*(N-1)/2 независимых значений). Именно это N² я имел в виду.

Однако умные структуры данных (например, kd-дерево) позволяют находить ближайших соседей без полного перебора таблицы из N² разностей.

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

1 лайк

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

Затем часть плагина Discourse становится довольно тривиальной. Вместо выборки из местоположения X она будет выбирать из местоположения Y (другая таблица).

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

Предложенный здесь подход с использованием ИИ звучит интересно и может стать идеальным решением.

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

Это не полноценный макет, но чтобы мы понимали друг друга, я имею в виду что-то вроде этого:

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

Это также может быть полезно для менее спорных тем. Когда я отвечаю на тему здесь, я часто использую функцию поиска по сайту, чтобы проверить, есть ли связанные темы. Результаты таких поисков можно было бы сохранить, разрешив пользователям предлагать связанные темы. В качестве примера: прочитав эту тему, я подумал о недавнем использовании ИИ в Discourse: Discourse Disorder. Мне кажется уместным, чтобы эта тема появилась в списке предлагаемых тем для текущей, с примечанием о том, что Discourse, похоже, изучает способы интеграции форумов с ИИ.

3 лайка

Обновление: это уже реализовано в плагине Discourse AI :confetti_ball:

5 лайков