Aller au contenu
Craft Solution Tech

Similarité de Jaccard : la métrique de similarité la plus simple en IA

Une division entre l'intersection et l'union de deux ensembles. Implémentation TypeScript, fuzzy matching par n-grams, et les cas où elle ne suffit pas.

4 min de lecture

Infographie : la formule de Jaccard illustrée par un diagramme de Venn, l'exemple des goûts cinéma aboutissant à 0,33, les domaines d'application et les deux limites de la métrique.
La formule, l'exemple, les usages et les limites — sur un seul écran.

Tu veux comparer deux ensembles et savoir à quel point ils se ressemblent ? La similarité de Jaccard fait ça en une seule division.


La formule

Elle fait peur à première vue 😅:

J(A, B) = |A ∩ B| / |A ∪ B|

En français :

Nombre d'éléments en commun ÷ Nombre total d'éléments uniques

Le résultat est toujours entre 0 (rien en commun) et 1 (identiques). Plus on approche de 1, plus il y a de similitude.


Un exemple concret

Imaginons deux utilisateurs et les films qu'ils ont aimés (exemple très simple) :

const userA = new Set(["Inception", "Matrix", "Interstellar", "Dune"]);
const userB = new Set(["Matrix", "Dune", "Blade Runner", "Arrival"]);

// Intersection (en commun) : Matrix, Dune → 2 éléments
// Union (tous les films uniques) : 6 éléments

const jaccard = 2 / 6; // = 0.33

Ces deux utilisateurs ont 33% de similarité dans leurs goûts cinéma, c’est pas énorme.


Implémentation en TypeScript

function jaccardSimilarity<T>(setA: Set<T>, setB: Set<T>): number {
  const intersection = new Set([...setA].filter(x => setB.has(x)));
  const union = new Set([...setA, ...setB]);

  if (union.size === 0) return 1; // deux ensembles vides = identiques

  return intersection.size / union.size;
}

// Usage
const a = new Set(["chat", "chien", "oiseau"]);
const b = new Set(["chat", "poisson", "oiseau"]);

console.log(jaccardSimilarity(a, b)); // 0.5

Où c'est utilisé en IA ?

DomaineUsage
RecommandationTrouver des utilisateurs avec des goûts similaires
NLP / RechercheComparer des documents via leurs mots-clés
Détection de duplicatasRepérer des textes quasi-identiques
Fuzzy matchingComparer des strings malgré les fautes de frappe
ClusteringRegrouper des éléments similaires

Cas pratique : fuzzy matching avec les n-grams

La puissance de Jaccard vient pas de la formule, mais de comment tu construis tes ensembles avant de l'appliquer.

Exemple : comparer deux textes malgré une faute de frappe.

// Fonction pour découper un texte en bigrams (groupes de 2 caractères)
function toBigrams(str: string): Set<string> {
  const bigrams = new Set<string>();
  const normalized = str.toLowerCase();

  for (let i = 0; i < normalized.length - 1; i++) {
    bigrams.add(normalized.slice(i, i + 2));
  }

  return bigrams;
}

const textA = "bonjour";
const textB = "bojour"; // il manque le 'n'

const bigramsA = toBigrams(textA); // {"bo", "on", "nj", "jo", "ou", "ur"}
const bigramsB = toBigrams(textB); // {"bo", "oj", "jo", "ou", "ur"}

console.log(jaccardSimilarity(bigramsA, bigramsB)); // ≈ 0.57

Résultat : 57% de similarité malgré la faute. C'est comme ça que fonctionnent beaucoup d'outils de détection de plagiat ou de recherche approximative.


Les limites

Jaccard c'est simple et efficace, mais pas adapté à tout :

  • Pas de notion de fréquence : un mot présent 1 fois ou 100 fois, c'est pareil
  • Pas adapté aux vecteurs continus : pour les embeddings, on utilise plutôt la cosine similarity
  • Sensible aux petits ensembles : 2 éléments en commun sur 3 (66%) vs sur 100 (2%).

Je suis actuellement en formation IA et je documente ma progression ici. Si t'as des questions ou des retours, n'hésite pas !

Sujets abordés

  • IA
  • machine learning
  • TypeScript

Dites-nous ce que vous cherchez à construire.

Nous écrire sur WhatsApp
Retour au blog