      p This really isn't a good solution. It's just a quick hack that requires no set up, and very few lines of code. If we started from scratch with the old data and the new examples, we could almost certainly do better. And retraining the entity recognition model doesn't take very long. However, we can't distribute the training data to you, and the best solution will depend on the specifics of your problem. If you need better accuracy, you should get in touch.
      
      h4 Boot-strapping examples with nlp2vec
  
      p We still need more examples. One solution is to sit down with a bunch of comments, and start annotating them from start to finish. For evaluation data, this is the only really satisfactory approach. But for training data, it's pretty inefficient.
  
      p What we'll do is make a little seed dictionary of food terms. We'll then use a distributional similarity model to rank words and phrases for their similarity to our seed set. Then, we'll page through each of these words and phrases in turn, tagging examples of them in context. 
  
      p Mostly, things are food or they aren't. Most words and phrases are unambiguous in this respect, which means they can be tagged in bulk, with one decision applying to many examples. And for the ambiguous entries, annotation decisions can be made much more quickly if you make lots of the same type of decision in a row.
  
 
</s> remove     h4 Boot-strapping examples with nlp2vec
 </s> add //    h4 Boot-strapping examples with nlp2vec
//
//    p We still need more examples. One solution is to sit down with a bunch of comments, and start annotating them from start to finish. For evaluation data, this is the only really satisfactory approach. But for training data, it's pretty inefficient.
//
//    p What we'll do is make a little seed dictionary of food terms. We'll then use a distributional similarity model to rank words and phrases for their similarity to our seed set. Then, we'll page through each of these words and phrases in turn, tagging examples of them in context. 
//
//    p Mostly, things are food or they aren't. Most words and phrases are unambiguous in this respect, which means they can be tagged in bulk, with one decision applying to many examples. And for the ambiguous entries, annotation decisions can be made much more quickly if you make lots of the same type of decision in a row.
//
//    p It's important that we're able to do this over #[em phrases], not just individual words. We want to be tagging instances of "hot dog", not just "dog". A simple way to achieve this is to use spaCy's syntactic parser to identify base noun phrases. We then merge these noun phrases into single tokens, before we send the data to Gensim's word2vec implementation. I did this over all comments posted to Reddit in 2015.
//
//    pre
//        code
//            | from __future__ import print_function, unicode_literals, division
//            | import io
//            | import bz2
//            | import logging
//            | from os import path
//            | import os
//            | 
//            | import plac
//            | import ujson
//            | from gensim.models import Word2Vec
//            | 
//            | 
//            | class Corpus(object):
//            |    def __init__(self, directory):
//            |        self.directory = directory
//            |
//            |    def __iter__(self):
//            |        for filename in os.listdir(self.directory):
//            |            text_loc = path.join(self.directory, filename)
//            |            with io.open(text_loc, 'r', encoding='utf8') as file_:
//            |                for sent_str in file_:
//            |                    yield sent_str.split()
//            | 
//            | 
//            | @plac.annotations(
//            |     in_dir=("Location of input directory"),
//            |     out_loc=("Location of output file"),
//            |     n_workers=("Number of workers", "option", "n", int),
//            |     size=("Dimension of the word vectors", "option", "d", int),
//            |     window=("Context window size", "option", "w", int),
//            |     min_count=("Min count", "option", "m", int))
//            | def main(in_dir, out_loc, n_workers=4, window=5, size=128, min_count=10):
//            |    logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO|)
//            |       corpus = Corpus(in_dir)
//            |       model = Word2Vec(
//            |           Corpus(in_dir),
//            |           size=size,
//            |           window=window,
//            |           min_count=min_count,
//            |           workers=n_workers)
//            |       model.save(out_loc)
//            | 
//            | 
//            | if __name__ == '__main__':
//            |     plac.call(main)

    //p Note that the approach that I'm advocating here is actually fairly different from "active learning", where you try to get the classifier's uncertainty to prioritise a queue of examples to be annotated. This can minimise the total number of decisions you need to make to achieve some given accuracy. However, it makes the annotation task much more difficult, and introduces a whole new machine learning problem to tinker with. Active learning is well researched because it's generalisable: it doesn't require any specific insights about your annotation task. But this also makes it much less powerful. </s> remove     p What we'll do is make a little seed dictionary of food terms. We'll then use a distributional similarity model to rank words and phrases for their similarity to our seed set. Then, we'll page through each of these words and phrases in turn, tagging examples of them in context. 
 </s> add     p As a simple example, consider a common word like #[em take], which has a large number of distinct senses, as both a noun and a verb. Vanilla word2vec collapses all uses of this word into a single entry. Splitting these entries out even a little bit turns out to be very useful. Here we see the nearest neighbours of the nominal sense: </s> remove     p Mostly, things are food or they aren't. Most words and phrases are unambiguous in this respect, which means they can be tagged in bulk, with one decision applying to many examples. And for the ambiguous entries, annotation decisions can be made much more quickly if you make lots of the same type of decision in a row.
 </s> add     pre
        code
            | >>> model = gensim.models.Word2Vec.load('np_ner_tag_reddit_2015_01-300d.model')
            | >>> model.most_similar(['take|NOUN'])
            | [(u'personal_stance|NOUN', 0.49355706572532654), (u'best_guess|NOUN', 0.48488736152648926), (u'personal_favorite_song|NOUN', 0.4821690320968628), (u'stance|NOUN', 0.48033151030540466), (u'favorite_track|NOUN', 0.47577959299087524), (u'personal_opinion|NOUN', 0.47202107310295105), (u'favorite_community|NOUN', 0.4700315594673157), (u'personal_view|NOUN', 0.4675809144973755), (u'overall_opinion|NOUN', 0.4594742953777313), (u'first_impression|NOUN', 0.458611398935318)] </s> remove     p It's important that we're able to do this over #[em phrases], not just individual words. We want to be tagging instances of "hot dog", not just "dog". A simple way to achieve this is to use spaCy's syntactic parser to identify base noun phrases. We then merge these noun phrases into single tokens, before we send the data to Gensim's word2vec implementation. I did this over all comments posted to Reddit in 2015.
 </s> add     p The model has learned that as a noun, #[em take] is similar to phrases like #[em personal stance] and #[em best guess]. Its similarity to the verbal sense is quite low: </s> remove     p Until machines can think for themselves, we have to either program them explicitly, or give them examples.  Let's say you want to write a program that tags mentions of a certain type of thing in text --- let's say, food.  You can't write this program without supplying some definition of what you consider to be food, and what you don't. That much is fundamental. But, you don't necessarily need to sit down with an arbitrary sample of text, and start tagging it manually, word-by-word. Sometimes you do --- but sometimes there are easier ways.
    
    p In this post I'll describe how to adapt spaCy's named entity recogniser to recognise categories of your choosing, including a quick and dirty way to produce training data semi-automatically. The strategy is to define a handful of seed words or phrases, and then use word2vec to generate a more expansive list. Before using Gensim to train the word vectors, we merge base noun phrases and previously recognised entities into single tokens, using spaCy's annotations. This gives a vector space that includes phrases as well as words. To train our tagger, we can manually classify some of these phrases in context, or we can use an old data generation trick adapted from word sense disambiguation.

 </s> add 
    p I'd been thinking about learning noun phrase vectors for a long time, but it only left the idea queue when I read the Trask et al "sense2vec" paper, where they show that simply using part-of-speech tags to make the keys a little more context specific helps a lot. The addition of phrases seems to make things even better.
      p This really isn't a good solution. It's just a quick hack that requires no set up, and very few lines of code. If we started from scratch with the old data and the new examples, we could almost certainly do better. And retraining the entity recognition model doesn't take very long. However, we can't distribute the training data to you, and the best solution will depend on the specifics of your problem. If you need better accuracy, you should get in touch.
      
      h4 Boot-strapping examples with nlp2vec
  
    p I'd been thinking about learning noun phrase vectors for a long time, but it only left the idea queue when I read the Trask et al "sense2vec" paper, where they show that simply using part-of-speech tags to make the keys a little more context specific helps a lot. The addition of phrases seems to make things even better.
  
      p What we'll do is make a little seed dictionary of food terms. We'll then use a distributional similarity model to rank words and phrases for their similarity to our seed set. Then, we'll page through each of these words and phrases in turn, tagging examples of them in context. 
  
      p Mostly, things are food or they aren't. Most words and phrases are unambiguous in this respect, which means they can be tagged in bulk, with one decision applying to many examples. And for the ambiguous entries, annotation decisions can be made much more quickly if you make lots of the same type of decision in a row.
  
keep keep keep keep replace keep keep keep keep keep
 * Write more notes about spaCy's NER 
website/src/jade/tutorials/bootstrap-ner-word2vec/index.jade