Files @ d2fa9460c0fb
Branch filter:

Location: Languedoc/shared.py - annotation

Laman
moved the prediction part to a separate file
import itertools

TOP_NGRAM_COUNT = 5000


def extract_ngram_freqs(text, k):
	n = len(text)
	d = dict()

	for i in range(0, n-k+1):
		key = text[i:i+k]
		if key.isspace():
			continue

		d[key] = d.get(key, 0) + 1

	count = sum(d.values())

	return {key: val/count for (key, val) in d.items()}


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))

	@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"""
		"""make a set difference of keys, multiply its size by the max score"""
		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()


def identify(text, models):
	sample = Sample(text=text)

	return sorted(models, key=lambda m: m.compare(sample))[0].language