Made file reading *much* more memory efficient.

It's roughly 2x slower, because we iterate through each file twice
(once for IDs & labels, and once for features), but I can now load a
3.3GB NDJ file with ~7,000,000 lines and ~18,000,000 features on my
MBP without causing my whole system to lock up from "memory pressure".

The key to the approach is the new UnsortedDictVectorizer class I wrote
that can actually be used with generators (unlike the regular
DictVectorizer).  I've open a PR, scikit-learn/scikit-learn#3683, to see
if I get this added to scikit-learn, but until then it also lives in
SKLL.