Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Classer des documents avec la similarité cosinus

Après cette leçon: Je peux classer des documents selon l’angle entre leur vecteur et celui de la requête.

Leçon de 60 min1 commandeLab JupyterLab de science des données : pandas, Matplotlib et scikit-learn dans le navigateur

Comment comparer une requête à chaque document

Le modèle vectoriel représente chaque document et chaque requête par une liste de nombres, un nombre par mot du vocabulaire. Le cosinus de l’angle entre deux listes dit à quel point elles se ressemblent.

Une étudiante tape « restaurant ouvre ». Le moteur doit classer les fiches de la plus proche à la plus lointaine, même si aucune ne contient exactement ces deux mots.

À la fin de cette leçon

Remarque

Je peux classer des documents selon l’angle entre leur vecteur et celui de la requête.

Mots clés

MotCe que ça veut direExemple
Vocabulairela liste de mots qui fixe les positions du vecteur
Vecteurune liste de nombres, un par mot du vocabulaire[1, 0, 1, 0]
Produit scalairela somme des produits, position par position
Normela longueur d’un vecteur
Similarité cosinusle produit scalaire divisé par les deux normes

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Un document devient une liste de comptes

On choisit un vocabulaire, ici quatre mots : restaurant, bibliotheque, ouvre, trois. Le vecteur d’un texte donne le nombre d’apparitions de chaque mot, dans cet ordre.

La requête est traitée comme un petit document : « restaurant ouvre » devient [1, 0, 1, 0].

Exemple travaillé : quatre documents en vecteurs

DocumentrestaurantbibliothequeouvretroisVecteur
0 : le restaurant universitaire ouvre a midi1010[1, 0, 1, 0]
1 : la bibliotheque universitaire ouvre a huit heures0110[0, 1, 1, 0]
2 : le restaurant propose un menu a trois euros1001[1, 0, 0, 1]
3 : la bibliotheque prete un livre pour trois semaines0101[0, 1, 0, 1]

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Le cosinus mesure l’angle entre deux vecteurs

Le produit scalaire multiplie deux vecteurs position par position, puis additionne. La norme est la racine carrée de la somme des carrés.

La similarité cosinus est le produit scalaire divisé par les deux normes. Elle vaut 1 pour la même direction et 0 sans mot commun. La longueur du texte ne joue pas.

Exemple travaillé : les quatre cosinus

DocumentProduit scalaireNormesCosinus
0 : [1, 0, 1, 0]21,41 et 1,412 / 2 = 1
1 : [0, 1, 1, 0]11,41 et 1,411 / 2 = 0,5
2 : [1, 0, 0, 1]11,41 et 1,411 / 2 = 0,5
3 : [0, 1, 0, 1]01,41 et 1,410

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Calculer un cosinus de deux vecteurs

Commande
docker exec jupyter python3 -c 'print(round(sum(x * y for x, y in zip([1, 0, 1, 0], [0, 1, 1, 0])) / (2 ** 0.5 * 2 ** 0.5), 2))'

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une erreur fréquente

Attention

Beaucoup pensent que le produit scalaire seul suffit pour classer. Un long document a des comptes plus grands et gagnerait toujours. Diviser par les normes ne garde que les proportions de mots.

Calculer un cosinus pas à pas

Code: python
vocabulaire = ["restaurant", "bibliotheque", "ouvre", "trois"]
requete = "restaurant ouvre".split()
document = "la bibliotheque universitaire ouvre a huit heures".split()
a = []
b = []
for mot in vocabulaire:
    a.append(requete.count(mot))
    b.append(document.count(mot))
produit = 0
for n in range(len(a)):
    produit = produit + a[n] * b[n]
norme_a = (a[0] ** 2 + a[1] ** 2 + a[2] ** 2 + a[3] ** 2) ** 0.5
norme_b = (b[0] ** 2 + b[1] ** 2 + b[2] ** 2 + b[3] ** 2) ** 0.5
print(a, b)
print(round(produit / (norme_a * norme_b), 2))
# Remplacez le document par "le restaurant universitaire ouvre a midi", puis relancez.

Classer, c’est trier les documents par cosinus décroissant

On calcule le cosinus de la requête avec chaque document, puis on met le plus grand en tête. En cas d’égalité, on garde l’ordre des numéros.

Dans notre exemple, le document 0 arrive premier avec 1. Les documents 1 et 2 suivent à égalité à 0,5, et le 3 ferme la marche avec 0.

Pour aller plus loin

Dans un carnet de JupyterLab, choisissez un vocabulaire de cinq mots et vos six phrases. Calculez le cosinus de deux requêtes avec chaque phrase.

Les égalités sont-elles fréquentes ? Ajoutez un mot au vocabulaire : le classement change-t-il ?

À propos de ce labo et de sa source: Lab JupyterLab de science des données : pandas, Matplotlib et scikit-learn dans le navigateur

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.