'Modifies the model so that it contains n documents of each type.
With MINORITY, n = the number of documents in the minority class.
With MAJORITY, n = the number of documents in the majority class
(generates artificial documents for minority classes).'

def resample(self, n=MINORITY):

    p1 = defaultdict(int)
    p2 = defaultdict(int)
    p3 = defaultdict((lambda : defaultdict(list)))
    for d in self.documents:
        p1[d.type] += 1
    for d in self.documents:
        p2[d.type] = max(p2[d.type], len(d.terms))
    for d in self.documents:
        for (f, w) in d.terms.items():
            p3[d.type][f].append(w)
    for t in p3:
        for f in p3[t]:
            p3[t][f].extend(([0] * (p1[t] - len(p3[t][f]))))
    if (n == MINORITY):
        n = min((p1.values() or [0]))
    if (n == MAJORITY):
        n = max((p1.values() or [0]))
    a = []
    x = defaultdict(int)
    for d in self.documents:
        if (x[d.type] < n):
            x[d.type] += 1
            a.append(d)
    for (t, i) in p1.items():
        for j in range(i, n):
            v = {}
            for f in shuffled(p3[t].keys()[:p2[t]]):
                w = choice(p3[t][f])
                w = (w if v else p3[t][f][0])
                if w:
                    v[f] = w
            a.append(Document(v))
    self.clear()
    self.extend(a)
    return self
