Реализация марковской модели в Python - PullRequest
1 голос
/ 18 марта 2019

Я пытаюсь реализовать свойство Маркова на множестве строк.Мне нужны все уникальные слова в соответствии с частотой следующих слов.

Пример

Ввод
Имя файла: Example.txt

I Love you
I Miss you 
Miss you Baby
You are the best
I Miss you 

КодФрагмент

from collections import Counter
import pprint

class TextAnalyzer:

    text_file = 'example.txt'


    def __init__(self):
        self.raw_data = ''
        self.word_map = dict()

        self.prepare_data()
        self.analyze()

        pprint.pprint(self.word_map)

    def prepare_data(self):
        with open(self.text_file, 'r') as example:
            self.raw_data=example.read().replace('\n', ' ')
        example.close()

    def analyze(self):
        words = self.raw_data.split()

        word_pairs = [[words[i],words[i+1]] for i in range(len(words)-1)]

        self.word_map = dict()

        for word in list(set(words)):
            for pair in word_pairs:
                if word == pair[0]:
                    self.word_map.setdefault(word, []).append(pair[1])

        self.word_map[word] = Counter(self.word_map[word]).most_common(11)

TextAnalyzer()

Фактический результат

{'Baby': ['You'],
 'I': ['Love', 'Miss', 'Miss'],
 'Love': ['you'],
 'Miss': ['you', 'you', 'you'],
 'You': ['are'],
 'are': ['the'],
 'best': ['I'],
 'the': ['best'],
 'you': [('I', 1), ('Miss', 1), ('Baby', 1)]}

Ожидаемый результат:

{'Miss': [('you',3)],
 'I': [('Love',1), ('Miss',2)],
 'Love': ['you',1],
 'Baby': ['You',1],
 'You': ['are',1],
 'are': ['the',1],
 'best': ['I',1],
 'the': ['best'],
 'you': [('I', 1), ('Miss', 1), ('Baby', 1)]}

Я хочу, чтобы выходные данные были отсортированы по максимальной частоте.Как я могу улучшить свой код для достижения этого результата.

1 Ответ

0 голосов
/ 18 марта 2019

Чтобы приблизиться к ожидаемому результату, вы можете отредактировать метод analize:

def analyze(self):
    words = self.raw_data.split()
    word_pairs = [[words[i],words[i+1]] for i in range(len(words)-1)]
    self.word_map = dict()

    for word in list(set(words)):
        pairword = []
        for pair in word_pairs:
            if word == pair[0]:
                pairword.append(pair[1])
        self.word_map[word] = Counter(pairword).most_common()

Это печатает:

{'Baby': [('You', 1)],
 'I': [('Miss', 2), ('Love', 1)],
 'Love': [('you', 1)],
 'Miss': [('you', 3)],
 'You': [('are', 1)],
 'are': [('the', 1)],
 'best': [('I', 1)],
 'the': [('best', 1)],
 'you': [('I', 1), ('Miss', 1), ('Baby', 1)]}

Что вы хотите, но не отсортированы. Вам нужно написать собственный метод печати, который сделает сортировку за вас.

Например, добавив в класс следующий метод:

def printfreq(self):
    sortkeys = sorted(self.word_map, key=lambda k:max(self.word_map[k], key=lambda val:val[1], default=(None, 0))[1], reverse=True)
    for kk in sortkeys:
        pprint.pprint(f"{kk} : {self.word_map[kk]}")

и замена строки pprint.pprint(self.word_map) на self.printfreq() приводит к печати:

"Miss : [('you', 3)]"
"I : [('Miss', 2), ('Love', 1)]"
"you : [('I', 1), ('Miss', 1), ('Baby', 1)]"
"Love : [('you', 1)]"
"the : [('best', 1)]"
"You : [('are', 1)]"
"best : [('I', 1)]"
"Baby : [('You', 1)]"
"are : [('the', 1)]"

Длинный ключ сортировки позволяет сортировать ключи словаря по максимальной частоте в списке.

EDIT

Я добавил аргумент по умолчанию к max. Это позволяет избежать ValueError: max() arg is an empty sequence, который может возникнуть, если на входе есть одно или несколько неповторяющихся слов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...