Tout d'abord, si vous voulez extraire des caractéristiques de comptage et appliquer la normalisation TF-IDF et la normalisation euclidienne par rangée, vous pouvez le faire en une seule opération avec TfidfVectorizer
:
>>> from sklearn.feature_extraction.text import TfidfVectorizer
>>> from sklearn.datasets import fetch_20newsgroups
>>> twenty = fetch_20newsgroups()
>>> tfidf = TfidfVectorizer().fit_transform(twenty.data)
>>> tfidf
<11314x130088 sparse matrix of type '<type 'numpy.float64'>'
with 1787553 stored elements in Compressed Sparse Row format>
Maintenant, pour trouver les distances en cosinus d'un document (par exemple, le premier de l'ensemble de données) et de tous les autres, il suffit de calculer les produits scalaires du premier vecteur avec tous les autres, car les vecteurs tfidf sont déjà normalisés par ligne.
Comme l'explique Chris Clark dans les commentaires et ici La similitude en cosinus ne tient pas compte de la magnitude des vecteurs. Les vecteurs normalisés en ligne ont une magnitude de 1. Le noyau linéaire est donc suffisant pour calculer les valeurs de similarité.
L'API des matrices éparses de scipy est un peu bizarre (pas aussi flexible que les tableaux denses à N dimensions de numpy). Pour obtenir le premier vecteur, vous devez découper la matrice en lignes pour obtenir une sous-matrice avec une seule ligne :
>>> tfidf[0:1]
<1x130088 sparse matrix of type '<type 'numpy.float64'>'
with 89 stored elements in Compressed Sparse Row format>
scikit-learn fournit déjà des métriques par paire (aussi appelées noyaux dans le jargon de l'apprentissage automatique) qui fonctionnent pour les représentations denses et éparses des collections de vecteurs. Dans ce cas, nous avons besoin d'un produit scalaire, également connu sous le nom de noyau linéaire :
>>> from sklearn.metrics.pairwise import linear_kernel
>>> cosine_similarities = linear_kernel(tfidf[0:1], tfidf).flatten()
>>> cosine_similarities
array([ 1. , 0.04405952, 0.11016969, ..., 0.04433602,
0.04457106, 0.03293218])
Ainsi, pour trouver les 5 premiers documents liés, nous pouvons utiliser argsort
et un découpage négatif du tableau (les documents les plus liés ont les valeurs de similarité en cosinus les plus élevées, donc à la fin du tableau des indices triés) :
>>> related_docs_indices = cosine_similarities.argsort()[:-5:-1]
>>> related_docs_indices
array([ 0, 958, 10576, 3277])
>>> cosine_similarities[related_docs_indices]
array([ 1. , 0.54967926, 0.32902194, 0.2825788 ])
Le premier résultat est un contrôle de cohérence : nous trouvons le document de la requête comme le document le plus similaire avec un score de similarité cosinusoïdale de 1 qui a le texte suivant :
>>> print twenty.data[0]
From: lerxst@wam.umd.edu (where's my thing)
Subject: WHAT car is this!?
Nntp-Posting-Host: rac3.wam.umd.edu
Organization: University of Maryland, College Park
Lines: 15
I was wondering if anyone out there could enlighten me on this car I saw
the other day. It was a 2-door sports car, looked to be from the late 60s/
early 70s. It was called a Bricklin. The doors were really small. In addition,
the front bumper was separate from the rest of the body. This is
all I know. If anyone can tellme a model name, engine specs, years
of production, where this car is made, history, or whatever info you
have on this funky looking car, please e-mail.
Thanks,
- IL
---- brought to you by your neighborhood Lerxst ----
Le deuxième document le plus similaire est une réponse qui cite le message original et comporte donc de nombreux mots communs :
>>> print twenty.data[958]
From: rseymour@reed.edu (Robert Seymour)
Subject: Re: WHAT car is this!?
Article-I.D.: reed.1993Apr21.032905.29286
Reply-To: rseymour@reed.edu
Organization: Reed College, Portland, OR
Lines: 26
In article <1993Apr20.174246.14375@wam.umd.edu> lerxst@wam.umd.edu (where's my
thing) writes:
>
> I was wondering if anyone out there could enlighten me on this car I saw
> the other day. It was a 2-door sports car, looked to be from the late 60s/
> early 70s. It was called a Bricklin. The doors were really small. In
addition,
> the front bumper was separate from the rest of the body. This is
> all I know. If anyone can tellme a model name, engine specs, years
> of production, where this car is made, history, or whatever info you
> have on this funky looking car, please e-mail.
Bricklins were manufactured in the 70s with engines from Ford. They are rather
odd looking with the encased front bumper. There aren't a lot of them around,
but Hemmings (Motor News) ususally has ten or so listed. Basically, they are a
performance Ford with new styling slapped on top.
> ---- brought to you by your neighborhood Lerxst ----
Rush fan?
--
Robert Seymour rseymour@reed.edu
Physics and Philosophy, Reed College (NeXTmail accepted)
Artificial Life Project Reed College
Reed Solar Energy Project (SolTrain) Portland, OR
3 votes
Pour chaque vecteur de trainVectorizerArray, vous devez trouver la similarité en cosinus avec le vecteur de testVectorizerArray.
0 votes
@excray Merci, avec votre aide j'ai réussi à comprendre, dois-je mettre la réponse ?
0 votes
@excray Mais j'ai une petite question, en fait le calcul tf*idf n'est pas utile pour cela, car je n'utilise pas les résultats finaux qui sont montrés dans la matrice.
5 votes
Voici la 3ème partie du tutoriel que vous citez qui répond en détail à votre question pyevolve.sourceforge.net/wordpress/?p=2497
0 votes
@ClémentRenaud j'ai suivi le lien que vous avez fourni mais comme mes documents sont plus grands, il commence à lancer MemoryError Comment pouvons-nous gérer cela ?