前提・実現したいこと
MySQLの「FULLTEXT INDEX」を利用し、類似のコンテンツに対し「すでに類似がありますよ」というレスポンスを表示することを目指しています。
類似スコアの算定は「AGAINST、MATCH」で実装しました。
発生している問題
吾輩は猫である
というデータに対し、
吾輩は、猫である
と言う風に、
を加えて検索すると、類似スコアが「0」になるという問題に苦慮しています。
明らかに(我々人間にとっては)類似性が高いのに、なんとかならないでしょうか…
該当のソースコード
以下の設計となっています。
MySQL
1-- 2-- テーブルの構造 `contents` 3-- 4CREATE TABLE IF NOT EXISTS `contents` ( 5 `ID` bigint(20) unsigned NOT NULL, 6 `content` varchar(1000) CHARACTER SET utf8mb4 NOT NULL 7) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; 8 9-- 10-- テーブルのデータのダンプ `contents` 11-- 12INSERT INTO `contents` (`ID`, `content`) VALUES 13(1, '智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。兎角に人の世は住みにくい。'), 14(2, '吾輩は猫である。'), 15(3, '吾輩は猫である。名前はまだ無い。どこで生れたか頓(とん)と見當がつかぬ。'), 16(4, 'きょう、ママンが死んだ。 もしかすると、昨日かも知れないが、私にはわからない。');
類似スコアが「0」になるという問題のコードはこちらです。
MySQL
1# score = 0 2SELECT ID, content, MATCH (content) 3AGAINST( 4 '吾輩は、猫である。' 5 IN NATURAL LANGUAGE MODE 6) AS score 7FROM contents
試したこと
長い文字数では、
があるだけの違いでも十分に類似性が高い値となりました。
例えば ID=1 の
智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。兎角に人の世は住みにくい。
というデータに対し、同じように、
を1つ加えて
智に働けば、角が立つ。情に棹させば流される。意地を通せば窮屈だ。兎角に人の世は住みにくい。
とすると、スコアは「1.465677261352539」となります。
# score = 1.465677261352539 SELECT ID, content, MATCH (content) AGAINST( '智に働けば、角が立つ。情に棹させば流される。意地を通せば窮屈だ。兎角に人の世は住みにくい。' IN NATURAL LANGUAGE MODE ) AS score FROM contents
この違いから、「類似スコアを、文字数の逆数の2乗する」などのように後から指数関数的に大きく倍すれば、文字数が短いものでも大きな類似スコアとなるか?とも考えましたが、結局「0」にいくつかけても「0」なのでこのままでは難しそうです。
なのでもし類似スコアの小数点をもっと小さく(現状0と表示されているその先まで)表示する方法があれば…、と考えた経緯から、質問を投稿させていただく運びとなった次第でございます。
または全ての類似スコアを全体的に底上げする方法があれば…とも考えられます。
もちろんこれらの方法に留まらず、「すでに類似がありますよ」というレスポンスを表示する。という目的に適った別のアプローチも募集させて頂ければ幸いです。
補足情報(FW/ツールのバージョンなど)
MySQLのバージョンは5.7.31 で、Xサーバーの利用になります。
ご回答どうぞ宜しくお願い致します。
###追記
検索用文字列を追加してみてはどうかと思いました、が、本来の文字列との類似性よりも、検索用文字列との類似性の方のスコアが色濃く出てしまい使えませんでした。こうです。
まず検索用文字列として__MY_FULLTEXT__この文は検索用です
を追加します。
MySQL
1UPDATE contents 2SET content = CONCAT(content, '__MY_FULLTEXT__この文は検索用です')
そして検索します。
MySQL
1SELECT ID, content, MATCH (content) 2AGAINST( 3 '吾輩は、猫である。__MY_FULLTEXT__この文は検索用です' 4 IN NATURAL LANGUAGE MODE 5) AS score 6FROM contents
これにより ID=2 の
吾輩は猫である。__MY_FULLTEXT__この文は検索用です
の類似スコアが「0.25517651438713074」と上昇しましたが、
反面で ID=1 の
智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。兎角に人の世は住みにくい。__MY_FULLTEXT__この文は検索用です
もまた「0.25517651438713074」になってしまいました。
つまり本来の文字列との類似性よりも、検索用文字列との類似性の方のスコアが色濃く出てしまったらしく、これでは目的を果たすことはできませんでした。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/01/01 13:15