cheburechko / snippets

Yandex.Crypta internship test assignment

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

snippets

Тестовое задание на стажировку в Яндекс.Крипта

Программа тестировалась на Linux Mint 18 c GCC 5.4.0.

Для сборки есть Makefile

  • make - собирает программу в файл main
  • make debug - то же самое с флагом -g и дополнительным выводом слов в terms.txt, сниппетов в snippets.txt.
  • make clean - очистить папку от *.o и main.

Алгоритм работает следующим образом:

  • Файл полностью считывается в одну строку.
  • Текст парсится классом Parser, тот наполняет следующие коллекции:
    • SnippetStorage - вектор объектов Snippet. Snippet - строка сниппета предпосчитанными TF, TF-IDF для всех слов в нём (строка SnippetTermFrequency). Строка сниппета состоит из предложений - строк оканчивающихся на [.?!]. В сниппете лежит не менее 15 слов, параметр можно настраивать в main.cpp.
    • TermDatabase - unordered_map где ключи слова, значения - объекты TermData. TermData содержит в себе все индексы всех сниппетов, в которых содержится данное слово, отсортированные по убыванию TF-IDF этого слова в данном сниппете.

TF вычисляется как доля данного слова в сниппете, IDF - как обратная доля данного слова во всём документе, TF-IDF - их произведение.

Слова - строки, не содержащие ASCII знаков пунктуации и whitspace. Английские ASCII символы приводятся к нижнему регистру, какие-либо иные варианты кодировок не учитываются и используются "как есть".

  • Запросы из stdin передаются в SnippetEngine
    • Запрос разбивается на неповторяющиеся слова, для каждого из них извлекаются TermData.
    • У каждого из TermData берутся итераторы на отсортированные сниппеты, по ним вычисляется bestPossibleScore как сумма TF-IDF с начальных итераторов.
    • Итераторы складываются в termRank - отсортированный map по TF-IDF сниппета, на который смотрит итератор
    • Далее идёт цикл:
      1. Выбирается итератор с лучшим TF-IDF
      2. Если сниппет в итераторе уже рассматривался, переходим на шаг 4
      3. Для сниппета вычисляется оценка как сумма TF-IDF по всем словам запроса, лучший сниппет обновляется.
      4. Итератор пропускает все сниппеты, которые были ранее рассмотрены.
      5. Обновлются termRank и bestPossibleScore.
      6. Если bestScore >= bestPossibleScore, цикл завершается.

Есть опция useMostMatches, с которой рассматриваются только сниппеты с максимальным количеством совпадений со словами из запроса, т.е. программа будет стараться доставать сниппеты, имеющие как можно больше слов из запроса. Это улучшает качество сниппетов, но и увеличивает время работы с 1-10 мкс до 100-1000 мкс. (на файле 1МБ). Параметр также настраивается в main.cpp, по умолчанию включён.

About

Yandex.Crypta internship test assignment


Languages

Language:C++ 97.9%Language:Makefile 2.1%