'Train a SubwordTextEncoder based on a dictionary of word counts.
Args:
token_counts: a dictionary of Unicode strings to int.
min_count: an integer - discard subtokens with lower counts.
num_iterations: an integer.  how many iterations of refinement.
num_reserved_ids: an integer.  how many ids to reserve for special tokens.'

def build_from_token_counts(self, token_counts, min_count, num_iterations=4, num_reserved_ids=NUM_RESERVED_TOKENS):

    self._init_alphabet_from_tokens(six.iterkeys(token_counts))
    self._init_subtokens_from_list(list(self._alphabet), reserved=num_reserved_ids)
    if (min_count < 1):
        min_count = 1
    for i in xrange(num_iterations):
        tf.logging.info('Iteration    {0}'.format(i))
        subtoken_counts = collections.defaultdict(int)
        for (token, count) in six.iteritems(token_counts):
            escaped_token = _escape_token(token, self._alphabet)
            subtokens = self._escaped_token_to_subtoken_strings(escaped_token)
            start = 0
            for subtoken in subtokens:
                for end in xrange((start + 1), (len(escaped_token) + 1)):
                    new_subtoken = escaped_token[start:end]
                    subtoken_counts[new_subtoken] += count
                start += len(subtoken)
        len_to_subtoken_strings = []
        for (subtoken_string, count) in six.iteritems(subtoken_counts):
            lsub = len(subtoken_string)
            if (count >= min_count):
                while (len(len_to_subtoken_strings) <= lsub):
                    len_to_subtoken_strings.append(set())
                len_to_subtoken_strings[lsub].add(subtoken_string)
        new_subtoken_strings = []
        for lsub in xrange((len(len_to_subtoken_strings) - 1), 0, (-1)):
            subtoken_strings = len_to_subtoken_strings[lsub]
            for subtoken_string in subtoken_strings:
                count = subtoken_counts[subtoken_string]
                if (count >= min_count):
                    if (subtoken_string not in self._alphabet):
                        new_subtoken_strings.append((count, subtoken_string))
                    for l in xrange(1, lsub):
                        subtoken_counts[subtoken_string[:l]] -= count
        new_subtoken_strings.extend(((subtoken_counts.get(a, 0), a) for a in self._alphabet))
        new_subtoken_strings.sort(reverse=True)
        self._init_subtokens_from_list([subtoken for (_, subtoken) in new_subtoken_strings], reserved=num_reserved_ids)
        tf.logging.info(('vocab_size    =    %d' % self.vocab_size))
