Done 2017 challenge 5
[cipher-tools.git] / language_models.py
index 929746888d036fb54de3f1fbf228e296e0bcd027..0fa6e85dc7f3732e2c36a1c1bc4ead827005023e 100644 (file)
@@ -5,6 +5,9 @@ import collections
 import unicodedata
 import itertools
 from math import log10
+import os 
+
+unaccent_specials = ''.maketrans({"’": "'", '“': '"', '”': '"'})
 
 def letters(text):
     """Remove all non-alphabetic characters from a text
@@ -31,7 +34,8 @@ def unaccent(text):
     >>> unaccent('HÉLLÖ')
     'HELLO'
     """
-    return unicodedata.normalize('NFKD', text).\
+    translated_text = text.translate(unaccent_specials)
+    return unicodedata.normalize('NFKD', translated_text).\
         encode('ascii', 'ignore').\
         decode('utf-8')
 
@@ -53,7 +57,7 @@ def sanitise(text):
 def datafile(name, sep='\t'):
     """Read key,value pairs from file.
     """
-    with open(name, 'r') as f:
+    with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), name), 'r') as f:
         for line in f:
             splits = line.split(sep)
             yield [splits[0], int(splits[1])]
@@ -67,7 +71,7 @@ normalised_english_bigram_counts = norms.normalise(english_bigram_counts)
 english_trigram_counts = collections.Counter(dict(datafile('count_3l.txt')))
 normalised_english_trigram_counts = norms.normalise(english_trigram_counts)
 
-with open('words.txt', 'r') as f:
+with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'words.txt'), 'r') as f:
     keywords = [line.rstrip() for line in f]
 
 
@@ -122,6 +126,7 @@ def log_probability_of_unknown_word(key, N):
 Pw = Pdist(datafile('count_1w.txt'), log_probability_of_unknown_word)
 Pl = Pdist(datafile('count_1l.txt'), lambda _k, _N: 0)
 P2l = Pdist(datafile('count_2l.txt'), lambda _k, _N: 0)
+P3l = Pdist(datafile('count_3l.txt'), lambda _k, _N: 0)
 
 def Pwords(words): 
     """The Naive Bayes log probability of a sequence of words.
@@ -139,15 +144,29 @@ def Pbigrams(letters):
     """
     return sum(P2l[p] for p in ngrams(letters, 2))
 
+def Pbigrams(letters):
+    """The Naive Bayes log probability of the bigrams formed from a sequence 
+    of letters.
+    """
+    return sum(P2l[p] for p in ngrams(letters, 2))
+
+def Ptrigrams(letters):
+    """The Naive Bayes log probability of the trigrams formed from a sequence
+    of letters.
+    """
+    return sum(P3l[p] for p in ngrams(letters, 3))
+
 
 def cosine_distance_score(text):
     """Finds the dissimilarity of a text to English, using the cosine distance
     of the frequency distribution.
 
     >>> cosine_distance_score('abcabc') # doctest: +ELLIPSIS
-    0.370847405...
+    0.73777...
     """
-    return norms.cosine_distance(english_counts, 
+    # return norms.cosine_distance(english_counts, 
+    #     collections.Counter(sanitise(text)))
+    return 1 - norms.cosine_similarity(english_counts, 
         collections.Counter(sanitise(text)))