White scenery @showyou, hatena

If you have any comments, you may also send twitter @shsub or @showyou.

libsvm

細かいことはあとでかく。というか公開するのに直す部分が多すぎる気が・・

textArrays = [
[ [ u"おはよう", u"ござい", u"ます" ], 1],
[ [ u"おはよう", u"ござい", u"なのよ"], 1],
[ [ u"こんばんわ", u"なのよ"], -1],
[ [ u"おはよう", u"ー"], 1]
]

testTexts = [
[ [ u"おはよう", u"ござい" ], 0],
[ [ u"こんばんわ", u"ー" ], 0]
]

[ [ [1, 1, 1], 1], [ [1, 1, 0, 1], 1], [ [0, 0, 0, 1, 1], -1], [ [1, 0, 0, 0, 0, 1], 1] ]
[ [ [1, 1, 0, 0, 0, 0], 0], [ [0, 0, 0, 0, 1, 1], 0] ]
([1, 1, -1, 1], [ [1, 1, 1], [1, 1, 0, 1], [0, 0, 0, 1, 1], [1, 0, 0, 0, 0, 1] ])
.*.*
optimization finished, #iter = 10
nu = 0.037483
obj = -0.750000, rho = -0.000152
nSV = 3, nBSV = 0
Total nSV = 3
[ [1, 1, 0, 0, 0, 0], 0] : 1.0
[ [0, 0, 0, 0, 1, 1], 0] : -1.0

*

まず、イメージとしては挨拶のやりとりをする際に、出てきた文章AがカテゴリC1(例えば「朝の挨拶」)に属すかどうか判定したい。ただいきなり文章Aと言ってもそのまま渡されても何がなんだか・・なので、入力した文章をベクトルにして分類します。


なお文のカテゴリ分けの仕方についてはLDAを使うと確率的にとれて便利っぽいですが、ここではもっといい加減にやります。

http://www.chasen.org/~daiti-m/paper/susemi200711language.pdf

*

例えば「おはようございます」だと形態素解析をした場合、「おはよう」「ござい」「ます」と別れます。「おはよう」をx_1, 「ござい」をx_2, 「ます」をx_3とすると、この文はx_1 = 1, x_2 = 1, x_3 = 1を満たすベクトルで表されます。なおここでは単語の順序は考慮してません。


おはようございます->["おはよう", "ござい", "ます"]->[1,1,1,0,0]

id 単語
1 おはよう
2 ござい
3 ます
4 こんばんわ
5 なのよ


次に「こんばんわなのよ」という文が来た場合、「こんばんわ」をx_4、「なのよ」をx_5としてベクトルは[0,0,0,1,1]となります。


次に「おはようなのよ」という文なら、同様に[1,0,0,0,1]となります。

*

次にSVMで領域を分けることを考えます。


SVMはものすごくいい加減に言ってしまうと、予め入力した、入力([1,1,1])と答え(C1に属すかどうか)のデータの塊に対して直線を引いて二つの領域に分割します。そして新しく来たデータを直線を境にどっちに属するか判断します。

パーセプトロンバックプロパゲーションと似てるようで違うんですが、詳しいことはググれ(http://preview.tinyurl.com/ylbmv5g)。あっちは重みを逆誤差伝播法で直していくのに対して、SVMはクラスごとの点から直線までの距離を大きくするように動くって違いがあるって言えばいいのかなぁ。

まあその辺の細かい話抜きにしてlibsvmが使いやすそうなので使ってみるかという話なのですが


これを使って、先程出した「おはようございます」「こんばんわ」等を入力として、「おはよう」に該当するもんだけ抽出できないかなぁと思っています。これだとあからさま過ぎてあまりウマさがないんだけど、もっと際どくして「ただいま。帰り電車が急に止まって大変だったわー」という文と「ただいま午前9時です」という文が与えられたときにどっちが「帰宅」を表すか判別できないかなぁと思ってます。予想としては結構間違いそうだけど・・


最初に出した例では、実際に「おはよう ござい ます->朝の挨拶(1)」, 「こんばんわなのよ->朝の挨拶ではない(-1)」とかいった学習データを入れて、そのあとで「おはようござい」「こんばんわー」はどっちだ?って判定をしてます。