Clojureを使った自然言語処理

ウェブ技術 デジタルトランスフォーメーション技術 人工知能技術 自然言語処理技術 セマンティックウェブ技術 深層学習技術 オンライン学習&強化学習技術 チャットボットと質疑応答技術 ユーザーインターフェース技術 知識情報処理技術 推論技術  Clojure プログラミング

Clojureを使った自然言語処理について述べてみたい。

まず英語で一通りの処理を行うならclojure-openNLPapacheのopenNLPのラッパーで、「lein new my-app(任意のアプリ名)」で生成されたフォルダー中のproject.cljファイルの:dependencies部分に[clojure-opennlp “0.5.0”]を加えれば良い。あとはsrcフォルダーの中のcore.cljファイルで

(use 'clojure.pprint) 
(use 'opennlp.nlp)
(use 'opennlp.treebank)

で設定したopenNLPのライブラリを使えるようにして、http://opennlp.sourceforge.net/models-1.5からモデルファイルをダウンロードしてmodelファイル下にコピーし、コード内に設定。

(def get-sentences (make-sentence-detector "models/en-sent.bin"))
(def tokenize (make-tokenizer "models/en-token.bin"))
(def detokenize (make-detokenizer "models/english-detokenizer.xml"))
(def pos-tag (make-pos-tagger "models/en-pos-maxent.bin"))
(def name-find (make-name-finder "models/namefind/en-ner-person.bin"))
(def chunker (make-treebank-chunker "models/en-chunker.bin"))

これで、利用できるようになる。例えば単語分割(tokenize)は

(def tokenize (make-tokenizer my-tokenizer-model))
(pprint (tokenize "Mr. Smith gave a car to his son on Friday")) ["Mr.", "Smith", "gave", "a", "car", "to", "his", "son", "on",  "Friday"]

のようになる。関数としてはNER(named entity recognition)で名前を見つける「name-find」や品詞を見つける「pos-tag」単語の連なりを見つける「chunker」等がある。

日本語の場合は、検索エンジンであるlucineのJapaneseAnalyzer で形態素解析ができる。ライブラリとしてはjavaのライブラリを利用する。前述と同様にproject.cljファイルの:dependencies部分に[org.apache.lucene/lucene-analyzers-kuromoji “5.0.0”]を加えて、core.cljファイルに

(:import 
(org.apache.lucene.analysis.ja JapaneseAnalyzer JapaneseTokenizer)
(org.apache.lucene.analysis.ja.tokenattributes PartOfSpeechAttribute)
(org.apache.lucene.analysis.tokenattributes CharTermAttribute OffsetAttribute)
(org.apache.lucene.analysis.util CharArraySet))

を加える。形態素解析を行う関数としては以下を利用できる。

(defn morphological-analysis
[src]
(let [analyzer (JapaneseAnalyzer. nil
JapaneseTokenizer/DEFAULT_MODE
CharArraySet/EMPTY_SET
#{})
rdr (StringReader. src)]
(with-open [ts (.tokenStream analyzer "field" rdr)]
(let [^OffsetAttribute offsetAtt (.addAttribute ts OffsetAttribute)
^PartOfSpeechAttribute posAtt (.addAttribute ts PartOfSpeechAttribute)
_ (.reset ts)
surface #(subs src (.startOffset offsetAtt) (.endOffset offsetAtt))
pos #(.getPartOfSpeech posAtt)
tokens (->> #(if (.incrementToken ts)
[(surface) (pos)]
nil)
repeatedly
(take-while identity)
doall)
_ (.end ts)]
tokens))))

この関数を利用すると(morphological-analysis “テキスト文”)、入力したテキスト文を形態素解析した結果を得ることができる。

また、かかり受け処理まで行うにはJUMAN/KNPを利用することができる。こちらもClojureのラッパーが存在するが、イレギュラーな使い方としてプログラムからのターミナル操作を照会する。まずhomebrewでjumanとknpをインストール(brew install juman)(brew install knp)して、ターミナル操作をするライブラリは[me.raynes/conch “0.8.0”]を利用する。コードとしては、以下のようになる。

(:require [me.raynes.conch :as sh])

(defn juman-parse [s](sh/with-programs [juman] (juman {:in s})))

このようにして抽出した単語から、不要な単語を抜き出したり(stop-word除去)、ベクトル化(one-hot-vector)を行うことで機械学習が行えるようになる。シンプルな機械学習例としては、検索等で用いられるtfidfを使った単語の頻度抽出等がある。

次回は機械学習技術について述べてみたい。

コメント

  1. […] 次回は、これらの中からいくつかのツールを実際に利用するケースを紹介したい。 […]

  2. […] またClojureやpythonのラッパーもありそれらからの利用と可能となる。 […]

  3. […] Clojureを使った自然言語処理(1) OpenNLP,kuromiji,jumanの紹介 […]

  4. […] 繰り返し処理と再帰 C,Java,Javascript,Pythonとの比較とmap,looprecur […]

タイトルとURLをコピーしました