辞書をMySqlにしたばあいのdictionary.pyは次のようになった。ただし、テンプレート型までしかいれていない。python2用であり、python3でやると不都合が起きると思う。なお、テキストブックの方は、python3用になっていた。
####################################
# -*- coding: utf-8 -*-
import MySQLdb
from analyzer import *
import re
"""
様々な辞書を処理するクラス
金城俊哉著「Pythonプログラミングパーフェクトマスター」を参照した
2017年2月12日 作成
"""
class Dictionary:
def __init__(self):
print "Dictionary を初期化します"
self.conn = MySQLdb.connect(
user='washida',
passwd='robotcomedian',
host='localhost',
db='dictionary',
charset="utf8"
)
self.c = self.conn.cursor()
# 辞書データを全て取得する
# ランダムフレーズの取得
sql = 'select * from random'
self.c.execute(sql)
self.random = [] #
print 'ランダムフレーズの取得 >> ',
count = 0
for row in self.c.fetchall():
#print 'id:', row[0], 'Phrase:', row[1], "\n"
if (row[1] != ''):
count += 1
self.random.append(row[1])
print "終了 総数 = ",str(count)
# パターンフレーズの取得
sql = 'select * from pattern'
self.c.execute(sql)
# 辞書型のインスタンスを用意
# self.pattern = {}
self.pattern = []
print 'パターンフレーズの取得 >> ',
count = 0
for row in self.c.fetchall():
# print 'id:', row[0], 'Pattern:', row[1], 'Phrase:', row[2], "\n"
if row[1] != '' and row[2] != '':
count += 1;
#self.pattern.setdefault('pattern', []).append(row[1])
#self.pattern.setdefault('phrases', []).append(row[2])
self.pattern.append({'pattern':row[1],'phrases':row[2]})
print "終了 総数 = ",str(count)
# 終了時に、データの更新が必要なpatternオブジェクト
self.update_pattern = []
# 終了時に新規追加が必要なpatternオブジェクト
self.newitem_pattern = []
# テンプレートデータの取得
print 'テンプレートフレーズの取得 >> ',
self.template = {}
sql = 'select max(nounnum) from template'
self.c.execute(sql)
#print "sql = ",sql
row = self.c.fetchone()
print '名詞最大数 = ', row[0],
count = 0
for i in range(int(row[0])):
j = i+1
sql = "select * from template where nounnum = '" + str(j) + "'"
self.c.execute(sql)
for row in self.c.fetchall():
#print 'id:', row[0], 'Nounnum:', row[1], 'Template:', row[2], "\n"
if row[1] != '' and row[2] != '':
if not row[1] in self.template:
self.template[row[1]] = []
self.template[row[1]].append(row[2])
count += 1;
print "終了 総数 = ",str(count)
# 終了時に、データの更新が必要なtemplateオブジェクト
self.update_template = []
# 終了時に新規追加が必要なtemplateオブジェクト
self.newitem_template = []
self.c.close()
self.conn.close()
def study(self, input, parts):
""" study_random()とstudy_pattern()を呼ぶ
@param input ユーザーの発言
@param parts 形態素解析結果
"""
# インプット文字列末尾の改行は取り除いておく
input = input.rstrip('\n')
# インプット文字列と解析結果を引数に、パターン辞書の登録メソッドを呼ぶ
self.study_pattern(input, parts)
# テンプレート辞書の登録メソッドを呼ぶ
self.study_template(parts)
def study_pattern(self, input, parts):
""" ユーザーの発言を学習する
@param input インプット文字列
@param parts 形態素解析の結果(リスト)
"""
print "学習を開始します"
# 多重リストの要素を2つのパラメーターに取り出す
for word, part in parts:
# analyzerのkeyword_check()関数による名詞チェックが
# Trueの場合
if (keyword_check(part)):
print "キーワードが存在しました!!"
depend = False # パターンオブジェクトを保持する変数
# patternリストのpattern辞書オブジェクトを反復処理
for ptn_item in self.pattern:
# インプットされた名詞が既存のパターンとマッチしたら
# patternリストからマッチしたParseItemオブジェクトを取得
if(re.search(ptn_item['pattern'], word)):
depend = ptn_item
break #マッチしたら止める
# 既存パターンとマッチしたParseItemオブジェクトから
# add_phraseを呼ぶ
if depend:
print "キーワードが既存のパターンにマッチするものでした!"
#depend.add_phrase(input) # 引数はインプット文字列
if(re.search(depend['phrases'], input)):
# すでにフレーズも含まれている場合は、なにもしない
pass
else:
# 既存のパターンに合致するが、フレーズに含まれていないものについては、フレーズに加えるだけにする
depend['phrases'] += ('|'+input)
# 終了時に更新すべきオブジェクトに位置付ける
self.update_pattern.append(depend)
else:
print "キーワードが既存のパターンにマッチしないものでした!"
# 既存パターンに存在しない名詞であれば
# 新規のParseItemオブジェクトを
# patternリストに追加
newitem = {'pattern':word, 'phrases':input}
self.pattern.append(newitem)
# 終了時に新規追加しなければならない
self.newitem_pattern.append(newitem)
def study_template(self, parts):
""" テンプレートを学習する
@param parts 形態素解析の結果(リスト)
"""
template = ''
count = 0
for word, part in parts:
# 名詞であるかをチェック
if (keyword_check(part)):
word = '%noun%'
count += 1
template += word
# self.templateのキーにcount(出現回数)が存在しなければ
# countをキーにして空のリストを要素として追加
if count > 0:
count = str(count)
if not count in self.template:
self.template[count] = []
self.newitem_template.append(count)
# countキーのリストにテンプレート文字列を追加
if not template in self.template[count]:
self.template[count].append(template)
self.update_template.append({'nounnum':count,'template':template})
def closeDict(self):
# データベースへの変更を保存、あれば
self.conn = MySQLdb.connect(
user='washida',
passwd='robotcomedian',
host='localhost',
db='dictionary',
charset="utf8"
)
self.c = self.conn.cursor()
# 辞書データを更新する
print "辞書データベースを更新します"
for item in self.update_pattern:
#
sql = "update pattern set phrases = '" + item['phrases'] + "' where pattern = '" + item['pattern'] + "'"
print "sql = ",sql
self.c.execute(sql)
for item in self.newitem_pattern:
#
sql = "insert into pattern (pattern, phrases) values ('" + item['pattern'] + "', '" + item['phrases'] + "')"
print "sql = ",sql
self.c.execute(sql)
for item in self.update_template:
# アップデートすべきtemplateだけがはいっているので、全部加える
sql = "insert into template (nounnum, template) values ('" + item['nounnum'] + "', '" + item['template'] + "')"
print "sql = ",sql
self.c.execute(sql)
for num in self.newitem_template:
# 新規なので、全部加える 新規の番号の文字列だけが入っている
for tmp in self.template[num]:
sql = "insert into template (nounnum, template) values ('" + num + "', '" + tmp + "')"
print "sql = ",sql
self.c.execute(sql)
self.conn.commit()
#データベースを閉じる
self.c.close()
self.conn.close()