Как стать автором
Обновить

Комментарии 28

Было бы ещё неплохо pom.xml добавить к проекту, чтобы прямо после чекаута кода можно было собрать проект.
Я не использовал Maven для этого проекта, но вот тут уже есть форк с необходимым вам файлом pom.xml.

P.S.: надо бы и к своему проекту прикрутить Maven. Займусь.
Добавил поддержку Maven. Файл pom.xml доступен на Github.
Палец вверх за Java. Посмотрите ещё в сторону deeplearning4j и word2vec (в том же deeplearning4j есть реализация). Последний даст прирост и по точности и по скорости, если хватит данных для обучения. И не надо будет словарь синонимов прикручивать. Тем более, что это неэффективно для тематических текстов.
Я изначально взял в качестве реализации нейронной сети именно deeplearning4j, но только создание сети с несколькими тысячами нейронов во входном и скрытом слоях длилось более получаса на очень неслабой машине. конечно, может быть стоило глубже поковыряться в параметрах, но я решил сменить фреймворк на Encog, у которого из коробки не было проблем со производительностью — на нем и остановился.
Вы сказали что не будете искать готовых решений(к слову, почему?), но тем не менее уже взяли некоторые существующие подходы.

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

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

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

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

Плюс за статью.
Так как критика приветствуется, имею следующее:
посмотрел код в пакете com.irvil.textclassifier.dao.jdbc; Сложилось впечатление, что код написан небрежно, где-то sql ошибки глотаются, где-то на консоль пишутся, con.commit есть, а con.rollback нет (правда может в SQLite jdbc драйвере это поведение по умолчанию), результаты операций не проверяются, с con.setAutoCommit нужно работать аккуратнее и много чего ещё. В общем, если проект будете развивать то рекомендую такие огрехи зачищать сразу.

Принято. Проведу детальный анализ и внесу правки.
Позвольте заметить, что вместо SQLite можно использовать H2db. Я пару лет назад её пробовал, и с Java-кодом она работала быстрее, чем SQLite. Возможно это от того, что нет оверхеда Java <-> JNI.
Да, я про H2 уже думал, у меня это даже записано в TODO. Она действительно должен быть быстрее.
Добавил поддержку H2.
Попробовал из " но вот тут уже есть форк" попробовать что то — никаких членораздельных результатов увы не получилось. Есть возможность как то дочистить тот самый форк, что бы можно было на данных чуть пообширнее чем 3 строчки это потестить?
Я добавил поддержку Maven в свой проект, поэтому теперь можно взять за основу его, а не форк. На каком конкретно этапе у вас возникли проблемы и какого они рода?
С мавином лучшче! Так вот:
1) git clone https://github.com/RusZ/TextClassifier.git
2) ubuntu
3) Java version: 1.8.0_111, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-8-oracle/jre
4) start MainWindow

Storage created. Wait…
Vocabulary is null or empty
'Characteristic 2' characteristic saved. Wait…
'Characteristic 1' characteristic saved. Wait…
Classifiable texts saved. Wait…
java.lang.IllegalArgumentException


Есть констольный вариант для «попробовать»? Винду ставить для хеллоуворда ка кто не охота.
У вас слишком маленький объем обучающих данных. Настолько маленький, что не выполняется требование, что униграмма должна встречаться хотя бы в 4 разных текстах — только в этом случае она добавится в словарь. В вашем случае словарь пустой. Вам нужно хотя бы 100-200 обучающих текстов даже для «попробовать».

А зачем вам винда? Скомпилироваться и запуститься должно в любой системе. Если проблема в подготовке XLSX-файла, то тут Google Docs в помощь.
А насколько сложно «обучающие данные» включить в уже существующий проект?

Я «загружаю» прилагаемый "/TextClassifier/test_db/test.xlsx", который, как я понял запрашивает оконное приложение при первом старте. Вот в этом то файлике данных и маловато. При моей попытке «набить хотя бы 100-200 текстов» прога тупо зависает на пару часов, и…
… дальше помогает только килл процесса :(

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

Файл test_db/test.xlsx используется в JUnit-тестах и служит для тестирования модуля считывания Excel-файла. Его использовать в качестве обучающих данных не нужно.

При моей попытке «набить хотя бы 100-200 текстов» прога тупо зависает на пару часов

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

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

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

ЗЫ
я убил пару часов что бы:
— прочитать
— понять
— скачать\скомпилить\прикрутить мавен с депетденси\
— подождать пока научиться…
— три дня дискуссии в хабре

ЗЫЗЫ
«машина» не медленная :)

Результат:
— кроме как на наборе данных из (!) одного это работает правильно и только в JUnit. Больше позитивных результатов не получилось :(

Вывод
— в корзину. Спасиба за помощь и радушие! :)
И Лена больше не нужна! :3
А не думали для повышения точности сделать многослойную модель? Например, на первом слое данные проходят через нейронную сеть, наивный байесовский классификатор, логистическую регрессию, k-means с количеством соседей равным и большим в 2 раза исходное количество классов. А на втором слое, какой-нибудь градиентный бустинг по данным предсказанным на первом слое.
Иногда используют комбинацию нескольких классификаторов. Правда, не такую сложную, как вы описали. Но это дает несущественный прирост производительности по сравнение с затраченными усилиями на разработку. Есть смысл с этим заморачиваться, если твоя программа будет соревноваться с другими и 1-2% к точности могут обеспечить победу.

Лучше выбрать какой-то один классификатор и направить силы на увеличение его точности. В многослойной модели, скорее всего, все упрется в бутылочное горлышко — самый неточный слой будет портить общую картину.
Правильно ли я понимаю, что результат классификации зависит только от количества определенных слов в тексте и не зависит от их порядка?
Результат классификации зависит не от количества, а от наличия в анализируемом тексте слова (точнее сказать, фрагмента) из словаря. Если использовать биграммы (или триграммы) вместо униграмм, то частично будет учитываться и порядок следования («Я люблю вкусное мороженное» --> [«я люблю», «люблю вкусное», «вкусное мороженное»]). Для использования биграмм в конфигурационном файле программы нужно сменить параметр ngram_strategy с filtered_unigram на bigram или filtered_bigram.
Есть идея, добавить во входные данные больше информации о тексте. Причем данные о тексте могут быть абсурдно бессмысленными — количество слов/символов, факт наличия определенных знаков препинания (вопрос, воскл.знак, точка, запятая, двоеточие и т.п.), расстояние между знаками препинания (можно разработать несколько метрик — типа мин/макс, и видов — межу точка/вопрос/воскл. — определяет длину предложений, и т.п.), использование 'ё', наличие иностранных слов или только русских и т.п.

Точно помню, при исследовании анализа авторства текстов вылезали такие странные закономерности что диву даешься (не мое, чужой диплом очень очень давно).
Где-то на киберленинке была работа об определении авторства произведения (минимум 1000 знаков нужно).
Т.е. задача такого типа: Есть неизвестный ранее текст. Надо определить: этот текст написан Л. Толстым, или кем-то другим?
Так вот, там предлагались метрики:
  1. Длина предложения;
  2. Состав частей речи (т.е., сколько существительных, прилагательных, глаголов и пр..)
  3. Наличие редких (не используемых в обычной разговорной речи) слов.

Авторы утверждали, что точность такого набора метрик более 90%.
Хотелось бы увидеть как будет себя вести со сверточной сетью.
Что с учетом положения слов в тексте?

ПС. При считывании значений ячеек экселя наверное лучше использовать .toString() вместо типизированных методов ожидающих конкретный тип ячейки
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории