CS 70

Written Questions

  • Pig speaking

    I already played around with the interactive demo in Phase 8, but I want to play with it MORE!

  • LHS Cow speaking

    You're in luck!

In this week's written questions, you'll be asked to more systematically explore the machine learning demo that you got working in Phase 8. In the process, you'll build some more intuition about how it works.

  • RHS Cow speaking

    There'll also be some more "traditional" questions that ask you to look at and interpret graphs. After all, this assignment is still (ostensibly) about building data structures...

Exploration: What Measure is a Pokemon?

  • Dog speaking

    I think I found a bug! I entered "valgrind" into the interactive mode and the AI said it sounds like a Pokemon, even though I know for a fact that Valgrind is software!

  • LHS Cow speaking

    That's not a bug...but it's a great catch!

Remember that 69% accuracy you got if you implemented everything correctly? That number isn't 100%, which means that the model makes mistakes (classifies some Pokemon as software and vice versa). But why?

  • Dog speaking

    Oh, I think I know the answer! It's because the things in the test set aren't in the training set, right? So it can't "remember" the right label for them, because it's never seen them?

  • LHS Cow speaking

    That's part of it, but there's more to it than that.

  • Pig speaking

    MORE? Music to my ears!

There's a common misconception that machine learning models simply memorize their training data and rearrange it, like making a collage out of things you found in your room. But what's actually happening is more subtle than that. Every machine learning model—from the simple one you built to the most cutting edge LLMs—have a finite number of parameters (roughly, variables in the math whose values can be trained). During training, the model tries to encode as much information as it can about the very information-rich training data into this finite number of parameters. This requires some degree of generalization...and, consequently, some loss of information.

  • LHS Cow speaking

    This is why you sometimes hear people say that machine learning is like a form of lossy compression.

  • Parrot speaking

    Squwak! Generative AI models are sometimes nicknamed "stochastic parrots" for similar reasons! Squwak!

Today's most cutting-edge models have billions of parameters. By contrast, our simple model has mere thousands of parameters—two for each feature (one representing its count in the Pokemon class, and the other in the software class). This makes our model much less capable than something like ChatGPT. But on the flip side, it also makes our model much easier to analyze...and to manipulate!

In fact, the interactive demo already implements some model analysis. When you input "valgrind" you should see something like the following:

That sounds more like a pokemon!
Here's how each feature contributed to my prediction: 
  val: +0.297027
  alg: +1.10796
  gri: +0.00934445
  rin: +1.61878
  ind: -0.278338

The numbers indicate how much more or less likely each feature is to be seen in the predicted class "pokemon". For example, "alg" is much more likely to be seen in Pokemon names, and "ind" is slightly less likely to be seen in Pokemon names (i.e., more likely to be seen in software names).

Here is your exploration task: Can you come up with a simple change to the string "valgrind" that will cause the model to predict "software" instead of "pokemon"? "Simple" is subjective of course, but try to keep the string mostly recognizable as "valgrind". You can add new characters (e.g., "valgrind.com") or substitute individual characters for similar-looking ones (e.g., 'a' to '@'), but try to avoid deleting too many characters.

Feel free to play around and find a solution you're happy with—the more whimsical, the better! To guide your exploration, you can use the feature explanations in the interactive demo, lean on your own intuitions about what software and/or pokemon names often look like, or scan through the training data (dataset-train.txt) to look for common patterns. When you're ready, tell us what you did in the written questions:

Questions

Question 1.1

What "simple" change did you make to the string "valgrind" to make the model predict "software"?

Briefly (1-2 sentences) explain how you came up with that change.

Question 1.2

As the converse of what you did above, consider the string "mamoswine". This is actually a pokemon, but the model classifies it as software. Once again, see if you can find a "simple" change that makes the model predict "pokemon" instead!

What "simple" change did you make to the string "mamoswine" to make the model predict "pokemon"?

Briefly (1-2 sentences) explain how you came up with that change.

Comparisons

(Note: These questions all say HashSet instead of HashMultiset, but for the purposes of this analysis, those are the same thing).

Question 2.1

Here's a plot of the time performance of insert, adding $$n$$ ints to a set. The numbers are inserted in increasing order. The myhash function is trivial, just returning the unmodified integer.

The plot shows time per item, with lines for two variants of HashSet<int> and std::unordered_set<int> which is also a hash table. For contrast, we have also included std::set<int> which is based on a red-black tree.

ordered-insert.png

What can you conclude about the performance of all three hash table implementations? (std::set uses a tree, not a hash table)

The graph is consistent with a single insert in a hash table with $$n$$ items requiring (expected amortized) …

Question 2.2

The above test filled the hash table buckets rather unrealistically, as they were filled sequentially due to the trivial hash function and the sequence of increasing integers.

If we used a better hash functions or inserted random integer values, values would be distributed randomly across buckets and it would be a more realistic test.

The graph below shows the results of such a test:

random-insert.png

Notice that all the methods are running more slowly in this graph.

Which explanation for this graph seems most plausible:

Question 2.3

Why do you think languages like Python use hash tables to implement their dictionaries rather than trees?

To Complete This Part of the Assignment…

You'll know you're done with this part of the assignment when you've done all of the following:

(When logged in, completion status appears here.)