今回の話
- なんで日本語をDBで扱うか、という話
- ちなみにDBに詳しいわけじゃないっす
- 何故データベース?
- ぶっちゃけ、データがたくさんありすぎる
- これは学習とかさせるには必要なんだけど・・・
- でも一度に扱うのは大変なのです
- 100MB単位のテキストなんてざら。GB単位も
- 毎回これ全部読み込むのは時間かかる
- というか、マシンによってはメモリも足りない
- この上全文検索とか、果てしなく時間がかかる
- しかも普通、自然言語処理だとテキストって形態素解析したり係り受け解析したり、一文がさらにたくさんのデータに分解される
- 例:Mecabで形態素解析すると……
- しかも 接続詞,*,*,*,*,*,しかも,シカモ,シカモ
- 普通 名詞,形容動詞語幹,*,*,*,*,普通,フツウ,フツー
- 、 記号,読点,*,*,*,*,、,、,、
- 自然 名詞,形容動詞語幹,*,*,*,*,自然,シゼン,シゼン
- 言語 名詞,一般,*,*,*,*,言語,ゲンゴ,ゲンゴ
- 処理 名詞,サ変接続,*,*,*,*,処理,ショリ,ショリ
- だ 助動詞,*,*,*,特殊・ダ,基本形,だ,ダ,ダ
- と 助詞,格助詞,引用,*,*,*,と,ト,ト
- テキスト 名詞,一般,*,*,*,*,テキスト,テキスト,テキスト
- って 助詞,格助詞,連語,*,*,*,って,ッテ,ッテ
- (以下略)
- あれっ。データ更にでかくなってね?
- さて、そんなデータをどう処理しよう
- そのまま?
- txt .csv など
- 配布形式としてはよくあるよ
- でも毎回そこから読み込むのは大変なのです
- なのでDBにしたりsuffix arrayにしたりして使います
- データベースにすると?
- ある程度まではアルゴリズム、データ構造を考えなくても検索とか高速化してくれます。はい。
- 高速に検索して文を取ってこれるなら、全部メモリに乗せなくてもいい
- ああでも、ちょっと面倒な事も…….
- デフォルトでは日本語使いにくいとか.
- メモリに乗せられるならそっちのが早い.
- だいたい、いくらDBでも原文そのままだと遅いって
- DB自体について詳しく知りたい方はここを見てみるといいかも
- DBの操作の仕方
- 基本的にはコマンド打って、結果を持ってきます
- データ構造は
- Table
- 表の事
- どんなデータをいれているかという単位。例えば「文」とか「index」とか。
- ともかく、たくさんのカラムが入ってる
- Column
- データの事
- int id, とかtxt sentence とか
- データの作り方
- テーブルの作り方
- create文
- create table 社員 (名前 varchar(10), 年齢 integer, 部署 varchar(200));
- これのイメージは
社員
- データの入れ方
- insert文
- insert into 社員 values ('橋本', 26, '広報部')
- これのイメージは
社員 上のデータが社員テーブルに追加(insert)されてる
- データの取得の仕方
- select * from 社員
- こうすると(橋本, 26, 広報部) のような対のリストが得られる
- * from の*が表示させたいカラム名
- select 年齢 from 社員
- とかすると 26という年齢だけ取得できる
- 他にも抽出条件をつけられる
- select * from 社員 where 名前="橋本"
- DBを作る時のお約束
- 上のように使うわけなので、テーブル名、カラム名、データ形式を記載すること
- というかそれさえわかってればあとはデータを取ってこれる
DBの使い方(SQLite3とPythonで言語処理っぽい事を)
- 例えば検索だったら……
- 転置インデックス
- 文をn-gramにして、(n-gram, 文のid)の対のテーブルを作る
- クエリに一致するn-gramを探して、対の文を提示
- 単語辞書
- 問題
- 案外インデックスとか辞書って巨大になりがちなのよね
- 入力文が増えると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:
- #とすると全行が得られる
- もっと詳しく知りたい場合はこちらをどうぞ
- IdxSentenceDB.pyをページ下部に追加しておきました
- sqlite3での簡単なデータベースの作り方
- テーブル内容
- idx (id, bigram, sid)
- sentence(sid, sentence)
- 簡単な検索テーブル
- クエリを入力すると、bigramにして、一致するsidのリストを取得。その後sidの一致するsentenceを取得するもの
|