done is better than perfect

自分が学んだことや、作成したプログラムの記事を書きます。すべての記載は他に定める場合を除き個人的なものです。

SQLite3で、レコードへの追加方法(Python)

SQLitePythonから使ってて、やり方が分からなかった方法の備忘録

やり方忘れるたびに調べるの面倒臭いんでメモっておきます。

データベース化する対象は京都大学の黒橋・河原研究室様が提供されているTextual Entailment 評価データです。

今回はこちらをまずデータベース化してから、MeCabによってposidを付与してみたいと思います。

まずは、提供されているテキストファイルから、sqliteを使って全部データベース化します。

[python] def createDB(): file_entailevaluationset = open("./entail_evaluation_set.txt") raw_set = [] for line in file_entailevaluationset.readlines(): raw_set.append*1 con = sqlite3.connect("./dic/entailevaluationset/entail_evaluation_set.db") con.execute('''create table entailset (number int, category text, decision text, t1 text, t2 text, t1_pos text, t2_pos text)''') con.executemany(u"insert into entailset values(?,?,?,?,?,?,?)",raw_set) con.commit() con.close() [/python]

もとのテキストファイルは半角スペース区切りでカラムが表現されているため、readlines()で一行づつ取ってきた後split()で分けます。

カラムはそれぞれ上から順番に元のカラムと対応するようになっていて、t1とt2とはそれぞれテキストと仮説を表します。

ここではわざわざ空白のカラムをt1_pos、t2_posとして入れていますが、いらないかもしれません。

次に、MeCabMeCabPythonバインディングを使用して、t1とt2にPOSタグ付けをします。ここでは後ほど利用しやすいように、posidという数字でタグ付けすることにします。

posidと品詞の対応はここなどを参考にしてください。

ちなみに僕の環境(Mac OS Χ 10.8.2 + Homebrewで入れたMeCab 0.994)では

/usr/local/Cellar/mecab/0.994/lib/mecab/dic/ipadic/pos-id.def

にpos-id.defが有りました。

[python] def insertPOStag(): tagger_text = MeCab.Tagger("-Ochasen") con = sqlite3.connect("./dic/entailevaluationset/entail_evaluation_set.db") c = con.execute(u"select * from entailset") for row in c: node_t1 = tagger_text.parseToNode*2 con.execute(u"update entailset set t2_pos=? where number=?",(str_posid_t2, row[0])) con.commit() con.close() [/python]

データベースにPythonのリスト型を入れる方法がわからなかったので、取り敢えずコンマ区切りの文字列で格納するようにしてます。

今回はデータベースに入れることだけを考えていて、僕自身SQLには慣れていないので、もしかしたら一般的でない書き方をしてたり、セキュアな実装ではないかも知れません。

もしもっといい方法や改善方法などがあるようでしたら教えて下さい。

*1: line.split(" ")[0].decode("utf-8"), line.split(" ")[1].decode("utf-8"), line.split(" ")[2].decode("utf-8"), line.split(" ")[3].decode("utf-8"), # t1 line.split(" ")[4].decode("utf-8"), # t2 "", # t1_pos "" # t2_pos

*2:row[3].encode("utf-8"))) node_t2 = tagger_text.parseToNode((row[4].encode("utf-8"))) node_t1 = node_t1.next node_t2 = node_t2.next str_posid_t1 = "" str_posid_t2 = "" while node_t1: str_posid_t1 += str(node_t1.posid) + "," node_t1 = node_t1.next while node_t2: str_posid_t2 += str(node_t2.posid) + "," node_t2 = node_t2.next con.execute(u"update entailset set t1_pos=? where number=?",(str_posid_t1, row[0]