Exemple #1
0
    def test_keys_ordering(self):
        data = [('foo', b'v1'), ('foobar', b'v2'), ('bar', b'v3')]

        d = dawg.BytesDAWG(data, payload_separator=b'\xff')
        assert d.keys() == ['bar', 'foobar', 'foo']

        d2 = dawg.BytesDAWG(data, payload_separator=b'\x01')
        assert d2.keys() == ['bar', 'foo', 'foobar']
Exemple #2
0
 def __init__(self, doc):
     # transform the key-value pairs into a (key, value) list
     pairs = []
     for key, val in doc.iteritems():
         # convert complex objects into a string
         pairs.append((key, bytes(val)))
     self.data = dawg.BytesDAWG(pairs)
Exemple #3
0
def build_test_data():

    dawg.CompletionDAWG(['f', 'bar', 'foo',
                         'foobar']).save('dev_data/small/completion.dawg')
    dawg.CompletionDAWG([]).save('dev_data/small/completion-empty.dawg')

    bytes_data = (('foo', b'data1'), ('bar', b'data2'), ('foo', b'data3'),
                  ('foobar', b'data4'))
    dawg.BytesDAWG(bytes_data).save('dev_data/small/bytes.dawg')

    record_data = (('foo', (3, 2, 256)), ('bar', (3, 1, 0)),
                   ('foo', (3, 2, 1)), ('foobar', (6, 3, 0)))
    dawg.RecordDAWG(str(">3H"), record_data).save('dev_data/small/record.dawg')

    int_data = {'foo': 1, 'bar': 5, 'foobar': 3}
    dawg.IntDAWG(int_data).save('dev_data/small/int_dawg.dawg')
    dawg.IntCompletionDAWG(int_data).save(
        'dev_data/small/int_completion_dawg.dawg')

    dawg.DAWG(TestPrediction.DATA).save('dev_data/small/prediction.dawg')
    dawg.RecordDAWG(str("=H"), [
        (k, (len(k), )) for k in TestPrediction.DATA
    ]).save('dev_data/small/prediction-record.dawg')

    create_dawg().save('dev_data/large/dawg.dawg')
    create_bytes_dawg().save('dev_data/large/bytes_dawg.dawg')
    create_record_dawg().save('dev_data/large/record_dawg.dawg')
    create_int_dawg().save('dev_data/large/int_dawg.dawg')
Exemple #4
0
    def create_from_other(self, compdawg):
        d = count_prefixes(compdawg)
        d = dict([(k, v.pop()) for k, v in d.iteritems() if len(v) == 1])

        self.trie = marisa_trie.BytesTrie(
            ((k, v.encode("utf-8")) for k, v in d.iteritems()))
        self.dawg = dawg.BytesDAWG(
            ((k, v.encode("utf-8")) for k, v in d.iteritems()))
Exemple #5
0
 def _load_bytes_dawg(self) -> None:
     if self.workdir and os.path.isdir(self.workdir):
         bytes_dawg_path = os.path.join(self.workdir, DictionaryManager.persist_name)
         if os.path.isfile(bytes_dawg_path):
             bytes_dawg = dawg.BytesDAWG()
             bytes_dawg.load(bytes_dawg_path)
             for k, v in bytes_dawg.iteritems():
                 self.word_dict[k] = WordData.frombytes(v)
             self.completion_dawg = dawg.CompletionDAWG(self.word_dict.keys())
Exemple #6
0
    def __init__(self, morph=None, morph_simple=None, dater=None):
        """
        Инициализация тэггера. Создание регулярных выражений для лематизации.
        Подгрузка словарей аббревиатур, исключений.
        Создание словарей месяцев, падежей и пр.

        morph - морфологический словарь pymorphy с предсказанием по префиксам.
        morph_simple - морфологический словарь pymorphy без предсказания по префиксам.

        Примечание:
        В pymorphy с включенным предсказанием по префиксам (check_prefixes=True) появляется много несуществующих слов.
        Т.к. это свойство задается сразу при инициализации объекта, приходится создавать 2 объекта:
        с предсказанием и без него.
        Во время лемматизации вначале применяется объект морфологии
        без предсказания по префиксу (morph_simple), если он подключен.
        Если он не знает какого-то слова, для этого слова
        используется объект морфологии с предсказанием про префиксу (morph), если он подключен.

        При этом Tagger не требует обязательного указания обоих объектов морфологии:
        достаточно указать только один (он и будет использоваться при лемматизации).
        """
        if not morph and not morph_simple:
            raise ValueError("No morphoanalyzer found!")
        # Рег. выражения для лемматизации
        self.digit = re.compile("^\d+$")
        self.eng = re.compile(u"^\d*[a-zA-Z]+(?:-[a-zA-Z])?$", re.UNICODE)
        self.short = re.compile(u"^[A-ZА-ЯЁ][a-zа-яё]?$")

        # Рег. выражения для разбиения текста на предложения
        self.splitter = re.compile("[.?!]+")
        self.starter = re.compile(u"[А-ЯЁA-Z\d\"\'\(\)\[\]~`«s-]")
        self.bad_ender = re.compile(u"^[А-ЯЁа-яёA-Za-z][а-яёa-z]?$")

        # Рег. выражение для управления
        self.prepcase = re.compile(u"\d+:ПРЕДЛ(?:\d+:(?:П|МС-П|ПРИЧАСТИЕ|ЧАСТ|СОЮЗ|Н))*\d+:(?:П|С|МС|МС-П)(?:\d+:СОЮЗ\d+:(?:С|МС))?")
        #self.prepcase = re.compile(u"\d+:ПРЕДЛ(?:\s\d+:(?:П|ПРИЧАСТИЕ|ЧАСТ|СОЮЗ))*\s\d+:(?:П|С)(\s\d+:СОЮЗ\s\d+:С)?")
        self.positem = re.compile(u"\d+:[А-Я-]+")
        # Морфология
        self.morph = morph
        self.morph_simple = morph_simple
        # Обработка дат
        self.dater = dater
        # Аббревиатуры
        self.abbrs = unpkl_2layered_s(os.path.join(os.path.dirname(sys.argv[0]), "dicts/abbr.pkl"))
        # Доп. правила
        self.excepts = unpkl_2layered_s(os.path.join(os.path.dirname(sys.argv[0]), "dicts/exceptions.pkl"))
        # Падежи
        self.cases = {u"им", u"рд", u"дт", u"вн", u"тв", u"пр"}
        self.declinable = {u"С", u"МС", u"П", u"ПРИЧАСТИЕ", u"МС-П", u"ЧИСЛ-П"}
        # Суффиксные частоты
        self.freqs = dawg.BytesDAWG()
        self.weights = defaultdict(float)
        self.small = 0.0
Exemple #7
0
 def load_statistics(self, trainfile, suff_len=3, process_cases=True):
     """
     Загрузка суффиксной и падежной статистики
     """
     try:
         if process_cases:
             self.caserules = unpkl_1layered_s(trainfile + ".cases.caserules.pkl")
         self.weights = unpkl_1layered_f(trainfile + "." + str(suff_len).zfill(2) + ".suffs.weights.pkl")
         self.freqs = dawg.BytesDAWG()
         self.freqs.load(trainfile + "." + str(suff_len).zfill(2) + ".suffs.freqs.dawg")
         with open(trainfile + "." + str(suff_len).zfill(2) + ".suffs.small", "rb") as fin:
             self.small = pickle.load(fin)
     except Exception as e:
         print("Tagger statistics not found!", e)
         sys.exit()
Exemple #8
0
 def _persist_bytes_dawg(self) -> None:
     if self.workdir and len(self.word_dict) > 0:
         if not os.path.isdir(self.workdir):
             print(
                 "[BytesDAWG] Are you sure {0} is a directory? Not persisting dictionary.".format(
                     self.workdir
                 )
             )
             return
         bytes_dawg_path = os.path.join(self.workdir, DictionaryManager.persist_name)
         bytes_dawg = dawg.BytesDAWG(
             [(k, bytes(v)) for k, v in self.word_dict.items()]
         )
         try:
             bytes_dawg.save(bytes_dawg_path)
         except FileNotFoundError:
             print(
                 "[BytesDAWG] Couldn't persist dictionary to path {0}, are you sure the workdir exists and is writeable?".format(
                     bytes_dawg_path
                 )
             )
Exemple #9
0
    def __init__(self, morph=None, dater=None):
        """
        Инициализация тэггера. Создание регулярных выражений для лемматизации.
        Подгрузка словаря аббревиатур.
        Создание словарей месяцев, падежей и пр.

        morph - морфологический словарь pymorphy2
        """
        if not morph:
            raise ValueError("No morphoanalyzer found!")
        # Рег. выражения для лемматизации
        self.digit = re.compile("^\d+$")
        self.eng = re.compile("^\d*[a-zA-Z]+(?:-[a-zA-Z])?$", re.UNICODE)
        self.short = re.compile("^[A-ZА-ЯЁ][a-zа-яё]?$")

        # Рег. выражения для разбиения текста на предложения
        self.splitter = re.compile("[.?!]+")
        self.starter = re.compile("[А-ЯЁA-Z\d\"\'\(\)\[\]~`«s-]")
        self.bad_ender = re.compile("^[А-ЯЁа-яёA-Za-z][а-яёa-z]?$")
        self.gram_spl = re.compile("[,\s]+")

        # Рег. выражение для управления
        self.prepcase = re.compile("\d+:" + mc.PREP + "(?:\d+:(?:" +
                                   mc.ADJF + "|" + mc.PRTF + "|" + mc.PRCL + "|" +
                                   mc.CONJ + "|" + mc.ADVB + "))*\d+:(?:" + mc.ADJF +
                                   "|" + mc.NOUN + "|" + mc.NPRO + ")(?:\d+:" +
                                   mc.CONJ + "\d+:(?:" + mc.NOUN + "|" + mc.NPRO + "))?")
        self.positem = re.compile("\d+:[А-Я-]+")
        # Морфология
        self.morph = morph
        # Обработка дат
        self.dater = dater
        # Аббревиатуры
        self.abbrs = unpkl_2layered_s(os.path.join(os.path.dirname(sys.argv[0]), "dicts/abbr.pkl"))
        # Суффиксные частоты
        self.freqs = dawg.BytesDAWG()
        self.weights = defaultdict(float)
        self.small = 0.0
Exemple #10
0
    def __init__(self, gazetteer_files, truecaser):

        data = []

        if type(gazetteer_files[0]) != list:
            for i in range(len(gazetteer_files)):
                gazetteer_files[i] = codecs.open(gazetteer_files[i],
                                                 encoding='utf-8',
                                                 mode='r')

        for i in range(len(gazetteer_files)):
            for entry in gazetteer_files[i]:
                e = entry.rstrip()
                data.append((e, bytes(i)))

                #Only store true-case versions of 2+ token entries if they are different from the original e
                if ' ' in entry:
                    e_true_case = u' '.join(
                        truecaser.case(entry.rstrip().split(' '), []))

                    if e_true_case != e:
                        data.append((e_true_case, bytes(i)))

        self.gazetteer_dawg = dawg.BytesDAWG(data)
Exemple #11
0
def create_bytes_dawg():
    words = words100k()
    values = [struct.pack(str('<H'), len(word)) for word in words]
    return dawg.BytesDAWG(zip(words, values))
Exemple #12
0
    def train(self, trainfile, radius=2, suff_len=3):
        """
        Сбор статистики на основе суффиксов: обработка всего корпуса
        
        trainfile - размеченный корпус,
        radius - это радиус контекста, который учитывается при выбора правильной леммы,
        suff_len - длина суффиксов, на которых основано обучение 
        """
        # Если тренировочный корпус еще не подготовлен, делаем это прямо сейчас
        if trainfile.endswith(".lemma"):
            Tagger.prepare_corpus(trainfile, suff_len)
            trainfile += "." + str(suff_len).zfill(2) + ".suffs"

        freqs = defaultdict(lambda: defaultdict(int))
        cfreqs = defaultdict(lambda: defaultdict(int))
        ranks = defaultdict(float)
        caseranks = defaultdict(float)

        # Структура словаря: {<Номер в контексте>, <Контекст>, <Список омонимов> : <Выбранный омоним> : <Вероятность>}
        normfreqs = defaultdict(lambda: defaultdict(float))
        # Структура словаря: {<Номер в контексте>, <Контекст>: <Ранг>}
        normweights = defaultdict(float)

        # Собираем частоты из корпуса
        with open(trainfile, "r", encoding="UTF8") as fin:
            sentence = []
            for line in fin:
                if line == mc.BTAG:
                    continue
                if line == mc.ETAG:
                    Tagger.count_sentence_suffs(sentence, freqs, cfreqs, radius)
                    del sentence[:]
                    sentence = []
                    continue
                sentence.append(line.strip().split("\t"))

        # Нормализуем частоты
        for k, v in freqs.items():
            total = sum([freq for freq in v.values()])
            for hom, freq in v.items():
                normfreqs[k][hom] = float(freq) / total
                
        # Вычисляем ранги контекстов
        for k, v in cfreqs.items():
            total = sum(v.values())
            entropy = - float(sum([freq * math.log(freq) for freq in v.values()]) - total * math.log(total)) / total
            ranks[k] = 1.0 / math.exp(entropy)

        # Вычисляем веса контекстов
        for k, v in ranks.items():
            normweights[k[0]] += v

        v_sum = sum([v for v in normweights.values()])
        for k, v in normweights.items():
            normweights[k] = v / v_sum

        # Сериализуем частоты и веса (ранги) контекстов (чем больше энтропия распределения по омонимам, тем меньше ранг (вес))

        dfreqs = dawg.BytesDAWG([("{0:d}\t{1}\t{2}\t{3}".format(k[0], k[1], " ".join(k[2]), hom), struct.pack("f", freq))
                                     for k, v in normfreqs.items() for hom, freq in v.items()])
        dfreqs.save(trainfile + ".freqs.dawg")
        dump_data(trainfile + ".weights.pkl", normweights)

        # Сериализуем small-значение (для тех случаев, которых нет в словаре)
        small = 1.0 / (2 * sum([freq for k, v in normfreqs.items() for v1, freq in v.items()]))
        dump_data(trainfile + ".small", small)
        
        return True
Exemple #13
0
def loaddict(f_index='pyindex.dawg', f_essay='essay.dawg'):
    global essay, p_index
    p_index = dawg.BytesDAWG()
    p_index.load(f_index)
    essay = dawg.IntDAWG()
    essay.load(f_essay)
Exemple #14
0
def gen(cs, N, size):
    words = numpy.random.choice(cs, [N, size])
    t = dawg.BytesDAWG((str(word), b"".join(word)) for word in words)
    return t
Exemple #15
0
 def dawg(self, **kwargs):
     return dawg.BytesDAWG(self.DATA, **kwargs)
Exemple #16
0
import pylab as pl
import tsvopener
import dawg
from nltk.corpus import brown
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

test_text = "four score and seven years ago, our fathers brought fourth\
             on this continent a new nation."
tokenized_text = nltk.word_tokenize(test_text)

new_category_dict = tsvopener.open_tsv("stat_categorized.tsv")

category_dawg = dawg.BytesDAWG([(x, str.encode(new_category_dict[x])) for x
                                in new_category_dict.keys()])


def make_lexicon_pie(input_dict, title):
    '''
    Make a pie of the full lexicon based on the given mapping of words to 
    languages
    :input_dict: dict of words to language sources
    :title: title to put on the pie chart
    '''
    e = 0
    f = 0
    n = 0
    l = 0
    g = 0
    o = 0