gensimでLDA(Latent Dirichlet Allocation)

トピックモデルを試そうとgensimのLdaModelを使ってみたのですが、参考にした記事「LSIやLDAを手軽に試せるGensimを使った自然言語処理入門」は対象とするgensimのバージョンが古いようだったので、現状にあうようアレンジして試してみました。この記事で使ったgensimのバージョンは0.11.1です。 過去のgensimと今のものとでは、メソッド名等の命名規則が変わっています。旧来はcamel caseでしたが、今は小文字とアンダースコアの組み合わせになっています。たとえばnumTopicsという名前付き引数はnum_topicsに変わっています。 それ以外にも多少の違いはあるのですが、yuku_tさんのgistのコードを今のバージョンのgensimで動くように修正したのが以下になります。 WikiCorpusクラスにはsaveAsTextと等価なメソッドが今は存在しないので、個別にDictionaryとCorpusをファイルに出力しています。 生成されたモデルをもとにLSI, LDAモデルを作成する流れは、メソッド名等を(たとえばPrintTopic→print_topic)書き換える点以外は元記事とほぼ変わりません。 また、LDAモデルの生成をマルチコアで実施するgensim.corpura.LdaMulticoreというクラスも用意されています。worker=2等とワーカースレッド数を指定できる点以外はLdaModelクラスと同じです。しかし、あまりよくスケールするわけではないようで、CPU論理コア数8の環境でworker=7としてみても対して速度が上がることはないようです(参考:Multicore LDA in Python: from over-night to over-lunch)。一応workerプロセスは指定しただけ起動はするのですけど。加えてマルチコアで処理した場合、出力されるログが少なくなって進捗状況がわかりづらくなるようです。 ところで以前書いたword2vecの記事でgensimのword2vecでのマルチスレッド動作について書いていなかったので、同様にworkerスレッド数を指定できることを追記しておきました。 また、Google C言語実装のword2vecのマルチスレッド処理について一つだけ気になるところがありました。それは、単純にファイルをバイト単位でスレッド数に分割し、処理している点です。単語の区切りを一切考慮しないので、その箇所がたまたま単語の途中であってもお構いなしに処理を進めてしまいます。 もっとも、出現頻度の少ない単語は捨てられるので、実用上問題になることはほとんどないはずではあります。運悪くUTF-8の途中で切られてしまい、なおかつ語彙として記録されてしまうと、gensimで読み込もうとするときにInvalidUnicodeErrorが発生してしまうので、その点だけは気を付ける必要があります。

Published
Categorized as その他

LanguageToolで長音記号チェック

漢字変換ミスで、たまに長音記号がかな文字以外の後に置かれる事例を見かけたので、それをLanguageToolのルールにして取り込んでもらいました。 現状ある日本語のルールをざっと見たのですが、うまい具合に表現する方法が思い浮かばなかったので、思い切ってメーリングリストで聞いてみました。 メイン開発者のDanielさんは親切で反応も早い方で、「正規表現でUnicodeの範囲を使えばできる」という方法を示してくれました。また、過去にも日本語のルールを書いているSilvanさんからは、JavaにおけるUnicodeのクラス表現(\p{IsXxx})を紹介してくれました。 これらを踏まえ、以下のようなルールをpull requestとして書き、無事masterにマージしてもらえました。 カタカナとひらがな以外が長音記号の前にあるとき、LanguageToolは警告を出します。 この機会に、Doc-ja Wikiの”LanguageTool使い方メモ“も若干修正しました。自前のgrammar.xmlを指定して起動する方法と、ソースコード上で変更をしたときにルールのテストをする方法について新た説明を加えています。 LanguageToolのリリースバージョンは現在2.9ですが、次期バージョン3.0ではgrammar.xmlの書式も変わっているため、いずれWiki内の説明もそちらに合わせて修正したいところです。

pyroongaの挙動

GroongaをPythonから扱うのにpyroongaを使ってみたのですが、いくつかハマリポイントがありました。 Groonga serverが必要 rroongaは単独で動作するのに対して、pyroongaはGroongaがserverとして起動している必要があります。 カラム名が予約語だとハマる pyroongaはテーブル名をクラス名に、カラム名をアトリビュートにマッピングして動作します。したがって、”from”などの予約語がカラム名だとうまく動きません。あまりPythonには詳しくないのですが、これを回避する方法は思いつきませんでした。 複数語のクエリで期待した結果が返ってこないことがあある いまいち原因がわからないのですが、”foo bar”というようなクエリをコマンドから与えた時に得られる結果と、queryメソッドで同じクエリを与えた時の結果が異なります。ちょっとよくわかりません。 対処: subprocess呼び出し 非常にダサい方法ではありますが、pythonからgroongaコマンドを直接呼び出すことで期待する結果が得られるようになりました。 これで期待通りの結果が得られるようになりました。 追記(2015/0512) ロケールが設定されてない環境(CGIなど)でqueryがunicode文字列の場合、引数をきちんとUTF-8でencodeしてやる必要があります。でないと、UnicodeEncodeErrorが発生します。私はこれで数時間悩みました。

Published
Categorized as 開発