傀儡師の館.Python

傀儡師の館.Python

PR

×

Calendar

Keyword Search

▼キーワード検索

Archives

2026.07
2026.06
2026.05
2026.04
2026.03
2026.02
2026.01
2025.12
2025.11
2025.10

Profile

kugutsushi

kugutsushi

Free Space

設定されていません。
2003.03.01
XML
カテゴリ: ことばの処理
○ 辞書をRDBMS に入れて遊ぶ 1 (Python で人工無能)

今日はのっけから本題のみ。

とりあえず、Gadfly に MeCab で使っている ipadic を試しに登録してみることにした。まず、辞書を作成するディレクトリのチェックと作成から。Gadfly はデータベースごとにディレクトリを作っておいた方がよいので、C:\\GadflyDB にまとめてデータベースを置くディレクトリとしておいて、そこにさらに ipadic というディレクトリを用意して、そこにデータベースを置くことにする。

import sys
import os
import gadfly

# とりあえず、 DB を C:¥GadflyDB というディレクトリに
# 保存することにする。もし、このディレクトリが存在しない
# 場合には、ディレクトリを作成し、作成できない場合は


DBDataDir = "C:¥¥GadflyDB¥¥ipadic"
if not os.path.isdir(DBDataDir):
  try:
    os.mkdir(DBDataDir)
  except:
    print "ディレクトリが作成できません。"

# データベース名
DBName = "ipadic"
# でもって、今度は、データベースを用意する。とりあえず、
# まずテーブルを作成してやる。そうしたら、ちょっと、ここに
# 実際にデータを登録できるかどうか、試してみよう。

# はなくて、最後に rollback してみる。

# ここから本番
# Gadfly への接続用にオブジェクトを作成し、
# connection という変数に代入する。
connection = gadfly.gadfly()


# ipadic というデータベースの使用を開始する。
# もし、存在しない場合は、勝手に新規に作成される。
# 存在する場合は「初期化」される。
connection.startup(DBName, DBDataDir)

# カーソルオブジェクトを作成し、
# cursor という変数に代入する。
cursor = connection.cursor()
# sql コマンドを用意する。
cmd = """create table dic
(key varchar,
cost varchar,
pos1 varchar,
pos2 varchar,
pos3 varchar,
pos4 varchar,
pos5 varchar,
pos6 varchar,
genkei varchar,
yomi varchar,
hatsuon varchar)
"""
# sql コマンドを実行し、テーブルを作成する
cursor.execute(cmd)
# コミットして、データベースに反映させる
connection.commit()
cmd = """insert into dic
(key, cost, pos1, pos2, pos3, pos4, pos5, pos6,
genkei, yomi, hatsuon)
values
(’若松山’,’3524’,’名詞’,’固有名詞’,
’一般’,’*’,’*’,’*’,’若松山’,
’ワカマツヤマ’, ’ワカマツヤマ’)
"""
# sql コマンド を実行し、データを挿入する
cursor.execute(cmd)
# test テーブルにあるデータをすべて選択する(select)
cursor.execute("select * from dic")
# テーブルができたか確認する
print cursor.pp()
# 明示的に前の命令(挿入)をロールバックして無効にする。
cursor.rollback()
# 接続を閉じる
connection.close()


ここまででいったん終了。とりあえずテーブルは作成してコミットしたので、テーブルはちゃんと残っているはずなので、これを使う。よけいなテスト用のデータはロールバックしたので残っていないはず。さて、これから ipadic の MeCab 用の csv ファイルから、ガツンと読み込んでやることにする。


import sys
import os
import gadfly

# データベース名
DBDataDir = "C:¥¥GadflyDB¥¥ipadic"
DBName = "ipadic"

# ipadic の csv ファイルの場所を指定する
CSVFile = "C:¥¥Program Files¥¥mecab¥¥dic¥¥ipadic¥¥dic.csv"
# データベースはすでに作成されているので、
# これからは接続するだけでいいというか、初期化しちゃだめ。
connection = gadfly.gadfly(DBName, DBDataDir)
cursor = connection.cursor()
csvfile = open(CSVFile, ’r’)
# コマンドの前半だけ用意する
cmd0 = """insert into dic
   (key, cost, pos1, pos2, pos3, pos4, pos5, pos6,
    genkei, yomi, hatsuon)
    values """

# カウンタ
c = 0
# 最初の行を読み込む
# ちなみに行末の改行(\n)が邪魔なので1文字捨てている。
line = csvfile.readline()[:-1]

while line:
  # カンマ区切りのデータをリストに分解 [’見出し’, ’品詞1’, ’品詞2’]
  line = line.split(’,’)
  # "(’見出し’, ’品詞1’, ’品詞2’, ...)" という文字列が欲しい。
  # のだが面倒なので、タプル(a, b, c...) という形式にリストから
  # いったん変換して、その表示用の文字列を使ってしまう(^^;;
  line = tuple(line).__repr__()
  # コマンドの前半部と読み込んだ行を合体して、
  # その行を挿入するための SQL 文を作る
  cmd = cmd0 + line
  # sql コマンド を実行し、データを挿入する
  cursor.execute(cmd)
  # どのくらいまで進んだか、画面に表示しておく
  # 1000 ごとに ’.’ を1つ表示しておく
  c = c + 1
  if ((c % 1000) == 0 ):
    print ’.’,
  # 次の行を読み込む
  # ちなみに行末の改行(\n)が邪魔なので1文字捨てている。
  line = csvfile.readline()[:-1]

# csv 形式の辞書を閉じる
csvfile.close()
# テスト用に小さい csv ファイルを最初に作ってテスト
# でかいのでそのままやると大変...
# cursor.execute("select * from dic")
#
# cursor が示しているポイントから、
# データをすべて取り出して(fetchall)、
# 変数 x に代入してすべての取り出した行に対して操作を行う。
#
#for x in cursor.fetchall():
# print x
# とするとデータが多くて大変なので
# 確認しないでとりあえず閉じて終わり。
connection.commit()
connection.close()


だいたい、1秒間に100行程度しか処理できない。うーむやっぱり大量のデータを扱うのはつらいってことかもしれない。せいぜい、4桁程度のデータまでかな。MySQL を使って同じことを Python からやってみたが、あっという間に終わった。Gadfly だと2時間以上かかるものが、MySQL だと 10分程度。うーん。ちょっと考えちゃうな。1行ごとにコミットしてみたり、1000行ごとにコミットしてみたり、checkpoint の設定を自動ではなく、手動にしてみたりもしたが、どうあがいても遅い。検索はどうだろう。まあ、やらないでも分かるな・・・。できあがったデータ量も、Gadfly 45MB 程度、MySQL は 30MB 程度と、容量もやっぱり差が出る。ちなみに、元のデータは 26MB 程度なので、MySQL がやっぱり優秀なのだな。

検索してもやっぱり、全然速さが違う。うーん、Gadfly はちょっと数十万行とかあつかう場合は、やっぱり厳しいな。インデックスをつけたとしても、そんなに速くならないだろうし(MySQL もインデックスなしで同じようなテーブルで作ったから条件同じだし)。ということで、この用途に対しては Gadfly をあえて使うこともないという、当たり前の結論に達して、MySQL でいいやということになる(笑)。

この記事、カテゴリを変更して再登録しようとしたが、文字数制限がきつくなって再登録できないので、後半部を 別の日に 入れておく。







お気に入りの記事を「いいね!」で応援しよう

Last updated  2006.09.15 22:39:07
コメントを書く


【毎日開催】
15記事にいいね!で1ポイント
10秒滞在
いいね! -- / --
おめでとうございます!
ミッションを達成しました。
※「ポイントを獲得する」ボタンを押すと広告が表示されます。
x
X

© Rakuten Group, Inc.
X
Design a Mobile Website
スマートフォン版を閲覧 | PC版を閲覧
Share by: