si j'ai deux chaînes dans mysql:
@ a = "Bienvenue dans Stack Overflow" @ b = "Bonjour pour déborder la pile";
existe-t-il un moyen d'obtenir le pourcentage de similitude entre ces deux chaînes en utilisant MYSQL? ici par exemple 3 mots sont similaires et donc la similitude devrait être quelque chose comme:
count (mots similaires entre @a et @b)/(count (@a) + count (@b) - count (intersection))
et donc le résultat est 3/(4 + 4 - 3) = 0,6
toute idée est très appréciée!
vous pouvez utiliser cette fonction (cop ^ H ^ H ^ Hadapted from http://www.artfulsoftware.com/infotree/queries.php#552 ):
CREATE FUNCTION `levenshtein`( s1 text, s2 text) RETURNS int(11)
DETERMINISTIC
BEGIN
DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
DECLARE s1_char CHAR;
DECLARE cv0, cv1 text;
SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
IF s1 = s2 THEN
RETURN 0;
ELSEIF s1_len = 0 THEN
RETURN s2_len;
ELSEIF s2_len = 0 THEN
RETURN s1_len;
ELSE
WHILE j <= s2_len DO
SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
END WHILE;
WHILE i <= s1_len DO
SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
WHILE j <= s2_len DO
SET c = c + 1;
IF s1_char = SUBSTRING(s2, j, 1) THEN
SET cost = 0; ELSE SET cost = 1;
END IF;
SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
IF c > c_temp THEN SET c = c_temp; END IF;
SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
IF c > c_temp THEN
SET c = c_temp;
END IF;
SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
END WHILE;
SET cv1 = cv0, i = i + 1;
END WHILE;
END IF;
RETURN c;
END
et pour l'obtenir comme XX% utilisez cette fonction
CREATE FUNCTION `levenshtein_ratio`( s1 text, s2 text ) RETURNS int(11)
DETERMINISTIC
BEGIN
DECLARE s1_len, s2_len, max_len INT;
SET s1_len = LENGTH(s1), s2_len = LENGTH(s2);
IF s1_len > s2_len THEN
SET max_len = s1_len;
ELSE
SET max_len = s2_len;
END IF;
RETURN ROUND((1 - LEVENSHTEIN(s1, s2) / max_len) * 100);
END
Je ne pense pas qu'il existe une méthode de requête agréable en une seule étape pour le faire - le langage naturel est principalement conçu pour la recherche "de type Google", ce qui semble différent de ce que vous essayez de faire.
Selon ce que vous essayez réellement de faire - je suppose que vous avez omis beaucoup de détails - je voudrais:
créez un tableau dans lequel vous divisez chaque chaîne en mots, tout en minuscules, en supprimant les espaces et la ponctuation - dans votre exemple, vous vous retrouvez avec:
string_id Word
1 hello
1 from
1 stack
1 overflow
2 welcome
2 from
2 stack
2 overflow
Vous pouvez ensuite exécuter des requêtes sur cette table - par exemple.
select count(*)
from stringWords
where string_id = 2
and Word in
(select Word
from stringWords
where string_id = 1);
vous donne l'intersection.
Vous pouvez ensuite créer une fonction ou similaire pour calculer la similitude selon votre formule.
Pas très propre, mais il devrait fonctionner assez rapidement, il est principalement relationnel et devrait être largement indépendant de la langue. Pour faire face à d'éventuelles fautes de frappe, vous pouvez calculer le soundex - cela vous permettrait de comparer "stack" avec "stak" et de voir à quel point ils sont similaires, bien que cela ne fonctionne pas de manière fiable pour des langues autres que l'anglais.
Vous pouvez essayer l'algorithme SOUNDEX, jetez un œil ici :)
EDIT 1:
Peut-être que ce lien sur le traitement du langage naturel avec MySQL pourrait être utile
Recherches en texte intégral en langage naturel
Comment trouver des résultats similaires et trier par similitude?
HTH!
Cela pourrait vous être utile si vous ne souhaitez pas écrire vos propres algorithmes:
http://dev.mysql.com/doc/refman/5.0/en/fulltext-natural-language.html