Частота слов TfidfVectorizer от sklearn?

У меня есть вопрос о TfidfVectorizer sklearn, когда он определяет частоту слова в каждом документе.

пример кода, который я видел:

>>> from sklearn.feature_extraction.text import TfidfVectorizer

>>> corpus = [

>>>     'The dog ate a sandwich and I ate a sandwich',
>>>     'The wizard transfigured a sandwich'
>>> ]

>>> vectorizer = TfidfVectorizer(stop_words='english')

>>> print vectorizer.fit_transform(corpus).todense()

[[ 0.75458397  0.37729199  0.53689271  0.          0.        ]
[ 0.          0.          0.44943642  0.6316672   0.6316672 ]]

мой вопрос: как мне интерпретировать числа в матрице? Я понимаю, что 0 означает, что слово, т.е. мастер, появляется 0 раз в первом документе, следовательно, это 0, но как мне интерпретировать число 0,75458397? Частота появления слова «съел» в первом документе? Или частота слова "съел" во всем корпусе?


person user3175707    schedule 02.03.2016    source источник


Ответы (5)


TF-IDF (что означает "частота термина – обратная частота документа") не дает вам частоту термина в его представлении.

TF-IDF дает высокие баллы терминам, встречающимся только в очень немногих документах, и низкие баллы терминам, встречающимся во многих документах, поэтому, грубо говоря, это мера того, насколько дискриминационным является термин в данном документе. Взгляните на этот ресурс, чтобы найти отличное описание TF-IDF и получить лучшее представление о том, что он делает.

Если вам нужны только подсчеты, вам нужно использовать CountVectorizer.

person tttthomasssss    schedule 03.03.2016
comment
exam_row=tv_df.iloc[0] print(examine_row.sort_values(ascending=False)) Чем выше число, тем чаще оно используется в документе - person Golden Lion; 04.09.2020
comment
Как можно получить частоты терминов в одиночку? CountVectorizer возвращает количество, а не частоту... - person Rylan Schaeffer; 08.06.2021
comment
Можно уточнить, что вы имеете в виду под частотой? т.е. частота, поскольку термин «частота» означает количество. - person tttthomasssss; 11.06.2021

Я думаю, вы забываете, что векторы TF-IDF обычно нормализуются, поэтому они всегда имеют величину (длину или 2-норму) 1.

Таким образом, значение TFIDF 0.75 представляет собой частоту "съесть", умноженную на обратную частоту документа "съел", а затем деленную на величину этого вектора TF-IDF.

Вот все грязные подробности (перейдите к tfidf0 = для изюминки):

from sklearn.feature_extraction.text import TfidfVectorizer
corpus = ["The dog ate a sandwich and I ate a sandwich",
          "The wizard transfigured a sandwich"]
vectorizer = TfidfVectorizer(stop_words='english')
tfidfs = vectorizer.fit_transform(corpus)


from collections import Counter
import pandas as pd

columns = [k for (v, k) in sorted((v, k)
           for k, v in vectorizer.vocabulary_.items())]
tfidfs = pd.DataFrame(tfidfs.todense(),
                      columns=columns)
#     ate   dog  sandwich  transfigured  wizard 
#0   0.75  0.38      0.54          0.00    0.00
#1   0.00  0.00      0.45          0.63    0.63

df = (1 / pd.DataFrame([vectorizer.idf_], columns=columns))
#     ate   dog  sandwich  transfigured  wizard
#0   0.71  0.71       1.0          0.71    0.71
corp = [txt.lower().split() for txt in corpus]
corp = [[w for w in d if w in vectorizer.vocabulary_] for d in corp]
tfs = pd.DataFrame([Counter(d) for d in corp]).fillna(0).astype(int)
#    ate  dog  sandwich  transfigured  wizard
#0    2    1         2             0       0
#1    0    0         1             1       1

# The first document's TFIDF vector:
tfidf0 = tfs.iloc[0] * (1. / df)
tfidf0 = tfidf0 / pd.np.linalg.norm(tfidf0)
#        ate       dog  sandwich  transfigured  wizard
#0  0.754584  0.377292  0.536893           0.0     0.0

tfidf1 = tfs.iloc[1] * (1. / df)
tfidf1 = tfidf1 / pd.np.linalg.norm(tfidf1)
#    ate  dog  sandwich  transfigured    wizard
#0   0.0  0.0  0.449436      0.631667  0.631667
person hobs    schedule 07.03.2018

Просто напечатайте ниже код, вы увидите что-то вроде этого

#(0, 1)        0.448320873199    Document 1, term = Dog
#(0, 3)        0.630099344518    Document 1, term = Sandwitch

    print(vectorizer.fit_transform(corpus))  
# if python 3 other wise remove () in print
person Sarmad Mahar    schedule 06.06.2018

ПРИМЕЧАНИЕ. Используйте это, если у вас есть только униграммы.

tfidfvectorizer sklearn не даст вам прямой счет. Чтобы получить количество, вы можете использовать TfidfVectorizer метод класса inverse_transform и build_tokenizer

from sklearn.feature_extraction.text import TfidfVectorizer
corpus = [
    'The dog ate a sandwich and I ate a sandwich',
    'The wizard transfigured a sandwich'
]

vectorizer = TfidfVectorizer(stop_words='english')

X = vectorizer.fit_transform(corpus)
X_words = tfidf.inverse_transform(X) ## this will give you words instead of tfidf where tfidf > 0

tokenizer = vectorizer.build_tokenizer() ## return tokenizer function used in tfidfvectorizer

for idx,words in enumerate(X_words):
    for word in words:
        count = tokenizer(corpus[idx]).count(word)
        print(idx,word,count)

Выход

0 dog 1
0 ate 2
0 sandwich 2
1 sandwich 1
1 wizard 1
1 transfigured 1
#0 means first sentence in corpus 

Это обходной путь, надеюсь, кому-то поможет :)

person deusxmachine    schedule 27.07.2019

это должно быть vectorizer в строке X_words = tfidf.inverse_transform(X) вместо tfidf.

person pinkwatermelon    schedule 13.01.2020