Hatena::ブログ(Diary)

備忘録-研究や勉強のメモ-

2011-03-09

tagged_words

「入門自然言語処理」素人の読み進めシリーズです。

p.476にて


genpaku_tfd = FreqDist(t[2] for (w, t) in genpaku.tagged_words())

と言う箇所。このままだと品詞タグがちゃんと表示されなかった。あれれ。tagged_words()メソッドで返ってくるlistの形式を調べてみると、

(   u'まずしい',
    u'マズシイ\tまずしい\t形容詞-自立\t形容詞・イ段\t基本形')
(u'王子', u'オウジ\t王子\t名詞-一般')
(u'さま', u'サマ\tさま\t名詞-接尾-人名')
(u'が', u'ガ\tが\t助詞-格助詞-一般')
(u'おり', u'オリ\tおる\t動詞-自立\t五段・ラ行\t連用形')
(u'まし', u'マシ\tます\t助動詞\t特殊・マス\t連用形')
(u'た', u'タ\tた\t助動詞\t特殊・タ\t基本形')

(w,t)のtにあたる部分ではタブ区切りで読み、原形、品詞1、品詞2と入っている。ってことは\tでsplitしてindex2にあたる品詞1を取り出して...

と考えて以下のコードでO.K. 本が書かれた時点とでコーパスの形式が変わってたのかな?まっいっか。

FreqDistはプログラムはじめでimport nltkしているのでnltk.FreqDistで呼び出す形式にしてみました。

genpaku_tfd = nltk.FreqDist(t.split('\t')[2] for (w,t) in genpaku.tagged_words())

genpaku_tfd.tabulate(10)

出力は、

助動詞 動詞-自立 名詞-一般 助詞-格助詞-一般 記号-読点 記号-句点 助詞-接続助詞 助
詞-係助詞 助詞-連体化 名詞-代名詞-一般
 350  335  305  240  132  125  123  117   82   66

ちなみに教科書では沢山のコーパスを読み込んでいますが、逐一読み込みの時間が掛かるので、g0005.chasenというものだけ読み込んでいます。適当に選んだけどこれは何の話だろう。。童話っぽいが。

jeitaディレクトリ内にあった_copyright.htmlより調べると、そのタイトルは、、

なんと「ブタ飼い王子」でした。聞いたことないな。作者はアンデルセン。息抜きに今度読もう。

正規表現

むむむ。。

str1 = u"\nいうえお"
str2 = u"\n"
if re.match(str2,str1):
    print "match!"
else:
    print "not match!"

これはちゃんとmatch!

しかし、

str1 = ur"あ\nいうえお"
str2 = ur"あ\n"
if re.match(str2,str1):
    print "match!"
else:
    print "not match!"

はnot match!になる。

さらにさらに

str1 = u"\nいうえお"
str2 = ur"あ\n"

はmatch,

str1 = ur"あ\nいうえお"
str2 = u"\n"

はnot match

原因究明中。これ理解したら家帰ろうっと。


追記 同日21:26

あんまりしっくりとした解釈までたどり着かなかったので、とりあえず以下のように今日は雑にまとめ。

正規表現のための文字列ではエスケープやメタ文字関係がごちゃっとするのでrをつけてrawで。マッチを探す方の文字列はごくごく普通に、rawを付けない。ruby正規表現使ってたときはこういうことで頭をひねった記憶が無いんだけどなぁ。。まあいっか。

list型とgenarator型

「入門自然言語処理」12章を読み進めております。

p.476にて、sum(len(w) for w in genpaku.words())という文にどうも違和感が。w for w in text みたいな構文はだいぶ見慣れてきましたが、[]で必ず左右を囲み、[w.lower() for w in text1]のようにしてlistの各要素に何らかの操作を施したlistを得る、っていう使い方じゃなきゃったけ?普通のカッコ()で囲まれている。。

しばし調べると

(len(w) for w in genpaku.words())はgeneratorクラス

[len(w) for w in genpaku.words()]はもちろんlistクラス

とこれらは別物です。

今の自分のレベルの理解では、generatorクラスとは、リストに似たリストもどきのようなもので、

sum(len(w) for w in genpaku.words())のように、複数の引数を取るsum等のメソッドと一緒に使うもの、と捉えました。

そういえばjoinの引数としてこのforの構文が出てきたときもたしかカッコ囲みのgeneratorクラスだったような、というかそうだ。

ちなみにsumやjoinは、generator,listクラスどちらでも引数に取ることもできるようです。

>>> ' '.join([n for n in ['a','b','c') #listクラスが引数

'a b c'

>>> ' '.join(n for n in ['a','b','c']) #generatorクラスが引数

'a b c'

下の方がすっきりしてます。

依存構造解析済みコーパス

入門自然言語処理、12章を読み進め中。p.475にて。文字コード関係のことで少し詰まったこと。

>>> print '\n\n'.join( '%s' % tree for tree in knbc.parsed_sents()[0:2] )

で出力するものが文字化けしてしまう。nltk.tree.Treeクラスとやらは%sに文字列として渡されるとき、shift-jis以外のエンコードで8ビット文字列となっていると見た。(windows環境なのでコマンドプロンプトではshift-jisで日本語を出力しないといけない)

すこし調べるとTreeクラスのインスタンス→文字列と変換するとエンコードが'utf-8'になっていた。以下のようにunicode文字列に逐一デコードするように変更

print '\n\n'.join(str(tree).decode('utf-8') for tree in knbc.parsed_sents()[0:5])

よし、文字化け修正完了。素人考えでutf-8の方がやっぱりpythonと相性が良いのかな、と思う。mac欲しい。shift-jisって名前はなんか垢抜けていないイメージ。

言語処理のための機械学習入門

参考書「言語処理のための機械学習入門」を昨日購入

言語処理のための機械学習入門 (自然言語処理シリーズ)

言語処理のための機械学習入門 (自然言語処理シリーズ)

言語処理に必要な数学の前提知識から解説されている。

純粋な数学の勉強は久々に感じて楽しい。しかし、マイナスで両辺を割ると不等号が逆になるという中学数学が何故か一時的に頭から消えたせいで簡単な公式と30分にらめっこをした。。