2011年2月27日日曜日

WhooshのTokenizer追加

IgoTokenizerに加えて
  • TinySegmenterTokenizer
  • MeCabTokenizer
を追加しました。

さらに、FeatureFilter(素性フィルタ)の追加と、IgoのTaggerをインデックスに保存しないモードを追加しました。

使い方
tk = WhooshJapaneseTokenizer.IgoTokenizer(igo.Tagger.Tagger('ipadic'))
tk = tk | WhooshJapaneseTokenizer.Filters.FeatureFilter([u'^助詞,係助詞.*$'])

IgoのTaggerをpickleする

MeCabTokenizerを作っているときに、またpickle出来なくてはまった。なので、独自に保存/復帰をするようにした。
そのとき、WhooshでIgoTokenizerを使うとインデックスが思った以上に大きくなる原因にやっと気が付いた。Taggerをインデックスに保存するのが原因。
そこで、IgoのTaggerも独自に保存復帰が出来るようにした。

# coding:utf8
import cPickle,gzip
import WhooshJapaneseTokenizer,igo.Tagger
tk = WhooshJapaneseTokenizer.IgoTokenizer(igo.Tagger.Tagger('ipadic'))
tk2 = WhooshJapaneseTokenizer.IgoTokenizer(dataDir='ipadic', gae=False)

print 'w tagger', len(cPickle.dumps(tk, -1))
print 'wo tagger', len(cPickle.dumps(tk2, -1))
tk = cPickle.loads(cPickle.dumps(tk, -1))
tk2 = cPickle.loads(cPickle.dumps(tk2, -1))

for t in tk(u'今日はいい天気です。'):
  print t.text,
print
for t in tk(u'今日はいい天気です。'):
  print t.text,
print

出力
$ python test2.py 
w tagger 41185761
wo tagger 119
今日 は いい 天気 です 。
今日 は いい 天気 です 。

これを逆手に取れば、Taggerをpickleしておけば、辞書が無くてもTaggerを作ることが出来る。
>>> import igo.Tagger, cPickle, gzip
>>> from cStringIO import StringIO
>>> cPickle.dump(igo.Tagger.Tagger('ipadic'), gzip.GzipFile('/tmp/tagger.gz', 'w'), -1)
>>> cPickle.load(gzip.GzipFile('/tmp/tagger.gz'))
<igo.Tagger.Tagger instance at 0x7f24f71c9a28>
これで大体8.4Mぐらい。

2011年2月21日月曜日

WhooshのTokenizerを作るときにはまったこと

TinySegmenterTokenizerを作っていたときにはまったこと。

WhooshではSchemaがインデックス内にpickle化されて保存されるので、Schemaを作るときに指定したTokenizerもpickle化出来ないとエラーになります。

コンストラクタで
def __init__(self, strip):
    if strip:
        self.strip = unicode.strip
    else:
        def strip(s):
            return s
        self.f = strip
等とやっていてはまりました。

データを作ったTokenizerがセットで保存されているのは良いと思うのですが、インデックスを複数のPythonのバージョンで共有できるのか気になります。そのうち試す…

はまったことではありませんが、pythonのunicode.stripは全角スペースやNBSPなども除去してくれる優れものであることが分かりました。

Whoosh用の日本語トークナイザを追加(TinySegmenterTokenizer)

辞書なしで使えれば手軽だと思ったので、TinySegmenter版も作りました。

PyPI whoosh-igo(パッケージ名とりあえずそのまま)
Launchpad Japanese Tokenizers for whoosh/

モジュール名(IgoTokenizer)がちょっとカバー範囲が広すぎると思ったので、
Tokenizerを追加したついでに、WhooshJapaneseTokenizerに変更しました。
長いけどこれならぶつかる可能性が減ったはず…

2011年2月19日土曜日

Whoosh用の日本語トークナイザ(IgoTokenizer)

Python hack-a-thon 2011.02の成果。

Igoを使って、Whoosh用のTokenizerを作りました。とりあえずですが使えます。
https://launchpad.net/igotokenizer

テストコード
# -*- coding: utf-8 -*-
import os
from whoosh.index import create_in
from whoosh.fields import *
from whoosh.qparser import QueryParser

import igo.Tagger
import IgoTokenizer

tk = IgoTokenizer.IgoTokenizer(igo.Tagger.Tagger('ipadic'))
scm = Schema(title=TEXT(stored=True, analyzer=tk), path=ID(unique=True,stored=True), content=TEXT(analyzer=tk))

def add_docs(w):
    w.add_document(title=u'その1', path=u'1', content=u'こんにちは世界')
    w.add_document(title=u'その2', path=u'2', content=u'さようなら世界')
    w.commit()

def search(s, qp, text):
    print 'search ' + text
    for r in s.search(qp.parse(text)):
        print r['path'], r['title']

if not os.path.exists("indexdir"):
    os.mkdir("indexdir")
ix = create_in('indexdir', scm)
w = ix.writer()
add_docs(w)

s = ix.searcher()
qp = QueryParser("content", schema=ix.schema)

search(s, qp, u"こんにちは世界")
search(s, qp, u"世界")
search(s, qp, u"こんにちは")
search(s, qp, u"さようなら")

実行結果
search こんにちは世界
1 その1
search 世界
1 その1
2 その2
search こんにちは
1 その1
search さようなら
2 その2

2011年2月14日月曜日

Compose key in X11(Debian GNU/Linux)

Debianといいながらaptosidだが…

VMのOSを64bit化するため、新しいVMをつくってaptosid-xfceの64bit版を入れた。
作業は、xfceからlxdeへの変更と、一通りパッケージを入れたところで、古いVMのhomeをコピーするだけで終了。
ついでにbtrfsにしようかと思ったけど、インストーラーで選べなかったのでやめた。


で、今回の本題。前は特にいじった記憶がないのだが、Windows KeyがSuper_Lとして使えなくなり、awesomeが(そのままでは)使い物にならなくなった。もしかしたら、前回はsidux-kdeからスタートしたからその影響かも知れない…

xevでみると、keycode=133で正しいコードが上がってくるけど、multi_keyになっていた。Xのログを見ると設定してないのに、xkboptionsが設定されているので、設定値から検索すると/etc/default/keyboardで設定されていた。

XKBOPTIONS="lv3:ralt_switch,compose:lwin"

確かにleft windows keyがcomposeキーになる設定になっている。前の設定を見ると

XKBOPTIONS="compose:rctrl"

だった。ただ、rctrlはVMのHostキーに割り当てているのでcomposeキーがなんだか分からないけど、なんか気分が良くないので、menu keyに割り当てるようにした。

XKBOPTIONS="compose:menu"

これでwindowsキーがSuper_Lになって、awesomeでもlxde(Win-R,Win-Eとか)でも問題なくなった。

ついでにcompose keyについて調べたら、使い道が分かった。綴り字記号とかで使うものらしい。
compose + ' + a = á
compose + " + a = ä
compose + ` + a = à
compose + , + c = ç
compose + ' + e = é
compose + ^ + e + ê
compose +` + e = è
compose + ? + ? = ¿