| ... | ... | @@ -176,64 +176,58 @@ |
|
|
|
|
|
|
|
## 3.1 Загрузка данных Zulip и начальная предобработка
|
|
|
|
|
|
|
|
Для получения информации используется API Zulip. Полученный массив, включающий в себя темы, содержание сообщений и id авторов, записывается в текстовый файл. Далее этот файл поступает в модуль, взаимодействующий с моделью машинного обучения. В результате работы формируется рейтинг людей, которые участвовали в обсуждении определенной темы и которых сервис идентифицирует как экспертов в заданной области.
|
|
|
|
Для получения информации используется [`API` **Zulip**](https://zulip.com/api/). Полученный массив, включающий в себя темы, содержание сообщений и `id` авторов, записывается в текстовые файлы `messages.txt` и `ids.json` в директорию [`zulip/data`](https://git.miem.hse.ru/240/competence-search/-/tree/master/zulip/data).
|
|
|
|
|
|
|
|
Алгоритм получения сообщений выглядит следующим образом:
|
|
|
|
1) Программа получает id последнего сообщения, которое написано на момент выполнения программы, и записывает его в переменную «last_anchor»;
|
|
|
|
2) При помощи эндпоинта GET «/api/v1/messages» сервис циклично производит запрос на получение 4500 сообщений за раз (рисунок 17). Такое число обусловлено лимитом сервиса на единовременное получение сообщений. Вводится переменная anchor, которой присваивается id последнего написанного сообщения в запросе. Когда ее значение превышает значение параметра «last_anchor», запросы на сообщения прекращаются;
|
|
|
|
|
|
|
|

|
|
|
|
Далее этот файл поступает в модуль, взаимодействующий с моделью машинного обучения ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/zulip/src/trainer/train_model.py#L10)) и модель машинного обучения начинает обучаться.
|
|
|
|
|
|
|
|
3) При получении массива сообщений каждое из них обрабатывается в отдельной функции «preprocess_message». В ней происходит удаление HTML-тегов и специальных слов и предложений, которые часто повторяются в Zulip и не несут ценности для разрабатываемого сервиса, что показано на рисунке;
|
|
|
|
Алгоритм получения сообщений выглядит следующим образом:
|
|
|
|
1. Программа получает `id` последнего сообщения, которое написано на момент выполнения программы, и записывает его в переменную `last_anchor` ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/zulip/src/trainer/fetch_data.py#L67));
|
|
|
|
2. При помощи эндпоинта `GET` **/api/v1/messages** ([`API` **Zulip**](https://zulip.com/api/get-messages)) сервис циклично производит запрос на получение `4500` сообщений за раз ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/zulip/src/trainer/fetch_data.py#L40)). Такое число обусловлено лимитом сервиса на единовременное получение сообщений. Вводится переменная `anchor`, которой присваивается `id` последнего написанного сообщения в запросе. Когда ее значение превышает значение параметра `last_anchor` ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/zulip/src/trainer/fetch_data.py#L80)), запросы на сообщения прекращаются;
|
|
|
|
|
|
|
|

|
|
|
|
3. При получении массива сообщений каждое из них обрабатывается в отдельной функции `preprocess_message` ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/zulip/src/trainer/preprocess.py#L67)). В ней происходит удаление `HTML`-тегов и специальных слов и предложений, которые часто повторяются в **Zulip** и не несут ценности для разрабатываемого сервиса;
|
|
|
|
|
|
|
|
4) Если в результате сообщение является непустым и содержит больше одного слова, оно записывается в текстовый файл, в котором указываются тема и содержание сообщения. Данное действие показано на рисунке. Для определения оптимального варианта работы модели производилась запись в файл как сообщений с указанием темы, так и с ее отсутствием;
|
|
|
|
4. Если в результате сообщение является непустым и содержит больше одного слова, оно записывается в текстовый файл `messages.txt` в директорию [`zulip/data`](https://git.miem.hse.ru/240/competence-search/-/tree/master/zulip/data), в котором указываются _тема_ и _содержание_ сообщения ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/zulip/src/trainer/preprocess.py#L91));
|
|
|
|
|
|
|
|

|
|
|
|
5. После обработки всех сообщений, полученных при запросе, переменной `anchor` присваивается идентификатор последнего полученного сообщения.
|
|
|
|
|
|
|
|
5) После обработки всех сообщений, полученных при запросе, переменной «anchor» присваивается идентификатор последнего полученного сообщения.
|
|
|
|
## 3.2 Загрузка данных МИЭМ Wiki и начальная предобработка
|
|
|
|
|
|
|
|
## 3.2 Загрузка данных «МИЭМ Wiki» и начальная предобработка
|
|
|
|
Принцип интеграции **МИЭМ Wiki** в сервис **Поисковик компетенций** следующий: сервис собирает тексты страниц и идентификаторы авторов, затем загружает их в модель машинного обучения и, найдя наиболее релевантные статьи под запрос, выдает список их авторов.
|
|
|
|
|
|
|
|
Принцип интеграции «МИЭМ Wiki» в сервис «Поисковик компетенций» следующий: сервис собирает тексты страниц и идентификаторы авторов, затем загружает их в модель машинного обучения и, найдя наиболее релевантные статьи под запрос, выдает список их авторов.
|
|
|
|
Для сбора информации о статьях, которые пользователи пишут непосредственно в **МИЭМ Wiki**, разрабатываемый сервис использует `GraphQL API`.
|
|
|
|
|
|
|
|
Для сбора информации о статьях, которые пользователи пишут непосредственно в «МИЭМ Wiki», разрабатываемый сервис использует GraphQL API.
|
|
|
|
Специфика данного сервиса заключается в том, что помимо оригинальных страниц, написанных студентами и преподавателями, он также агрегирует информацию из сервиса «Taiga» – инструмента для управления проектами. Соответственно, при получении данных из «МИЭМ Wiki» мы по-разному обрабатываем их.
|
|
|
|
**Специфика** данного сервиса заключается в том, что помимо оригинальных страниц, написанных студентами и преподавателями, он также агрегирует информацию из сервиса **Taiga** – инструмента для управления проектами. Соответственно, при получении данных из **МИЭМ Wiki** следует обрабатывать их по-разному.
|
|
|
|
|
|
|
|
Данные из сервиса «Taiga» являются наиболее полезными, так как содержат проектную документацию, в тексте которой возможно найти фразы, подтверждающие компетентность авторов (предполагается, что, например, если человек написал руководство администратора, то он имеет компетенции в решении вопросов администрирования). Однако существуют авторы таких статей, которые не авторизованы в «МИЭМ Wiki», поэтому мы не можем напрямую брать информацию о их. Для этого мы анализируем содержание страниц на предмет наличия специального блока текста, который указывает, что данная страница поступила из сервиса «Taiga».
|
|
|
|
> Данные из сервиса **Taiga** являются наиболее полезными, так как содержат проектную документацию, в тексте которой возможно найти фразы, подтверждающие компетентность авторов (предполагается, что, например, если человек написал руководство администратора, то он имеет компетенции в решении вопросов администрирования). Однако существуют авторы таких статей, которые не авторизованы в **МИЭМ Wiki**, поэтому брать информацию о их не представляется возможным. Для этого анализируется содержание страниц на предмет наличия специального блока текста, который указывает, что данная страница поступила из сервиса **Taiga**.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
Первоначально в модель машинного обучения загружались страницы как единые документы. Однако средняя страница содержит слишком много тем в объеме текста, что не подходит для точного выделения компетенций. Поэтому было принято решение делить страницы на более мелкие документы по подзаголовкам. Так как для создания страниц в «МИЭМ Wiki» используются два способа: HTML и Markdown разметки – программа выделяет отдельные документы по тегам заголовков.
|
|
|
|
|
|
|
|
В результате модуль по работе с моделью машинного обучения передается два файла: текстовый массив с содержанием статей и файл в формате JSON, в котором порядок документов в первом файле соответствует данным об идентификаторе самой страницы и списке ее авторов.
|
|
|
|
> Первоначально в модель машинного обучения загружались страницы как единые документы. Однако средняя страница содержит слишком много тем в объеме текста, что не подходит для точного выделения компетенций. Поэтому было принято решение делить страницы на более мелкие документы по подзаголовкам. Так как для создания страниц в **МИЭМ Wiki** используются два способа: `HTML` и `Markdown` разметки – программа выделяет отдельные документы по тегам заголовков.
|
|
|
|
|
|
|
|
Итоговый алгоритм получения данных из «МИЭМ Wiki» выглядит следующим образом:
|
|
|
|
1) Получение списка идентификаторов всех страниц «МИЭМ Wiki», используя запрос GraphQL API. Для отправки запросов используется библиотека Python «requests»;
|
|
|
|
2) Цикличное получение данных о заголовке, содержании, идентификатора страницы, email авторов каждой страницы;
|
|
|
|
3) Проверка, что идентификатор автора не равен единице (1 – это id административного аккаунта, а эта информация является нерелевантной для нашего проекта);
|
|
|
|
4) Если страница содержит специальный блок с именами авторов, характерный для документации из сервиса «Taiga», то производится обработка данных, чтобы получить список идентификаторов авторов из сервиса «Taiga»;
|
|
|
|
5) Предобработка страницы. Помимо других изменений, в этом блоке удаляются все HTML-теги, кроме тегов заголовков, так как они нужны для последующего разбиения страницы на отдельные документы;
|
|
|
|
6) Поиск авторов страниц, которые создавали или редактировали их непосредственно в «МИЭМ Wiki». Для этого программа вызывает функцию получения редакторов страницы из API «МИЭМ Wiki», показанной на рисунке.
|
|
|
|
В результате модуль по работе с моделью машинного обучения передается **два** файла: текстовый массив с содержанием статей - `wiki.txt` в директории [`wiki/data`](https://git.miem.hse.ru/240/competence-search/-/tree/master/wiki/data) , и файл в формате `JSON` - `ids.json` в директории [`wiki/data`](https://git.miem.hse.ru/240/competence-search/-/tree/master/wiki/data), в котором порядок документов в первом файле (`id` документа, или же номер строки в файле) соответствует данным об идентификаторе самой страницы в **МИЭМ Wiki** и списке ее авторов.
|
|
|
|
|
|
|
|

|
|
|
|
Итоговый алгоритм получения данных из **МИЭМ Wiki** выглядит следующим образом:
|
|
|
|
|
|
|
|
7) Добавление id пользователей Wiki в финальный список авторов;
|
|
|
|
8) Вызов функции, которая находит документы в заданной странице;
|
|
|
|
9) Разделение страницы на документы по HTML или Markdown заголовкам;
|
|
|
|
10) Обработка документа, удаление из него HTML и Markdown тегов. Функция, осуществляющая это, показана на рисунке;
|
|
|
|
1. Получение списка идентификаторов всех страниц **МИЭМ Wiki**, используя запрос `GraphQL API` ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/wiki/src/trainer/fetch_data.py#L82));
|
|
|
|
2. Цикличное получение данных о заголовке, содержании, идентификатора страницы, email авторов каждой страницы ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/wiki/src/trainer/fetch_data.py#L91));
|
|
|
|
3. Проверка, что идентификатор автора не равен единице (`1` – это `id` административного аккаунта, а эта информация является нерелевантной для нашего проекта);
|
|
|
|
4. Если страница содержит специальный блок с именами авторов, характерный для документации из сервиса **Taiga**, то производится обработка данных, чтобы получить список идентификаторов авторов из сервиса **Taiga**;
|
|
|
|
5. Предобработка страницы ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/wiki/src/trainer/fetch_data.py#L110)). Помимо других изменений, в этом блоке удаляются все `HTML`-теги, кроме тегов заголовков, так как они нужны для последующего разбиения страницы на отдельные документы;
|
|
|
|
6. Поиск авторов страниц, которые создавали или редактировали их непосредственно в **МИЭМ Wiki**. Для этого программа вызывает функцию получения редакторов страницы из `API` **МИЭМ Wiki** ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/wiki/src/trainer/fetch_data.py#L113));
|
|
|
|
7. Добавление `id` пользователей **Wiki** в финальный список авторов;
|
|
|
|
8. Вызов функции, которая находит документы в заданной странице ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/wiki/src/trainer/fetch_data.py#L122));
|
|
|
|
9. Разделение страницы на документы по `HTML` или `Markdown` заголовкам;
|
|
|
|
10. Обработка документа, удаление из него `HTML` и `Markdown` тегов ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/wiki/src/trainer/fetch_data.py#L24));
|
|
|
|
11. Запись каждого документ в текстовый файл;
|
|
|
|
12. Запись в `JSON`-файл идентификатора страницы и префиксов почт ее авторов ([код](https://git.miem.hse.ru/240/competence-search/-/blob/c911531e19c93a1f7a0dc6b70b70c419284db23d/wiki/src/trainer/fetch_data.py#L139)).
|
|
|
|
|
|
|
|

|
|
|
|
## 3.3 Загрузка данных сервиса Личный кабинет МИЭМ и начальная предобработка
|
|
|
|
|
|
|
|
11) Запись каждого документ в текстовый файл;
|
|
|
|
12) Запись в JSON-файл идентификатора страницы и префиксов почт ее авторов.
|
|
|
|
**Личный кабинет МИЭМ** хранит информацию об исследовательских и прикладных проектах факультета. Для каждого проекта программа получает его описание, список участников и набор их компетенций («вакансии»).
|
|
|
|
|
|
|
|
## 3.3 Загрузка данных сервиса «Личный кабинет МИЭМ» и начальная предобработка
|
|
|
|
«Личный кабинет МИЭМ» хранит информацию об исследовательских и прикладных проектах факультета. Для каждого проекта программа получает его описание, список участников и набор их компетенций («вакансии»).
|
|
|
|
В функции предобработки из описаний проектов программа удаляет изображения, ссылки и дополнительные символы, которые снижают качество работы модели.
|
|
|
|
|
|
|
|
В функции предобработки из описаний проектов программа удаляет изображения, ссылки, дополнительные символы, которые снижают качество работы модели.
|
|
|
|
В модель передаются три типа документов: текстовый массив с описанием каждого проекта, JSON-файл, в котором помещены данные с id проекта и соответствующему ему списком id участников, а также файл с информацией о компетенциях каждого пользователя Личного кабинета.
|
|
|
|
В модель передаются три типа документов: текстовый массив с описанием каждого проекта `projects.txt` в директории [`cabinet/data`](https://git.miem.hse.ru/240/competence-search/-/tree/master/cabinet/data), `JSON`-файл `projects_info.json` в директории [`cabinet/data`](https://git.miem.hse.ru/240/competence-search/-/tree/master/cabinet/data), в котором помещены данные с `id` проекта и соответствующему ему списком `id` участников, а также файл с информацией о компетенциях каждого пользователя Личного кабинета - `students_info.txt` в директории [`cabinet/data`](https://git.miem.hse.ru/240/competence-search/-/tree/master/cabinet/data).
|
|
|
|
|
|
|
|
# 4 Размещение приложения на сервере
|
|
|
|
|
| ... | ... | @@ -264,7 +258,7 @@ |
|
|
|
|
|
|
|
Также модель имеет внутренние методы, необходимые для работы описанных ранее основных методов. Одним из них является метод _c_tf_idf, помогающий найти слова, которые максимально ясно описывают каждый из топиков, за счёт использования информации о других группах. То есть выделяются слова, которые имеются в документах одной группы, но редко или никогда не встречаются в документах других групп.
|
|
|
|
|
|
|
|
# 5 Описание модели "Личнный кабинет МИЭМ"
|
|
|
|
# 5.2 Описание тематической модели обработки данных Личнного Кабинета МИЭМ
|
|
|
|
Для составления оценок релевантности пользователей по данным сервиса «Личный кабинет МИЭМ» был разработан программный модуль, осуществляющий поиск по ключевым словам в проектных «вакансиях» студентов.
|
|
|
|
Работа модели основана на векторизации документов с использованием TF-IDF меры. Для этого данные в «вакансиях» проходят через несколько этапов обработки:
|
|
|
|
1) Токенизация (с учетом специальных символов);
|
| ... | ... | |