2017-08-14 2 views
2

J'essaie d'obtenir tfidf à partir d'un document. Mais je ne pense pas que cela me donne des valeurs correctes ou que je fasse quelque chose de mal. Veuillez suggérer. Code et sortie ci-dessous:Est-ce correct tfidf?

Update 1: (comme suggéré par juanpa.arrivillaga)

vectorizer = TfidfVectorizer(smooth_idf=False) 

sortie:

script - 0.269290317245 
wordcount - 0.269290317245 
by - 0.269290317245 
read - 0.269290317245 
be - 0.269290317245 
to - 0.269290317245 
book - 0.209127954024 
first - 0.354084405732 
is - 0.269290317245 
this - 0.269290317245 
there - 0.354084405732 
hello - 0.354084405732 
information - 0.0 
... 

sortie après mise à jour 1:

script - 0.256536760895 
wordcount - 0.256536760895 
by - 0.256536760895 
read - 0.256536760895 
be - 0.256536760895 
to - 0.256536760895 
book - 0.182528018244 
first - 0.383055542114 
is - 0.256536760895 
this - 0.256536760895 
there - 0.383055542114 
hello - 0.383055542114 
information - 0.0 
... 

Selon ma compréhension, tfidf est = t f * idf. Et la façon dont je le calcule manuellement comme exemple:

document 1: "Bonjour, c'est le premier livre à être lu par le script wordcount." document 2: "Ceci est le deuxième livre à être lu par le script wordcount, il a quelques informations supplémentaires." document 3: "juste le troisième livre."

TFIDF pour Bonjour:

tf= 1/12(total terms in document 1)= 0.08333333333 
idf= log(3(total documents)/1(no. of document with term in it))= 0.47712125472 
0.08333333333*0.47712125472= 0.03976008865 

qui est différent ci-dessous (bonjour - 0,354084405732).

calcul manuel après mise à jour 1:

tf = 1 
idf= log(nd/df) +1 = log (3/1) +1= 0.47712125472 + 1= 1.47712 
tfidf = tf*idf = 1* 1.47712= 1.47712 

(pas identique à la sortie de code "bonjour - 0,383055542114" après lissage idf)

Toute aide à comprendre ce qui se passe est très apprécié ..

+5

Vous pouvez voir exactement ce qui est utilisé ['here in the docs'] (http://scikit-learn.org/stable/modules/feature_extraction.html#tfidf-term-weighting). Notez que vous n'effectuez pas de lissage IDF, ce que fait 'TfidfVectorizer' par défaut. –

+0

En outre, les docs semblent impliquer que la fréquence du terme est un terme brut fréquence, non normalisé par la longueur du document –

+0

@ juanpa.arrivillaga, pouvez-vous transformer votre commentaire en une réponse - cela pourrait aider les gens à chercher/demander la même chose .. – MaxU

Répondre

2

Voici une sortie sans lissage ou normalisation:

In [2]: from sklearn.feature_extraction.text import TfidfVectorizer 
    ...: books = ["Hello there this is first book to be read by wordcount script.", "This is second book to be read by wordcount sc 
    ...: ript. It has some additionl information.", "just third book."] 
    ...: vectorizer = TfidfVectorizer(smooth_idf=False, norm=None) 
    ...: response = vectorizer.fit_transform(books) 
    ...: feature_names = vectorizer.get_feature_names() 
    ...: for col in response.nonzero()[1]: 
    ...: print(feature_names[col], '-', response[0, col]) 
    ...: 
hello - 2.09861228867 
there - 2.09861228867 
this - 1.40546510811 
is - 1.40546510811 
first - 2.09861228867 
book - 1.0 
to - 1.40546510811 
be - 1.40546510811 
read - 1.40546510811 
by - 1.40546510811 
wordcount - 1.40546510811 
script - 1.40546510811 
this - 1.40546510811 
is - 1.40546510811 
book - 1.0 
to - 1.40546510811 
be - 1.40546510811 
read - 1.40546510811 
by - 1.40546510811 
wordcount - 1.40546510811 
script - 1.40546510811 
second - 0.0 
it - 0.0 
has - 0.0 
some - 0.0 
additionl - 0.0 
information - 0.0 
book - 1.0 
just - 0.0 
third - 0.0 

donc considérer le résultat de "hello":

hello - 2.09861228867 

Maintenant, manuellement:

In [3]: import math 

In [4]: tf = 1 

In [5]: idf = math.log(3/1) + 1 

In [6]: tf*idf 
Out[6]: 2.09861228866811 

Le problème avec votre calcul manuel est que vous utilisez log la base , mais vous devez utiliser le naturel logarithme.

Si vous ressentez encore le désir ardent de passer par les étapes de lissage et de normalisation, cela devrait vous permettre de le faire correctement.

+0

Merci beaucoup pour votre aide. Je le reçois maintenant.Pouvez-vous également suggérer comment supprimer l'avertissement que je reçois avec le même code que "VisibleDeprecationWarning:' rank' est obsolète, utilisez plutôt l'attribut ou la fonction 'ndim'." – Manvi

+0

@Manvi Je n'ai aucune idée d'où vient cet avertissement. Il semble que vous devriez poser une autre question, mais aussi, cela semble assez explicite - n'utilisez pas l'argument 'rank' pour n'importe quelle fonction qui vous donne cet avertissement, utilisez' ndim' ou une fonction à la place ... –

+0

@Manvi il semble que cela provienne de l'implémentation sous-jacente 'sklearn', qui utilise une fonction' scipy' obsolète. Probablement cela a été corrigé - je n'obtiens pas l'avertissement. Essayez de mettre à jour 'sklearn' –