rabbit-slide-komainu8-postgresql-conference-japan-2021 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c70ecfa7c7eba2672af560d513cd242a2dbcf99d1705a25276c6dde7a46bd689
4
+ data.tar.gz: 9e126bdb80ea9514826a2df952da77885659f39b093dae75eb90780ac924be39
5
+ SHA512:
6
+ metadata.gz: 5f36961f4d290ab89fe04eadbe7cd8abc03bc0c29b5340ede122ffb465261bf63e53b671be11757a9dda8b5b32a6cf84dd3ef156f0cd495dd5a3310595b1f4bc
7
+ data.tar.gz: b3c6839c4421c6bdf559e2ebeb46bd0de10a878f6a5bb3aed0478e9029703d6234fdb27b77587aea1501d85fbe0ebc53ad1ae74e22746519c9acf9bfccb2f783
data/.rabbit ADDED
@@ -0,0 +1 @@
1
+ improve-search-result-with-pgroonga.rab
data/README.rd ADDED
@@ -0,0 +1,42 @@
1
+ = PGroongaを使って全文検索結果をより良くする方法
2
+
3
+ PostgreSQL で使用できる全文検索の拡張に PGroonga という高速に全文検索できる拡張があります。
4
+
5
+ PGroongaはバックエンドに本格的な全文検索エンジンGroongaを使っており、高速な全文検索以外にも、
6
+ より良い検索結果を出すための機能(検索結果の適合率や再現率の向上や、より良い結果順にするためのスコアリング)
7
+ が盛り込まれています。
8
+
9
+ PGroongaはPostgreSQLの拡張なので、SQLベースでこれらの機能を使うことができ、
10
+ SQLを使い慣れている人であれば、比較的スムーズにこれらの機能を使えます。
11
+
12
+ 本発表では、全文検索結果をより良くするPGroongaの機能について、どのような機能があり、
13
+ それらをどう使うのかについて網羅的に紹介します。
14
+
15
+ == ライセンス
16
+
17
+ === スライド
18
+
19
+ CC BY-SA 4.0
20
+
21
+ 原著作者:堀本泰弘
22
+
23
+ == 作者向け
24
+
25
+ === 表示
26
+
27
+ rake
28
+
29
+ === 公開
30
+
31
+ rake publish
32
+
33
+ == 閲覧者向け
34
+
35
+ === インストール
36
+
37
+ gem install rabbit-slide--postgresql-conference-japan-2021
38
+
39
+ === 表示
40
+
41
+ rabbit rabbit-slide--postgresql-conference-japan-2021.gem
42
+
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require "rabbit/task/slide"
2
+
3
+ # Edit ./config.yaml to customize meta data
4
+
5
+ spec = nil
6
+ Rabbit::Task::Slide.new do |task|
7
+ spec = task.spec
8
+ # spec.files += Dir.glob("doc/**/*.*")
9
+ # spec.files -= Dir.glob("private/**/*.*")
10
+ # spec.add_runtime_dependency("rabbit-theme-YOUR-THEME")
11
+ end
12
+
13
+ desc "Tag #{spec.version}"
14
+ task :tag do
15
+ sh("git", "tag", "-a", spec.version.to_s, "-m", "Publish #{spec.version}")
16
+ sh("git", "push", "--tags")
17
+ end
data/config.yaml ADDED
@@ -0,0 +1,31 @@
1
+ ---
2
+ id: postgresql-conference-japan-2021
3
+ base_name: improve-search-result-with-pgroonga
4
+ tags: [
5
+ rabbit,
6
+ postgresql,
7
+ pgcon21j,
8
+ fts,
9
+ search,
10
+ pgroonga,
11
+ groonga
12
+ ]
13
+ presentation_date: 2021-11-12
14
+ presentation_start_time: 2021-11-12T16:10:00+09:00
15
+ presentation_end_time: 2021-11-12T17:00:00+09:00
16
+ version: 1.0.0
17
+ licenses: [
18
+ CC-BY-SA-4.0
19
+ ]
20
+ slideshare_id:
21
+ speaker_deck_id:
22
+ ustream_id:
23
+ vimeo_id:
24
+ youtube_id:
25
+ author:
26
+ markup_language: :rd
27
+ name: Horimoto Yasuhiro
28
+ email: horimoto@clear-code.com
29
+ rubygems_user: komainu8
30
+ slideshare_user:
31
+ speaker_deck_user:
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,520 @@
1
+ = PGroongaを使って\n全文検索結果を\nより良くする方法
2
+
3
+ : author
4
+ 堀本 泰弘
5
+ : institution
6
+ 株式会社クリアコード
7
+ : content-source
8
+ PostgreSQL Conference Japan 2021
9
+ : date
10
+ 2021-11-12
11
+ : allotted-time
12
+ 45m
13
+ : start-time
14
+ 2021-11-12T16:10:00+09:00
15
+ : end-time
16
+ 2021-11-12T16:55:00+09:00
17
+ : theme
18
+ .
19
+
20
+ = 本日の資料
21
+
22
+ * 本日のスライド
23
+ * ((<URL:https://slide.rabbit-shocker.org/authors/komainu8/improve-search-result-with-pgroonga.rab>))
24
+
25
+ = 自己紹介
26
+
27
+ # image
28
+ # src = images/self-introduction.png
29
+ # relative_height = 107
30
+
31
+ = 目次
32
+
33
+ (1) 検索の評価指標
34
+ (2) PGroongaで検索結果の改善
35
+ (3) 参考資料
36
+
37
+ = 検索の評価指標
38
+
39
+ よく検索結果が\n
40
+ ((*いまいち*))だ...\n
41
+ という話を\n聞きます
42
+
43
+ = 検索の評価指標
44
+
45
+ # image
46
+ # src = images/search-result-01.png
47
+ # relative_height = 100
48
+
49
+ = 検索の評価指標
50
+
51
+ * 😞検索漏れ
52
+ * 😞ノイズが多い
53
+ * 😞有用な情報を探し出せない
54
+
55
+ = 検索の評価指標
56
+
57
+ (1) 効率性\n低コストで検索できるかどうか
58
+ (2) ((*有効性*))\n検索結果の全体 or 一部が\n((*欲しい情報*))だったかどうか
59
+
60
+ = 検索の評価指標
61
+
62
+ 今日は有効性に\nついてのお話です
63
+
64
+ = 有効性の指標
65
+
66
+ (1) 適合率
67
+ (2) 再現率
68
+ (3) ランキング
69
+
70
+ = 適合率と再現率
71
+
72
+ # image
73
+ # src = images/precision-recall-1.png
74
+ # relative_height = 82
75
+
76
+ = 適合率と再現率
77
+
78
+ # image
79
+ # src = images/precision-hight-recall-low.png
80
+ # relative_height = 90
81
+
82
+ = 適合率と再現率
83
+
84
+ # image
85
+ # src = images/precision-low-recall-hight.png
86
+ # relative_height = 90
87
+
88
+ = ランキング
89
+
90
+ 欲しい情報が\nランキング((*上位*))にあるか
91
+
92
+ = ランキング
93
+
94
+ ユーザーは\n((*上位数件*))\nしか見ない
95
+
96
+ = PGroongaで検索結果の改善
97
+
98
+ * PGroongaで適合率/再現率改善
99
+
100
+ * ノーマライザーを使う
101
+ * トークナイザーを使う
102
+ * ステミングを使う
103
+ * fuzzy検索を使う
104
+ * 同義語展開を使う
105
+
106
+ = PGroongaで検索結果の改善
107
+
108
+ * PGroongaでランキング改善
109
+
110
+ * スコアラーを使う
111
+
112
+ = PGroongaのノーマライザー\n(デフォルト)
113
+
114
+ # coderay sql
115
+
116
+ CREATE DATABASE pgroonga_test;
117
+ CREATE EXTENSION pgroonga;
118
+ CREATE TABLE normalizer_test (
119
+ id integer,
120
+ content text
121
+ );
122
+ CREATE INDEX pgroonga_content_index ON normalizer_test USING pgroonga (content);
123
+
124
+ INSERT INTO normalizer_test VALUES (1, 'キログラム');
125
+ INSERT INTO normalizer_test VALUES (2, 'きろぐらむ');
126
+ INSERT INTO normalizer_test VALUES (3, '㌕');
127
+ INSERT INTO normalizer_test VALUES (4, 'キログラム');
128
+ INSERT INTO normalizer_test VALUES (5, 'kiroguramu');
129
+ INSERT INTO normalizer_test VALUES (6, 'kiroguramu');
130
+
131
+ SELECT * FROM normalizer_test WHERE content &@ 'キログラム';
132
+
133
+ = PGroongaのノーマライザー\n(デフォルト)
134
+
135
+ # RT
136
+ delimiter = [|]
137
+
138
+ id | content
139
+
140
+ 1 | キログラム
141
+ 3 | ㌕
142
+ 4 | キログラム
143
+
144
+ = PGroongaのノーマライザー\n(デフォルト)
145
+
146
+ * 半角/全角を同一視
147
+ * ㌕とキログラムを同一視
148
+
149
+ = PGroongaのノーマライザー\n(デフォルト)
150
+
151
+ PGroongaのデフォルトはNFKCを使った正規化\n
152
+ ※対象のテキストのエンコードがUTF-8の時
153
+
154
+ = ノーマライザーの変更
155
+
156
+ 再現率を上げたい
157
+
158
+ = PGroongaのノーマライザー\n(NormalizerNFKC130)
159
+
160
+ # coderay sql
161
+
162
+ DROP INDEX pgroonga_content_index;
163
+ CREATE INDEX pgroonga_content_index
164
+ ON normalizer_test
165
+ USING pgroonga (content)
166
+ WITH (normalizers='NormalizerNFKC130("unify_to_romaji", true)');
167
+ SELECT * FROM normalizer_test WHERE content &@ 'キログラム';
168
+
169
+ = PGroongaのノーマライザー\n(NormalizerNFKC130)
170
+
171
+ # RT
172
+ delimiter = [|]
173
+
174
+ id | content
175
+
176
+ 1 | キログラム
177
+ 2 | きろぐらむ
178
+ 3 | ㌕
179
+ 4 | キログラム
180
+
181
+ = PGroongaのノーマライザー\n(NormalizerNFKC130)
182
+
183
+ # RT
184
+ delimiter = [|]
185
+
186
+ id | content
187
+
188
+ 5 | kiroguramu
189
+ 6 | kiroguramu
190
+
191
+ = PGroongaのノーマライザー\n(NormalizerNFKC130)
192
+
193
+ * Unify_to_romaji
194
+
195
+ * ローマ字に正規化\nローマ字で読んだときに同じ語は同一視する
196
+ * (e.g. 「kiroguramu」と「きろぐらむ」を同一視。ローマ字読みが同じだから)
197
+
198
+ = オプションの指定方法
199
+
200
+ * 'NormalizerNFKC130\n("オプション名", true)');
201
+
202
+ = 指定可能オプション一覧
203
+
204
+ * NormalizerNFKC130の\nオプション一覧
205
+ * ((<URL:https://groonga.org/ja/docs/reference/normalizers/normalizer_nfkc130.html#syntax>))
206
+
207
+ = PGroongaのトークナイザー\n(デフォルト)
208
+
209
+ # coderay sql
210
+
211
+ CREATE TABLE tokenizer_test (
212
+ title text
213
+ );
214
+ CREATE INDEX pgroonga_content_index ON tokenizer_test USING pgroonga (title);
215
+
216
+ INSERT INTO tokenizer_test VALUES ('京都府 1日目 金閣寺');
217
+ INSERT INTO tokenizer_test VALUES ('京都府 2日目 嵐山');
218
+ INSERT INTO tokenizer_test VALUES ('京都府 3日目 天橋立');
219
+ INSERT INTO tokenizer_test VALUES ('東京都 1日目 スカイツリー');
220
+ INSERT INTO tokenizer_test VALUES ('東京都 2日目 浅草寺');
221
+ INSERT INTO tokenizer_test VALUES ('北海道 1日目 函館');
222
+ INSERT INTO tokenizer_test VALUES ('北海道 2日目 トマム');
223
+ INSERT INTO tokenizer_test VALUES ('北海道 3日目 富良野');
224
+ INSERT INTO tokenizer_test VALUES ('北海道 4日目 美瑛');
225
+ INSERT INTO tokenizer_test VALUES ('北海道 5日目 旭川');
226
+
227
+ SELECT * FROM tokenizer_test WHERE title &@ '京都';
228
+
229
+ = PGroongaのトークナイザー\n(デフォルト)
230
+
231
+ # RT
232
+ delimiter = [|]
233
+
234
+ title
235
+
236
+ 京都府 1日目 金閣寺
237
+ 京都府 2日目 嵐山
238
+ 京都府 3日目 天橋立
239
+ 東京都 1日目 スカイツリー
240
+ 東京都 2日目 浅草寺
241
+
242
+ = トークナイザーの変更
243
+
244
+ 適合率を上げたい
245
+
246
+ = PGroongaのトークナイザー\n(TokenMecab)
247
+
248
+ # coderay sql
249
+
250
+ DROP INDEX pgroonga_content_index;
251
+ CREATE INDEX pgroonga_content_index
252
+ ON tokenizer_test
253
+ USING pgroonga (title)
254
+ WITH (tokenizer='TokenMecab');
255
+
256
+ SELECT * FROM tokenizer_test WHERE title &@ '京都';
257
+
258
+ = PGroongaのトークナイザー\n(TokenMecab)
259
+
260
+ # RT
261
+ delimiter = [|]
262
+
263
+ title
264
+
265
+ 京都府 1日目 金閣寺
266
+ 京都府 2日目 嵐山
267
+ 京都府 3日目 天橋立
268
+
269
+ = トークナイザーの指定方法
270
+
271
+ * tokenizer='トークナイザー名'
272
+
273
+ = 指定可能トークナイザー一覧
274
+
275
+ * 使用可能なトークナイザー
276
+ * ((<URL:https://groonga.org/ja/docs/reference/tokenizers.html>))
277
+
278
+ = ステミング(語幹処理)
279
+
280
+ 語形変化\n意味は同じだが\n語の形が変わる
281
+
282
+ = ステミング(語幹処理)
283
+
284
+ 例えば
285
+
286
+ * develop(原形)
287
+ * developped(過去形)
288
+ * developing(進行形)
289
+
290
+ 意味は同じだが語形は異なる
291
+
292
+ = ステミング(語幹処理)
293
+
294
+ 語幹:単語の変化しない部分
295
+
296
+ = ステミング(語幹処理)
297
+
298
+ (('tag:left'))
299
+ ((*develop*))\n
300
+ ((*develop*))ped\n
301
+ ((*develop*))ing
302
+
303
+ = ステミング(語幹処理)
304
+
305
+ 語幹で検索\n
306
+ ->語形変化後の語も検索できる
307
+
308
+ = PGroongaのステミング\n(未使用)
309
+
310
+ # coderay sql
311
+
312
+ CREATE TABLE steming_test (
313
+ title text
314
+ );
315
+ CREATE INDEX pgroonga_content_index ON steming_test USING pgroonga (title);
316
+
317
+ INSERT INTO tokenizer_test VALUES ('I develop Groonga');
318
+ INSERT INTO tokenizer_test VALUES ('I am developing Groonga');
319
+ INSERT INTO tokenizer_test VALUES ('I developed Groonga');
320
+
321
+ SELECT * FROM tokenizer_test WHERE title &@ 'develop';
322
+
323
+ = PGroongaのステミング\n(未使用)
324
+
325
+ # RT
326
+ delimiter = [|]
327
+
328
+ title
329
+
330
+ I develop Groonga
331
+
332
+ = PGroongaのステミング
333
+
334
+ # coderay sql
335
+
336
+ CREATE INDEX pgroonga_content_index
337
+ ON steming_test
338
+ USING pgroonga (title)
339
+ WITH (plugins='token_filters/stem',
340
+ token_filters='TokenFilterStem');
341
+
342
+ = PGroongaのステミング
343
+
344
+ # RT
345
+ delimiter = [|]
346
+
347
+ title
348
+
349
+ I develop Groonga
350
+ I am developing Groonga
351
+ I developed Groonga
352
+
353
+ = 同義語
354
+
355
+ 同義語:同じ意味を持つ別の語
356
+
357
+ = 同義語
358
+
359
+ 例えば\n
360
+ 「ミルク」と\n「牛乳」
361
+
362
+ = 同義語
363
+
364
+ 意味が同じものはヒットしてほしい
365
+
366
+ = 同義語展開
367
+
368
+ ミルク -> \n
369
+ ミルク OR 牛乳
370
+
371
+ = PGroongaの同義語展開
372
+
373
+ # coderay sql
374
+
375
+ CREATE TABLE synonyms (
376
+ term text PRIMARY KEY,
377
+ synonyms text[]
378
+ );
379
+
380
+ CREATE INDEX synonyms_search ON synonyms USING pgroonga (term pgroonga.text_term_search_ops_v2);
381
+
382
+ INSERT INTO synonyms (term, synonyms) VALUES ('ミルク', ARRAY['ミルク', '牛乳']);
383
+ INSERT INTO synonyms (term, synonyms) VALUES ('牛乳', ARRAY['牛乳', 'ミルク']);
384
+
385
+ CREATE TABLE memos (
386
+ id integer,
387
+ content text
388
+ );
389
+
390
+ INSERT INTO memos VALUES (1, '牛乳石鹸');
391
+ INSERT INTO memos VALUES (2, 'ミルクジャム');
392
+ INSERT INTO memos VALUES (3, 'ストロベリー');
393
+
394
+ CREATE INDEX pgroonga_content_index ON memos USING pgroonga (content);
395
+
396
+ SELECT * FROM memos
397
+ WHERE
398
+ content &@~
399
+ pgroonga_query_expand('synonyms', 'term', 'synonyms', '牛乳');
400
+
401
+ = 同義語展開
402
+
403
+ # RT
404
+ delimiter = [|]
405
+
406
+ id | content
407
+
408
+ 1 | 牛乳石鹸
409
+ 2 | ミルクジャム
410
+
411
+ = 曖昧検索
412
+
413
+ typo対策
414
+
415
+ = 曖昧検索
416
+
417
+ * 似たような語ならヒットする
418
+ (完全一致じゃなくてもヒットする)
419
+
420
+ = 曖昧検索
421
+
422
+ 「テノクロジー」で\n
423
+ 「テクノロジー」がヒット
424
+
425
+ = PGroongaのfuzzy検索
426
+
427
+ # coderay sql
428
+
429
+ CREATE TABLE tags (
430
+ name text
431
+ );
432
+
433
+ CREATE INDEX tags_search ON tags USING pgroonga(name) WITH (tokenizer='');
434
+ INSERT INTO tags VALUES ('テクノロジー');
435
+ INSERT INTO tags VALUES ('テクニカル');
436
+
437
+ SELECT name FROM tags
438
+ WHERE
439
+ name &`
440
+ ('fuzzy_search(name, ' || pgroonga_escape('テノクロジー') || ',
441
+ {"with_transposition": true,
442
+ "max_distance": 1})');
443
+
444
+ = 曖昧検索
445
+
446
+ # RT
447
+ delimiter = [|]
448
+
449
+ name
450
+
451
+ テクノロジー
452
+
453
+ = PGroongaでランキング改善
454
+
455
+ 何を基準に\nランキングを\n決めるのか
456
+
457
+ = PGroongaのスコアリング
458
+
459
+ * TF(PGroongaのデフォルト)
460
+ * TF-IDF
461
+
462
+ = PGroongaのスコアリング\nTF(デフォルト)
463
+
464
+ 単語の((*出現数*))\nが大事
465
+
466
+ = PGroongaのスコアリング\nTF(デフォルト)
467
+
468
+ * 検索キーワードが文書内に多く含まれる文書のスコアーが高くなる
469
+
470
+ = PGroongaのスコアリング\nTF-IDF
471
+
472
+ 単語の((*レア度*))\nが大事
473
+
474
+ = PGroongaのスコアリング\nTF-IDF
475
+
476
+ * 文書に出てくる頻度が高い\n(レア度低い)
477
+ * 文書に出てくる頻度が低い\n(レア度高い)
478
+
479
+ = PGroongaのスコアリング\nTF-IDF
480
+
481
+ # coderay sql
482
+
483
+ CREATE TABLE memos (
484
+ title text,
485
+ content text
486
+ );
487
+
488
+ CREATE INDEX pgroonga_memos_index
489
+ ON memos
490
+ USING pgroonga (content);
491
+ INSERT INTO memos VALUES ('PostgreSQL', 'PostgreSQLはリレーショナル・データベース管理システムです。');
492
+ INSERT INTO memos VALUES ('Groonga', 'Groongaは日本語対応の高速な全文検索エンジンです。');
493
+ INSERT INTO memos VALUES ('PGroonga', 'PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。');
494
+ INSERT INTO memos VALUES ('コマンドライン', 'groongaコマンドがあります。');
495
+
496
+ SELECT *, pgroonga_score(tableoid, ctid) AS score
497
+ FROM memos
498
+ WHERE content &@~
499
+ ('PostgreSQL OR 検索',
500
+ ARRAY[1],
501
+ ARRAY['scorer_tf_idf($index)'],
502
+ 'pgroonga_memos_index')::pgroonga_full_text_search_condition_with_scorers
503
+ ORDER BY score DESC;
504
+
505
+ = PGroongaのスコアリング\nTF-IDF
506
+
507
+ # RT
508
+ delimiter = [|]
509
+
510
+ title | score
511
+
512
+ Groonga | 1.3862943649291992
513
+ PostgreSQL | 1
514
+ PGroonga | 1
515
+
516
+ = 参考資料
517
+
518
+ * PGroonga自体の解説
519
+
520
+ * ((<URL:https://www.slideshare.net/kou/postgresql-conference-japan-2017>))