StanfordCoreNLP является золотым стандартом в обработке языков и достаточной причиной для всех, кто серьезно занимается обработкой естественного языка, вычислительной лингвистикой или анализом текста, рассмотреть язык JVM. В этом руководстве рассказывается, как настроить и запустить минимальную функцию синтаксического анализа StanfordCoreNLP с помощью Clojure, функционального Lisp для JVM.
Настраивать
Поскольку StanfordCoreNLP — это не один .jar
файл, а целый их набор, я рекомендую использовать для этого проекта lein-resource-expand. Это позволяет вам указать каталог, в котором расположены все файлы StanfordCoreNLP .jar
, и использовать нотацию glob (например: mypath/CoreNLP/*.jar
), чтобы выбрать их все. В противном случае первым шагом будет добавление файлов StanfordCoreNLP в путь к ресурсам.
В Лейненгене это выглядит примерно так:
(comment with resource expand!) :resource paths ["mypath/myjars/stanford-corenlp-full-2018"]
Первые шаги
После того, как вы настроили проект и .jars на своем пути к ресурсам, пришло время запустить CoreNLP.
Подход CoreNLP заключается в настройке конвейеров анализа, а затем применении этих конвейеров к аннотациям. Итак, наша задача — перенести эти классы Java в Clojure.
Для этого нам просто нужно инициировать класс StanfordCoreNLP с некоторыми свойствами, указывающими, какие аннотации применять.
(def myProps (java.util.Properties.)) (. myProps setProperty "annotators" "tokenize, ssplit, pos") (def nlPipe (edu.stanford.nlp.pipeline.StanfordCoreNLP. myProps))
Здесь мы создали свойства myProps
, настроили их для обработки токенизации, разделения предложений и тегов частей речи — здесь доступен полный список аннотаторов — и использовали их для запуска nlPipe
, нашего конвейера НЛП.
Затем для анализа текста мы просто создаем объект аннотации и аннотируем его с помощью нашего конвейера nlPipe
.
(def sentences (edu.stanford.nlp.pipeline.Annotation. "I'll meet you by the Sample Gates. Do you know where that is?")) (.annotate nlPipe sentences) (.jsonPrint nlPipe sentences *out*)
Если вы зашли так далеко, вы должны увидеть кучу JSON, напечатанных в вашем терминале. Мы сказали конвейеру аннотировать наш объект аннотации и распечатать результаты в JSON. Если вы не хотите, чтобы ваши данные были в формате JSON, вы можете ознакомиться с документацией о том, как вернуть эти данные различными способами.
Становимся более функциональными
Возможно, это был быстрый и простой способ обработки текста, но он не был функциональным. Кроме того, мы не хотим, чтобы наши данные находились в терминале, мы хотим, чтобы они были в формате, который мы можем передавать внутри Clojure. Давайте создадим обертку, чтобы сделать все это.
(defn pipe2JSON [pipeline t] (let [txt (.process pipeline t)] (let [buffer (java.io.StringWriter.)] (.jsonPrint pipeline txt buffer) (json/parse-string (.toString buffer)))))
А затем давайте продемонстрируем это, распечатав теги части речи для первого предложения:
(let [a (pipe2JSON nlpipe "I'll meet you by the Sample Gates. Do you know where that is?") ] (println (map (fn [x] (get x "pos")) (get (get (get a "sentences") 0)"tokens"))))
Здесь наша функция pipe2JSON
берет конвейер и применяет его к строке, JSON-печатает эту строку в объект, который мы затем превращаем в знакомый Clojure PersistentArrayMap.
Более…
StanfordCoreNLP имеет гораздо больше возможностей, чем описано здесь. Если вы анализируете скромные объемы данных, этого должно быть достаточно; если вы хотите заниматься продвинутым НЛП или НЛП в большем масштабе, прочтите документацию. Хорошее место для начала — понимание класса StanfordCoreNLP.
Код этого руководства доступен на моем GitHub
Первоначально опубликовано на www.jtwolohan.com.