言語処理でデータベース



今回の話

  • なんで日本語をDBで扱うか、という話
  • ちなみにDBに詳しいわけじゃないっす
    • なので「詳しくなくてもわかる利点」くらいの話


言語処理でデータベース

  • 何故データベース?
    • ぶっちゃけ、データがたくさんありすぎる
      • これは学習とかさせるには必要なんだけど・・・
      • でも一度に扱うのは大変なのです
    • 100MB単位のテキストなんてざら。GB単位も
    • 毎回これ全部読み込むのは時間かかる
    • というか、マシンによってはメモリも足りない
    • この上全文検索とか、果てしなく時間がかかる
    • しかも普通、自然言語処理だとテキストって形態素解析したり係り受け解析したり、一文がさらにたくさんのデータに分解される
      • 例:Mecabで形態素解析すると……
        • しかも  接続詞,*,*,*,*,*,しかも,シカモ,シカモ
        • 普通    名詞,形容動詞語幹,*,*,*,*,普通,フツウ,フツー
        • 、      記号,読点,*,*,*,*,、,、,、
        • 自然    名詞,形容動詞語幹,*,*,*,*,自然,シゼン,シゼン
        • 言語    名詞,一般,*,*,*,*,言語,ゲンゴ,ゲンゴ
        • 処理    名詞,サ変接続,*,*,*,*,処理,ショリ,ショリ
        • だ      助動詞,*,*,*,特殊・ダ,基本形,だ,ダ,ダ
        • と      助詞,格助詞,引用,*,*,*,と,ト,ト
        • テキスト        名詞,一般,*,*,*,*,テキスト,テキスト,テキスト
        • って    助詞,格助詞,連語,*,*,*,って,ッテ,ッテ
        • (以下略)
        • あれっ。データ更にでかくなってね?
    • さて、そんなデータをどう処理しよう
      • そのまま?
        • txt .csv など
        • 配布形式としてはよくあるよ
        • でも毎回そこから読み込むのは大変なのです
        • なのでDBにしたりsuffix arrayにしたりして使います
    • データベースにすると?
      • ある程度まではアルゴリズム、データ構造を考えなくても検索とか高速化してくれます。はい。
        • データベース側でそのあたり、考えてくれているので
      • 高速に検索して文を取ってこれるなら、全部メモリに乗せなくてもいい
        • 状況に応じて必要な物だけとってくればいい
      • ああでも、ちょっと面倒な事も…….
        • デフォルトでは日本語使いにくいとか.
        • メモリに乗せられるならそっちのが早い.
        • だいたい、いくらDBでも原文そのままだと遅いって
      • DB自体について詳しく知りたい方はここを見てみるといいかも



DBの使い方(SQL編)

  • DBの操作の仕方
    • 基本的にはコマンド打って、結果を持ってきます
    • データ構造は
      • Table
        • 表の事
        • どんなデータをいれているかという単位。例えば「文」とか「index」とか。
        • ともかく、たくさんのカラムが入ってる
      • Column
        • データの事
        • int id, とかtxt sentence とか
    • データの作り方
      • テーブルの作り方
        • create文
        • create table 社員 (名前 varchar(10), 年齢 integer, 部署 varchar(200));
        • これのイメージは
          社員
           名前年齢部署 
             
      • データの入れ方
        • insert文
        • insert into 社員 values ('橋本', 26, '広報部')
        • これのイメージは
          社員
           名前年齢部署 
          橋本 26 広報部 
          上のデータが社員テーブルに追加(insert)されてる
    • データの取得の仕方
      • select * from 社員
      • こうすると(橋本, 26, 広報部) のような対のリストが得られる
      • * from の*が表示させたいカラム名
        • select 年齢 from 社員
        • とかすると 26という年齢だけ取得できる
      • 他にも抽出条件をつけられる
      • select * from 社員 where 名前="橋本"
        • これなら名前=橋本のデータだけ取得

  • DBを作る時のお約束
    • 上のように使うわけなので、テーブル名、カラム名、データ形式を記載すること
    • というかそれさえわかってればあとはデータを取ってこれる


DBの使い方(SQLite3とPythonで言語処理っぽい事を)

  • 例えば検索だったら……
    • 転置インデックス
      • 文をn-gramにして、(n-gram, 文のid)の対のテーブルを作る
      • クエリに一致するn-gramを探して、対の文を提示
    • 単語辞書
      • 文を形態素解析して(形態素, 文のid)の(略)
    • 問題
      • 案外インデックスとか辞書って巨大になりがちなのよね
      • 入力文が増えるとidも巨大になるわけで、対も大きくなるわけです
    • 軽量化したい場合
      • Idの符号化などをします
    • 詳しくはこっちを見て! いいページだよ!
  • Pythonでの使い方
    • 基本的にはselect文やcreate文を叩いて、Listで取得します
    • ここではSQLite3での使い方
      • SQLite3
        • Pythonにはモジュールがあるのでそれを使います
      • サンプル
        • import sqlite3
        • db = sqlite3.connect('path')
        • com = db.execute("select * from idx where word=\"%s\""%(word))
        • result = {}
        • row = com.fetchone()
        •         if row:
        •             if id:
        •                 result['id'] = row[0]
        •             if txt:
        •                 result['txt'] = row[1]
        •             if sid:
        •                 result['sid'] = row[2].split(' ')
      • ちなみにまとめてデータを取得したいなら、
        • for row in com:
          • print row
        • #とすると全行が得られる
      • もっと詳しく知りたい場合はこちらをどうぞ


ソースコードの例


Source Viewer





ċ
山本和英,
2012/02/28 2:42
Comments