あなたは、どの都市が最も密接に関連しているかをどのように計算するのですか?について質問します。例えば。都市 1 (パリ) を見ていたら、結果は次のようになります: ロンドン (2)、ニューヨーク (3)提供されたデータ セットに基づいて、関連するものは 1 つだけです。それは都市間の共通タグです。共通のタグを共有する都市が最も近いものになります。以下は、共通のタグを共有する都市 (最も近い都市を見つけるために提供されているものを除く) を見つけるサブクエリです。
SELECT * FROM `cities` WHERE id IN (
SELECT city_id FROM `cities_tags` WHERE tag_id IN (
SELECT tag_id FROM `cities_tags` WHERE city_id=1) AND city_id !=1 )
働く
私の場合、「パリ」にはIDが1つあります
SELECT tag_id FROM `cities_tags` WHERE city_id=1
パリが持っているすべてのタグIDが見つかります
SELECT city_id FROM `cities_tags` WHERE tag_id IN (
SELECT tag_id FROM `cities_tags` WHERE city_id=1) AND city_id !=1 )
パリにもあるのと同じタグを持つパリを除くすべての都市を取得します
これがあなたのフィドルです
Jaccardの類似性/インデックスについて読んでいると、実際の用語が何であるかを理解するためのいくつかのものが見つかりました。この例を見てみましょう。2つのセットAとBがあります
A={A, B, C, D, E} を設定
B={I、H、G、F、E、D} を設定します。
ジャカード類似度を計算する式は、JS=(A 交差 B)/(A 結合 B) です。
A と B の交差 = {D,E}= 2
ユニオン B ={A, B, C, D, E,I, H, G, F} =9
JS=2/9 =0.2222222222222222
今、あなたのシナリオに向かってください
パリには tag_ids 1,3 があるので、これのセットを作成し、セット P ={Europe,River} と呼びます。
London には tag_ids 1,3 があるので、これのセットを作成し、Set L ={Europe,River} と呼びます。
New York には tag_ids 2,3 があるので、これのセットを作成し、Set NW ={North America,River} と呼びます。
JS パリをロンドンで計算する JSPL = P 交差 L / P 結合 L 、JSPL = 2/2 = 1
ニューヨークでの JS パリの計算 JSPNW = P 交差 NW / P 結合 NW ,JSPNW = 1/3 = 0.3333333333
以下のフィドルの例を見ることができる完璧なジャカードインデックスを計算するこれまでのクエリは次のとおりです
SELECT a.*,
( (CASE WHEN a.`intersect` =0 THEN a.`union` ELSE a.`intersect` END ) /a.`union`) AS jaccard_index
FROM (
SELECT q.* ,(q.sets + q.parisset) AS `union` ,
(q.sets - q.parisset) AS `intersect`
FROM (
SELECT cities.`id`, cities.`name` , GROUP_CONCAT(tag_id SEPARATOR ',') sets ,
(SELECT GROUP_CONCAT(tag_id SEPARATOR ',') FROM `cities_tags` WHERE city_id= 1)AS parisset
FROM `cities_tags`
LEFT JOIN `cities` ON (cities_tags.`city_id` = cities.`id`)
GROUP BY city_id ) q
) a ORDER BY jaccard_index DESC
上記のクエリでは、カスタム計算エイリアスを取得するために、結果セットを 2 つのサブセレクトに派生させました。

上記のクエリにフィルターを追加して、それ自体との類似性を計算しないようにすることができます
SELECT a.*,
( (CASE WHEN a.`intersect` =0 THEN a.`union` ELSE a.`intersect` END ) /a.`union`) AS jaccard_index
FROM (
SELECT q.* ,(q.sets + q.parisset) AS `union` ,
(q.sets - q.parisset) AS `intersect`
FROM (
SELECT cities.`id`, cities.`name` , GROUP_CONCAT(tag_id SEPARATOR ',') sets ,
(SELECT GROUP_CONCAT(tag_id SEPARATOR ',') FROM `cities_tags` WHERE city_id= 1)AS parisset
FROM `cities_tags`
LEFT JOIN `cities` ON (cities_tags.`city_id` = cities.`id`) WHERE cities.`id` !=1
GROUP BY city_id ) q
) a ORDER BY jaccard_index DESC
この結果は、パリがロンドンと密接に関連しており、次にニューヨークと関連していることを示しています
Jaccard 類似性フィドル