diff --git a/languedoc.py b/languedoc.py --- a/languedoc.py +++ b/languedoc.py @@ -1,9 +1,8 @@ import os -import re import random import itertools -from shared import identify, extract_ngram_freqs, TOP_NGRAM_COUNT +from shared import preprocess, identify, extract_ngram_freqs, rank_ngram_freqs, Sample random.seed(19181028) @@ -11,11 +10,6 @@ CROSSVALIDATION_SOURCE_COUNT = 5 TEST_LENS = [8, 16, 32, 64] -def preprocess(text): - text = re.sub(r"[\W\d_]+", " ", " "+text+" ") - return text.lower() - - def merge_ngram_freqs(freqs): n = len(freqs) res = dict() @@ -28,78 +22,28 @@ def merge_ngram_freqs(freqs): return res -class Sample: - def __init__(self, language="??", text=""): - self.language = language - self.frequencies = dict() - self._ranked_ngrams = dict() - - if text: - self._extract(text) - - def _extract(self, text): - for k in range(1, 4): - self.frequencies.update(extract_ngram_freqs(text, k)) - - @staticmethod - def merge(samples): - assert len({x.language for x in samples}) == 1 - - res = Sample(samples[0].language) - res.frequencies = merge_ngram_freqs([x.frequencies for x in samples]) - - return res - - @property - def ranked_ngrams(self): - if not self._ranked_ngrams: - ordered_ngrams = sorted(self.frequencies.items(), key=lambda kv: -kv[1])[:TOP_NGRAM_COUNT] - self._ranked_ngrams = dict(zip([key for (key, freq) in ordered_ngrams], itertools.count(0))) - - return self._ranked_ngrams - - def compare(self, other): - """take k most common - use frequencies x order - use letter, digrams, trigrams - use absolute x square""" - res = sum(abs(v-other.ranked_ngrams.get(k, len(other.ranked_ngrams))) for (k, v) in self.ranked_ngrams.items()) + \ - sum(abs(v-self.ranked_ngrams.get(k, len(self.ranked_ngrams))) for (k, v) in other.ranked_ngrams.items()) - - return res - - def print_overview(self): - print(f"Sample({self.language}):") - - for freqs in self.frequencies: - x = [ - (k, round(v, 3)) - for (k, v) in sorted(freqs.items(), key=lambda kv: -kv[1]) - ] - print(" ", x[:8], "...", x[-8:]) - - print() - - class SampleSet: def __init__(self, language): self.language = language self.texts = [] - self.samples = [] + self.frequencies = [] def add(self, text): self.texts.append(text) - self.samples.append(Sample(self.language, text)) + self.frequencies.append(extract_ngram_freqs(text)) def create_model(self): - return Sample.merge(self.samples) + merged_frequencies = merge_ngram_freqs(self.frequencies) + res = Sample(self.language, rank_ngram_freqs(merged_frequencies)) + return res def generate_tests(self, n): - for (i, (text, sample)) in enumerate(itertools.cycle(zip(self.texts, self.samples))): + for (i, (text, freqs)) in enumerate(itertools.cycle(zip(self.texts, self.frequencies))): if i >= n: break - yield (text, Sample.merge([x for x in self.samples if x is not sample])) + ranked_ngrams = rank_ngram_freqs(merge_ngram_freqs([f for f in self.frequencies if f is not freqs])) + yield (text, Sample(self.language, ranked_ngrams)) def cross_validate(sample_sets):