TF-IDF — algoritmo de recomendação
Aprenda o build up de um dos modelos mais aplicados e versátil do mercado.
Na NLP, tf-idf é uma técnica importante incorporada em algoritmos como similaridade de cosseno, distância euclidiana, SVM… com objetivo de encontrar documentos semelhantes a uma determinada consulta de pesquisa.
Uma introdução ao TF-IDF
TF-IDF é o produto da Frequência do Termo e da Frequência Inversa do Documento. Aqui está a fórmula para o cálculo do TF-IDF.
TF-IDF = Term Frequency (TF) * Inverse Document Frequency (IDF)
Como o Tfidfvectorizer da biblioteca sklearn, calcula os valores TF-IDF
Term Frequency (TF) — sklearn usa o número de vezes, um termo ‘t’ aparece em um documento, contudo existem outras maneiras de calcular:
- tf(t) = (Nº de vezes que o termo ‘t’ ocorre em um documento) / (Frequência do termo mais comum em um documento)
- tf(t) = (Nº de vezes que o termo ‘t’ ocorre em um documento) / (Nº de termos em um documento)
Frequência inversa do documento (IDF) — idf é uma medida de quão comum ou raro um termo é em todo os documentos. Portanto, o ponto a ser observado é que é comum a todos os documentos. Se a palavra for comum e aparecer em muitos documentos, o valor idf (normalizado) se aproximará de 0 ou se aproximará de 1 se for raro.
De acordo com a documentação online do sklearn, ele usa o método abaixo para calcular o idf de um termo em um documento.
idf(t) = ln[(1+n)/(1+df(t))]+1
(smooth_idf = True)
e
idf(t) = ln[n/df(t)]+1
(smooth_idf = False)
É possível encontrar também em outro formato, mais simples:
idf(t) = ln[n/df(t)]
onde:
n = Total de documentos
t = termo que necessita ser calculado
df(t) = Número de documentos onde o t é presente
Validar valores TF-IDF na matriz esparsa
Vamos ao exemplo prático:
Quando estiver trabalhando com documentos de textos muito extensos, tente sempre traduzir para inglês e acionar o parâmetro stop_words
, pois assim manterá sua matrix com as palavras mais relevantes. Por enquanto ela só tem no inglês, mas de qualquer maneira você pode utilizar a biblioteca nltk
e configurar uma eliminação em português.
Para começar, a frequência do termo (tf) para cada termo nos documentos é fornecida na tabela acima.
Agora precisa calcular os valores idf para cada termo.
Como mencionado anteriormente, o valor idf de um termo é comum em todos os documentos. Aqui vamos considerar o caso em que smooth_idf = True (comportamento padrão). Então idf(t) é dado por:
idf(t) = ln[(1+n)/(1+df(t))]+1
idf(“beach”) = log e (3/2) +1 => 1,405465083
idf(“going”) = log e (2/2) + 1 => 1
idf(“having”) = log e (2/2) + 1 => 1
idf(“went”) = log e (2/2) + 1 => 1
Calcule tf-idf dos termos em cada documento d1 e d2.
For d1
tf-idf(“beach”) = tf(“beach”) x idf (“beach”) = 2 x 1.405465083 => 2.810930165
tf-idf(“going”) = tf(“going”) x idf (“going”) = 1 x 1 => 1
tf-idf(“having”) = tf(“having”) x idf (“having”) = 1×1 => 1
tf-idf(“went”) = tf(“went”) x idf (“went”) = 1×1 => 1
For d2
tf-idf(“beach”) = tf(“beach”) x idf (“beach”) = 0 x 1.405465083 => 0
tf-idf(“going”) = tf(“going”) x idf (“going”) = 1 x 1 => 1
tf-idf(“having”) = tf(“having”) x idf (“having”) = 1×1 => 1
tf-idf(“went”) = tf(“went”) x idf (“went”) = 1×1 => 1
Então temos a matriz esparsa com forma 2 x 3
Normalizar valores TF-IDF
Para evitar que documentos grandes no corpus dominem os menores, temos que normalizar cada linha na matriz esparsa para ter a norma euclidiana.
D1
2.810930165 / sqrt( 2.810930165 2 + 12 + 12 + 12) => 0.851354321
1 / sqrt( 2.8109301652 + 12 + 12 + 12) => 0.302872811
1 / sqrt( 2.8109301652 + 12 + 12 + 12) => 0.302872811
1 / sqrt( 2.8109301652 + 12 + 12 + 12) => 0.302872811
D2
0 / sqrt(0 2 + 12 + 12 + 12) => 0
1 / sqrt(02 + 12 + 12 + 12)=> 0.577350269
1/ sqrt(02 + 12 + 12 + 12) => 0.577350269
1 / sqrt(02 + 12 + 12 + 12) => 0.577350269
Isso nos dá a matriz esparsa normalizada final:
Caso queira testar, segue o código completo:
Procure sempre entender como funciona as bibliotecas de machine learning, só assim que você conseguirá fugir das frustações em não conseguir resolver problemas reais.