Lab 5: Information Retrieval and Vector Semantics
As discussed in class, one problem with using the term-document matrix for IR is that cosine similarity on those vectors depends on exact word overlap. One solution we discussed was to learn higher-level "concepts" using SVD—a rudimentary version of the larger concept of vector semantics. In this part of the lab, you'll apply SVD to the term-document matrix to transform your original document vectors into "concept space" where each column represents some higher-level concept that is correlated with multiple words. Then, you'll observe how this transformation impacts the search results.
TASK: Create a WikiDocumentVectors subclass that represents documents using SVD
Our main information retrieval system in WikiSearchEngine was designed to be generic, so thankfully as long as we simply implement an SVD vector model, we can just plug that model in to WikiSearchEngine without having to change any of the IR code. To this end, you will create a new WikiDocumentVectors subclass, which you should name SVDDocumentVectors.
That's the power of object-oriented programming!
Thanks, CS 70!
Remember that SVD works by transforming a term-document matrix, so SVDDocumentVectors will share quite a bit of code with your previous CountDocumentVectors. Therefore, you should start by copying the code from your CountDocumentVectors (yes, I know copy-pasting code is considered bad practice, but we'll let it slide for this lab since otherwise we'd need to overcomplicate the inheritance structure of the classes...) . Then, you can proceed by making a few simple modifications:
- In
train, instead of directly returning the term-document matrix, you should instead run SVD on it. The matrix you get fromTfidfVectorizeris a sparse matrix (which you learned about in Lab 3), so to do SVD on it, you can use thesvdsfunction from thescipy.sparselibrary. For the number of latent dimensions (i.e., the number of "concepts" we want to learn), you should set thekparameter to 100.svdswill return three matrices:U,s, andVh. These correspond to \( U \), \( \Sigma \), and \( V^T \) from the lecture. As a reminder, \( U \) contains the document vectors in "concept space" (so, this is what you want to return), \( \Sigma \) contains the singular values (which, for our purposes, we'll ignore), and \( V^T \) contains the word vectors in "concept space" (but transposed so the words are on the columns). You will want to hang on to \( V \) somehow, as we'll need it later! - In
get_document_vector, after computing the query vector usingTfidfVectorizer, you need to similarly transform that vector to "concept space". As a reminder, this can be done by a matrix multiplication with \( V \) (which, as noted above, you should have somehow held on to after training!). As usual, be careful about the matrix shapes when doing matrix multiplication! Intuitively, the result we want is a single vector representing the query in "concept space". So, this should be a single-row 1xkmatrix, wherekis the number of latent dimensions (which we previously set to 100). I recommend printing the matrix shapes to make sure you're getting them right; don't hesitate to reshape and/or transpose as needed!
TASK: Add a new command-line argument to enable the use of SVD vectors
Now that we've defined our SVD vector model, we need to modify the main function to let us specify that we want to use the SVD vectors in WikiSearchEngine. Make the following modifications to main:
- Add a new argument
--model/-mto the argument parser. This argument should be a string that can take two possible values: "tfidf" or "svd", and the default value should be "tfidf". - Modify the initialization of the
doc_vector_modelvariable, which in Part 2 you initialized as aCountDocumentVectorsobject. You should add anifstatement so that ifargs.modelis "svd", thendoc_vector_modelinstead gets initialized as aSVDDocumentVectorsobject. Ifargs.modelis "tfidf" (the default), thendoc_vector_modelshould remain as aCountDocumentVectorsobject.
Once you have made these changes, then running:
python wiki_search.py /courses/cs159/data/wikipedia/enwiki_sampled/ -q "liberal arts college in southern california" -m svd
should run the same "liberal arts college in southern california" search from before, but using SVD vectors.
Use this setting to answer the following analysis questions:
Analysis Question #3
Re-run the same queries from Analysis Question #1 using your new SVD vector model, and paste the new results in your journal. What changed? For each query, do you think the new results are better or worse than before? Why?
Analysis Question #4
Re-run your queries from Analysis Question #2 using your new SVD vector model, and paste the new results in your journal. What changed? Do the new results better align with your expectations? For the two queries you originally expected the IR system to get wrong, does the system now get them right?
(When logged in, completion status appears here.)