Поисковик абзацев текстов схожих с искомых. Кластеризация абзацев

Здравствуйте, уважаемые читатели блога о контент-анализе!

Закончил работу над новой программкой на JAVA — программка сугубо учебная (пару дней назад закончился третий месяц моего изучения JAVA и по сути — вообще программирования), полезностью, вероятно, особой не обладает, но если вы найдете ей применение — отлично. Программка позволяет ввести в поиск фрагмент текста и найти все похожие на него фрагменты. Также она позволяет кластеризовать по темам все абзацы загруженных текстов.

ff

Скачать ее можно ТУТ. Для запуска надо установить JAVA, если она еще не установлена и далее запустить файл FindFrags.jar — или двойным кликом или через командную строку командой: java -jar FindFrags.jar, находясь в нужном каталоге или задав путь до файла jar.

Итак, запустили файл и видим следующий интерфейс, предлагающий указать конфигурационные данные для программы:

ff

Как это видно на картинке, программа использует базу данных. Конкретнее — MYSQL. В этой связи предварительно потребуется установить сервер MYSQL и создать саму базу. Как это делается на примере другой моей программки, можно почитать ЗДЕСЬ.

Далее необходимо импортировать словарь (он нужен для лемматизации слов корпуса текстов). Импортировать словарь (да в общем и все остальные таблицы (прошу прощения, уже с некоторыми данными, которые стоит стереть после импорта или использовать как демо)) можно с помощью этого дампа SQL.

Вот все таблицы, которые потребуются для работы. В дампе может быть лишняя таблица, можно ее просто проигнорировать. Структура БД такая:

ffТеперь структура таблиц:

ff

Ну то, что выше, в общем для работы с программой не особо актуально. Записал себе на память 🙂

Вводим в поля учетные данные пользователя БД, название БД, наименования таблиц из БД (raw_data — для исходных загружаемых пользователем текстов, frags — для фрагментов текстов, indexed_data — для результатов индексирования корпуса, morf_dict — словарь словоформ.

Если вы хотите задать свои названия таблиц и создать их (а также проверить, не присутствуют ли уже в БД таблицы с такими названиями, то это можно сделать на вкладке БД).

ffМожете ввести в первое поле название таблицы и проверить — есть ли такая таблица в БД. В общем появится окошко с уведомлением. Аналогично с созданием таблиц. Само собой, действуют правила именования таблиц для MYSQL.

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

ff

Теперь нам надо проиндексировать весь корпус текстов. Переходим на вкладку КОРПУС.

ff

Индексация работает только на основе лемматизатора. Стеммер я не стал делать. В следующих проектах индексацию/кластеризацию буду делать через Lucene/Solr, OpenNlp и пр, а уже там будут и лемматизаторы и стеммеры.

Суть лемматизации в этой программке такая: система токенизирует каждый из текстов. Каждое слово ищет в списке стоп слов (не стал его расширять до нужного размера, просто потому что это проект очень и очень учебный) — если слово там находится, то ему присваивается индекс 0. Если нет — слово ищется в словаре. Если там оно не находится — индекс 0, если находится, то индекс будет равен id этого слова в словаре. У каждой из словоформ одной леммы один и тот же id. У разных лемм — разные id.

Далее id текста, номер параграфа, номер слова в тексте, id слова и само слово записывается новой строкой в таблицу indexed_data. Дальше индексируется следующее слово и так — весь корпус. Поэтому индексация занимает некоторое время (значительно, прямо скажем). Для тестирования программки, думаю, стоит взять среднего размера текстов 15 из СМИ. Это минут на 5-10 индексирования. Конечно же, это зависит и от мощности компьютера.

Когда тексты будут проиндексированы, появится уведомление.

Посмотрим сами тексты. Кликнем по кнопке ПОКАЗАТЬ КОНТЕНТ. Появится первый текст корпуса. Как видно на скриншоте, с помощью навигатора можно посмотреть все тексты, передвигаясь к следующему/предыдущему. Тут же можно удалить все тексты и удалить результаты индексирования.

ffНа скриншоте видно, что мы выделили небольшой фрагмент текста. Похожие на него фрагменты мы будем искать во всём корпусе текстов. Скопируем фрагмент (ctrl C) и вставим на вкладке ПОИСК в поле для фрагмента текста. Найденные фрагменты будут записаны в таблицу frags. Однако, они должны соответствовать ряду условий: 1.Релевантность найденного фрагмента по отношению к исходному должна быть не ниже задаваемой пользователем величины от 0 до 1. По умолчанию это 0.1. Релевантность считается как отношение количества уникальных (дубли не имеют значения) слов общих для обоих фрагментов (исходного и найденного) к средней длине обоих фрагментов (длина = уникальные слова фрагмента, имеющие ненулевой индекс). 2. Можно задать минимальную и максимальную разницу в объемах исходного и найденного фрагментов. Здесь не стоит устанавливать огромные значения. По умолчанию в обоих случаях — это 3.

Нажмем кнопку ИСКАТЬ ФРАГМЕНТЫ. Начнется поиск, по завершении которого появится окно с уведомлением.

ffПосмотрим, что было найдено в результате поиска — перейдем на вкладку ФРАГМЕНТЫ. Здесь можно указать, сколько фрагментов вы хотите увидеть (вверху будут наиболее релевантные результаты) и какова будет минимальная релевантность для отображения. Кликаем на кнопку ПОКАЗАТЬ.

ffПервый найденный абзац — это сам исходных фрагмент. релевантность не 1 — это косяк… Но зато так быстрее работает 🙂

Найденные фрагменты мы можем экспортировать в XLSX, нажав соответствующую кнопку. Нажмем. В корневой папке программки появится файл frags.xlsx. Откроем его.

ff

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

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

Идем дальше. Вкладка КЛАСТЕРИЗАЦИЯ. Здесь можно ввести минимальный коэффициент схожести абзацев для включения их в один кластер. Алгоритм такой — сопоставляются массивы уникальных id слов каждого из абзацев с каждым из абзацев(кроме 0). Если коэффициент их похожести (рассчитывается так же как релевантность в алгоритме поиска, описанная ранее) больше указанного значения, то абзацы помещаются в один кластер. При этом в разных кластерах могут быть одинаковые абзацы.

ff

Посмотрим, что получилось. Кнопка ПОКАЗАТЬ РЕЗУЛЬТАТ.

ff

Ниже другой кластер (строго говоря, я взял очень удобный для кластеризации корпус — в нем 12 публикаций на 2 темы из СМИ)

ff

Всего у нас 24 кластера. Можно сократить их количество — кнопка СОКРАТИТЬ КОЛИЧЕСТВО КЛАСТЕРОВ. Запустится алгоритм, который будет сопоставлять содержания кластеров между собой. Если отношение количества общих параграфов для двух сравниваемых кластеров выше чем значение, вводимое пользователем в поле (используется то же самое поле — на этом этапе можно менять значение), то кластеры объединяются. Так можно провести повторную кластеризацию в несколько итераций. Я решил не делать цикл, а дать пользователю возможность кластеризовать кластера столько раз, сколько он сочтет нужным сам. Жмем. У нас осталось всего 9 кластеров.

ff

Как мы видим, результаты кластеризации можно экспортировать в XLSX. Файлик clusters.xlsx появится в корне программы. Откроем его.

ff

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

Кластеризацию текстов решил не делать — всё это для lucene/solr, open nlp и пр пр пр пр пр.

На последней вкладке указано подробнейшее описание программы и авторы.

ff

Ну и небольшой PS: у программки некоторые проблемы с большими объемами данных. Не стоит загружать в нее больше ста текстов (объем — 100 средних статьей СМИ). Иначе под Windows программка начинает материться ошибками уже при индексации корпуса. Под линуксом почему-то не ругалась при индексации 250 публикаций. В общем ей не хватает памяти, так что, если захотите потестить — наверное, лучше это делать на небольших массивах.

Может быть этот обзор наведет вас на какие-то мысли. Буду рад, если вы их укажите в комментариях.

Напомню, что это просто учебная программка — нее более того.

Для тех, кто как и я только недавно начал изучать программирование, — это пример того, чему можно научиться за 3 месяца неспешного изучения JAVA + несколько месяцев опыта процедурного PHP, чуть-чуть MYSQL и MS SQL, чуть-чуть HTML и CSS (которого тут само собой вообще нет). То есть это немного, но уже что-то. Кому-то покажется, что это совсем ничего, кому-то покажется что вроде норм, а кому-то збс 🙂

Дальше, видимо, сделаю перерыв в написании программок. Надо изучить груду литературы по основам того, основам сего в программировании и только потом приступать к новым проектам. Надеюсь как можно скорее приступить к работе над веб приложением для QDA (качественного анализа данных). Хочу начать максимум через пол года. Попутно делать что-то простое в Natural Language Processing на JAVA.

P.S.S. Если кому нужны исходники — они ТУТ. Гитхабом пользоваться еще не учился 🙂

Бай!

 

 

Print Friendly, PDF & Email

Автор

Алексей Рюмин

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