質問編集履歴

2

誤字

2018/07/22 03:02

投稿

hershel
hershel

スコア13

test CHANGED
File without changes
test CHANGED
@@ -138,7 +138,7 @@
138
138
 
139
139
 
140
140
 
141
- リンゴ 私はリンゴが好きです|私はプログラムです
141
+  私はリンゴが好きです|私はプログラムです
142
142
 
143
143
  リンゴ 私はリンゴが好きです
144
144
 

1

情報の追加

2018/07/22 03:01

投稿

hershel
hershel

スコア13

test CHANGED
File without changes
test CHANGED
@@ -127,3 +127,203 @@
127
127
  しかしこれ以前の文章には「妹」も「附加」も出てこないためなぜここでエラーが出るのか不明です。
128
128
 
129
129
  ご教授いただけると幸いです。
130
+
131
+
132
+
133
+ 追記
134
+
135
+ ptn['pattern']にはそれまで会話の中に登場した名詞が入ります。
136
+
137
+ 会話を行うとその中に登場した名詞や文章を学習してファイルに
138
+
139
+
140
+
141
+ リンゴ 私はリンゴが好きです|私はプログラムです
142
+
143
+ リンゴ 私はリンゴが好きです
144
+
145
+ プログラム 私はプログラムです
146
+
147
+
148
+
149
+ といった形で情報を入れます。
150
+
151
+ 先頭の単語がptn['pattern']にあたります。
152
+
153
+
154
+
155
+ 関連するコードは
156
+
157
+ ```
158
+
159
+ import re
160
+
161
+ from janome.tokenizer import Tokenizer
162
+
163
+
164
+
165
+
166
+
167
+ class Dictionary:
168
+
169
+ """思考エンジンの辞書クラス。
170
+
171
+
172
+
173
+ クラス変数:
174
+
175
+ DICT_PATTERN -- パターン辞書のファイル名
176
+
177
+ TOKENIZER -- 形態素解析器
178
+
179
+
180
+
181
+ スタティックメソッド:
182
+
183
+ make_pattern(str) -- パターン辞書読み込み用のヘルパー
184
+
185
+ pattern_to_line(pattern) -- パターンハッシュをパターン辞書形式に変換する
186
+
187
+ analyze(str) -- 文字列strを形態素解析する
188
+
189
+
190
+
191
+ プロパティ:
192
+
193
+ pattern -- パターン辞書
194
+
195
+ """
196
+
197
+
198
+
199
+ DICT_PATTERN = '***.txt'
200
+
201
+ TOKENIZER = Tokenizer()
202
+
203
+
204
+
205
+ def __init__(self):
206
+
207
+ """ファイルから辞書の読み込みを行う。"""
208
+
209
+ with open(Dictionary.DICT_RANDOM, encoding='utf-8') as f:
210
+
211
+ self._random = [l for l in f.read().splitlines() if l]
212
+
213
+
214
+
215
+ with open(Dictionary.DICT_PATTERN, encoding='utf-8') as f:
216
+
217
+ self._pattern = [Dictionary.make_pattern(l) for l in f.read().splitlines() if l]
218
+
219
+
220
+
221
+ def study(self, text):
222
+
223
+ """パターン辞書をメモリに保存する。"""
224
+
225
+ self.study_pattern(text, Dictionary.analyze(text))
226
+
227
+
228
+
229
+ def study_pattern(self, text, parts):
230
+
231
+ """ユーザーの発言textを、形態素partsに基づいてパターン辞書に保存する。"""
232
+
233
+ for word, part in parts:
234
+
235
+ if self.is_keyword(part): # 品詞が名詞であれば学習
236
+
237
+ # 単語の重複チェック
238
+
239
+ # 同じ単語で登録されていれば、パターンを追加する
240
+
241
+ # 無ければ新しいパターンを作成する
242
+
243
+ duplicated = next((p for p in self._pattern if p['pattern'] == word), None)
244
+
245
+ if duplicated:
246
+
247
+ if not text in duplicated['phrases']:
248
+
249
+ duplicated['phrases'].append(text)
250
+
251
+ else:
252
+
253
+ self._pattern.append({'pattern': word, 'phrases': [text]})
254
+
255
+
256
+
257
+ def save(self):
258
+
259
+ """メモリ上の辞書をファイルに保存する。"""
260
+
261
+ with open(Dictionary.DICT_RANDOM, mode='w', encoding='utf-8') as f:
262
+
263
+ f.write('\n'.join(self.random))
264
+
265
+
266
+
267
+ with open(Dictionary.DICT_PATTERN, mode='w', encoding='utf-8') as f:
268
+
269
+ f.write('\n'.join([Dictionary.pattern_to_line(p) for p in self._pattern]))
270
+
271
+
272
+
273
+ @staticmethod
274
+
275
+ def analyze(text):
276
+
277
+ """文字列textを形態素解析し、[(surface, parts)]の形にして返す。"""
278
+
279
+ return [(t.surface, t.part_of_speech) for t in Dictionary.TOKENIZER.tokenize(text)]
280
+
281
+
282
+
283
+ @staticmethod
284
+
285
+ def pattern_to_line(pattern):
286
+
287
+ """パターンのハッシュを文字列に変換する。"""
288
+
289
+ return '{}\t{}'.format(pattern['pattern'], '|'.join(pattern['phrases']))
290
+
291
+
292
+
293
+ @staticmethod
294
+
295
+ def is_keyword(part):
296
+
297
+ """品詞partが学習すべきキーワードであるかどうかを真偽値で返す。"""
298
+
299
+ return bool(re.match(r'名詞,(一般|代名詞|固有名詞|サ変接続|形容動詞語幹)', part))
300
+
301
+
302
+
303
+ @staticmethod
304
+
305
+ def make_pattern(line):
306
+
307
+ """文字列lineを\tで分割し、{'pattern': [0], 'phrases': [1]}の形式で返す。
308
+
309
+ [1]はさらに`|`で分割し、文字列のリストとする。"""
310
+
311
+ pattern, phrases = line.split('\t')
312
+
313
+ if pattern and phrases:
314
+
315
+ return {'pattern': pattern, 'phrases': phrases.split('|')}
316
+
317
+
318
+
319
+ @property
320
+
321
+ def pattern(self):
322
+
323
+ """パターン辞書"""
324
+
325
+ return self._pattern
326
+
327
+
328
+
329
+ ```