これは、出版物「都市住所検索の国際化」の続きです。ロシア語のSoundexをSphinxSearchに実装する」では、キリル文字で書かれたテキストに対して、SphinxSearchで音声Soundexアルゴリズムのサポートを実装する方法について説明しました。Soundexのサポートは、ラテン語のテキストですでに利用可能です。ラテンアルファベットについてはMetphoneと同じですが、キリル文字については同じではありませんが、音訳、正規表現、およびファイルを使用して、この厄介な事実を修正しようとします。
これは直接の続きであり、元のメタフォン、ロシア語のメタフォン(音訳が不要という意味で)、Caverphoneの実装方法を分析し、ダブルメタフォンを作成することはできません。
この実装は、SphinxSearchプラットフォームとManticoreSearchプラットフォームの両方に適しています。
最後に、Metaphoneがrakomakophoneをどのように認識するかを見てみましょう。
Dockerイメージ
結果を「感じる」ことができるように、Dockerイメージtkachenkoivan / searchfoneticを準備しました。このパブリケーションと前のパブリケーションのすべてのインデックスが画像に追加されていますが、注意してください。前のパブリケーションのインデックスの名前は、画像に保存されているものと一致していません。どうして?良い考えが後に来るからです。
アルゴリズムの説明は、すべて同じですが、出版物「音声アルゴリズム」から取られました。そこに書かれている文章はなるべく複製しないようにしています。
オリジナルのメタフォン
これは基本的な方法で実装され、音訳の正規表現が作成されます。
regexp_filter = (|) => a
regexp_filter = (|) => b
regexp_filter = (|) => v
…
そして、メタフォンをオンにします。
morphology = metaphone
, Soundex. , , , Soundex , Soundex, – , .
, , , Metaphone + . .
Sphinx blend_chars. , Sphinx , , , , – , , , .., .. , , , , «&». «M&M’s» ? «&»? blend_chars
.
, blend_chars
:
blend_chars = U+0020
, - “ ”, , , . , , .
mysql> select * from metaphone where match('');
+------+--------------------------------------+-----------+---------------------------+
| id | aoguid | shortname | offname |
+------+--------------------------------------+-----------+---------------------------+
| 1130 | e21aec85-0f63-4367-b9bb-1943b2b5a8fb | | |
+------+--------------------------------------+-----------+---------------------------+
, « », call keywords
:
mysql> call keywords (' ', 'metaphone');
+------+---------------+------------+
| qpos | tokenized | normalized |
+------+---------------+------------+
| 1 | morisa toreza | MRSTRS |
| 1 | morisa | MRS |
| 2 | toreza | TRS |
+------+---------------+------------+
, : «morisa», «toreza» «morisa toreza», Metaphone, «».
Metaphone Sphinx Search. , . , , :
regexp_filter = [ ] =>
« », , , .
, , , .
Caverphone , .
mysql> call keywords (' ', 'caverphone');
+------+-----------+------------+
| qpos | tokenized | normalized |
+------+-----------+------------+
| 1 | mrsa trza | mrsa trza |
| 1 | mrsa | mrsa |
| 2 | trza | trza |
+------+-----------+------------+
mysql> select * from caverphone where match('');
Empty set (0.00 sec)
Soundex ( ), Sphinx, , , , , «morisa» «toreza» , «morisa toreza» :
mysql> call keywords (' ', 'simple_soundex');
+------+---------------+---------------+
| qpos | tokenized | normalized |
+------+---------------+---------------+
| 1 | morisa toreza | morisa toreza |
| 1 | morisa | m620 |
| 2 | toreza | t620 |
+------+---------------+---------------+
blend_chars
– , . metaphone. ( ) – : , .
.
Double Metaphone
Metaphone , , , .
, , Metaphone . , , , , DoubleMetaphone.java. , «C», , .
, , – , , , Sphinx Manticore.
, Metaphone . , . Sphinx . .
, , Java, Commons Codec. – , . , – , .
, , , . – .
, , :
DoubleMetaphone dm = new DoubleMetaphone();
String metaphone1 = dm.doubleMetaphone("Text", false);
String metaphone2 = dm.doubleMetaphone("Text", true);
metaphone1
metaphone2
.
– .
, Commons Codec. , . Metaphone , , . , : , , .
Sphinx .
Metaphone
.
. , . « », « Metaphone».
, , , .
, , . , « », «», «» , :
mysql> call keywords (' ', 'rus_metaphone');
+------+--------------+--------------+
| qpos | tokenized | normalized |
+------+--------------+--------------+
| 1 | | |
| 2 | | |
+------+--------------+--------------+
. , , GitHub Gist manticore.conf.
:
regexp_filter = (?i)(|||) =>
regexp_filter = (?i)(||) =>
regexp_filter = (?i)(||) =>
regexp_filter = (?i)() =>
, , , , , :
regexp_filter = (?i)()(||||||||||||||||) => \2
regexp_filter = (?i)()(||||||||||||||||) => \2
regexp_filter = (?i)()(||||||||||||||||) => \2
regexp_filter = (?i)()(||||||||||||||||) => \2
regexp_filter = (?i)()(||||||||||||||||) => \2
regexp_filter = (?i)()(||||||||||||||||) => \2
,
regexp_filter = (?i)\b => regexp_filter = (?i)\b => regexp_filter = (?i)\b => regexp_filter = (?i)\b => regexp_filter = (?i)\b => regexp_filter = (?i)\b =>
regexp_filter = (?i)(||) =>
Caverphone
.
, :
regexp_filter = (A|a) => a
regexp_filter = (B|b) => b
…
, , , , .
e
regexp_filter = e\b =>
, , :
regexp_filter = \b(cough) => cou2f regexp_filter = \b(rough) => rou2f …
regexp_filter = (cq) => 2q
regexp_filter = (ci) => si
…
a, — 3
regexp_filter = (?i)\b(a|e|i|o|u|y) => A
regexp_filter = (?i)(a|e|i|o|u|y) => 3
regexp_filter = (j) => y
regexp_filter = \b(y3) => Y3
…
2
regexp_filter = 2 =>
3, A
regexp_filter = 3\b => A
3
regexp_filter = 3 =>
10 .
:
mysql> select * from caverphone where match ('');
+------+--------------------------------------+-----------+------------------+
| id | aoguid | shortname | offname |
+------+--------------------------------------+-----------+------------------+
| 5 | 01339f2b-6907-4cb8-919b-b71dbed23f06 | | |
| 387 | 4b919f60-7f5d-4b9e-99af-a7a02d344767 | | |
+------+--------------------------------------+-----------+------------------+
«» «». , , , Daitch Mokotoff Soundex - «»:
mysql> select * from daitch_mokotoff_soundex where match ('');
+------+--------------------------------------+-----------+--------------+
| id | aoguid | shortname | offname |
+------+--------------------------------------+-----------+--------------+
| 387 | 4b919f60-7f5d-4b9e-99af-a7a02d344767 | | |
| 541 | 69b8220e-a42d-4fec-a346-1df56370c363 | | |
+------+--------------------------------------+-----------+--------------+
:
mysql> call keywords (' ', 'caverphone');
+------+-----------+------------+
| qpos | tokenized | normalized |
+------+-----------+------------+
| 1 | lnna | lnna |
| 2 | lnna | lnna |
| 3 | lna | lna |
+------+-----------+------------+
mysql> call keywords (' ', 'daitch_mokotoff_soundex');
+------+-----------+------------+
| qpos | tokenized | normalized |
+------+-----------+------------+
| 1 | 866 | 866 |
| 2 | 8616 | 8616 |
| 3 | 866 | 866 |
+------+-----------+------------+
, , , - . , .
: .
, , . Just for fun.
, rock the microphone?! , Metaphone . !
-, blend_chars, rock the microphone, :
blend_chars = U+0020
- metaphone, .
keywords
Sphinx:
mysql> call keywords ('', 'metaphone');
+------+-------------+------------+
| qpos | tokenized | normalized |
+------+-------------+------------+
| 1 | rakomakofon | RKMKFN |
+------+-------------+------------+
rock the microphone:
mysql> call keywords ('rock the microphone', 'metaphone');
+------+---------------------+------------+
| qpos | tokenized | normalized |
+------+---------------------+------------+
| 1 | rock the microphone | RK0MKRFN |
| 1 | rock | RK |
| 2 | the | 0 |
| 3 | microphone | MKRFN |
+------+---------------------+------------+
RK0MKRFN, RKMKFN, 2(!). the , RKMKRFN:
mysql> call keywords ('rock microphone', 'metaphone');
+------+-----------------+------------+
| qpos | tokenized | normalized |
+------+-----------------+------------+
| 1 | rock microphone | RKMKRFN |
| 1 | rock | RK |
| 2 | microphone | MKRFN |
+------+-----------------+------------+
RKMKRFN RKMKFN, 1! .
«the», stopwords , - blend_chars = U+0020
«the» . , 1, .
希望qsuggest
は実現しませんでした-それはヒントを与えません。どうして?keywords
2つの列がtokenized
ありnormalized
、qsuggest
が列にヒントを与えtokenized
、qsuggest
それに対するレーベンシュタインの距離を測定すると、でnormalized
、距離が1であるかどうかは関係ありません。
したがって、観察は面白いですが、実用的ではありません。