An interviewer asks: "Implement TF-IDF without a library." TF-IDF scores a word in a document by how often it appears there, the term frequency (tf), times how rare it is across all the documents, the inverse document frequency (idf). The idf is log(N / df): N is the number of documents and df the number of documents the word is in. A word in every document gets log(1) = 0, however often it appears.
The starting code has 4 short reviews, a vocabulary function that gives back their distinct words, sorted, and in tfidf an array counts of zeros with one row per document and one column per word. .split() gives back a string's words, cut at the spaces, and words.index(word) gives back a word's position in the list, which is its column.
Three numpy tools finish the job. a > 0 gives back True or False for each value, and .sum(axis=0) counts the Trues of each column. np.log gives back the natural log of each number. And multiplying a table by a row of numbers multiplies every row of the table, column by column. On another array:
a = np.array([[2, 0], [1, 3]])
print((a > 0).sum(axis=0)) # [2 1]: 2 values above 0 in column 0, 1 in column 1
print(a * np.array([10, 0])) # every row times [10, 0]: [[20, 0], [10, 0]]
With the 4 reviews of the starting code, the program must print:
Words: ['great', 'is', 'lamp', 'mug', 'price', 'teapot', 'the'] Last review: [0. 0. 0. 0.693 1.386 0. 0. ] the mug is great -> mug the lamp is great -> lamp the teapot is great -> teapot great price great mug -> price
Your task: inside tfidf(docs, words), fill counts with two nested loops (for each document, for each of its words, add 1 at the word's column), then compute df and idf and return the counts times the idf. The hidden check compares your numbers with scikit-learn's TfidfVectorizer.
Assignment
Follow the Coding Tutorial to count the words, then weigh the counts with the idf.
Hint
'great' is in all 4 reviews, so its idf is log(4 / 4) = 0 and it never wins, even in the review where it appears twice. The words come from the documents themselves, so every df is at least 1 and the log never divides by zero.
Free plan: 30 tutor messages. PRO is unlimited.
