Статистическая модель предложения предложений, такая как проверка орфографии

Уже существуют модели проверки орфографии, которые помогают нам находить предлагаемые правильные варианты написания на основе корпуса обученных правильных написаний. Можно ли увеличить степень детализации до «слова» из алфавита, чтобы мы могли иметь даже предложения фраз, например, если введена неправильная фраза, то она должна предлагать ближайшую правильную фразу из корпуса правильных фраз, конечно, она обучается из список допустимых фраз.

Существуют ли какие-либо библиотеки Python, которые уже достигают этой функциональности, или как поступить с этим для существующего большого корпуса фраз золотого стандарта, чтобы получить статистически релевантные предложения?

Примечание: это отличается от проверки орфографии, поскольку алфавиты в программе проверки орфографии конечны, тогда как в корректоре фраз алфавит сам является словом, следовательно, теоретически бесконечен, но мы можем ограничить количество слов из банка фраз.


person stackit    schedule 05.08.2015    source источник
comment
Что вы подразумеваете под правильной фразой? Вы имеете в виду, как много телефонов теперь предлагают следующее слово, которое вы хотите напечатать? Вы имеете в виду фразу, которая грамматически правильна?   -  person Kristy Hughes    schedule 05.08.2015
comment
да, как следующее слово, то есть статистическое, не беспокоясь о грамматике @KristyHughes   -  person stackit    schedule 05.08.2015


Ответы (1)


Вы хотите построить модель N-грамм, которая заключается в вычислении вероятности того, что каждое слово будет следовать за последовательностью из n слов.

Вы можете использовать текстовый корпус NLTK для обучения своей модели или токенизировать свой собственный корпус с помощью nltk.sent_tokenize(text) и nltk.word_tokenize(sentence).

Можно считать 2-граммовыми (марковская модель):

Какова вероятность того, что «котенок» последует за «милым»?

... или 3 грамма:

Какова вероятность того, что «котенок» последует за «милым»?

и т.п.

Очевидно, что обучение модели с n + 1 граммом обходится дороже, чем n-грамм.

Вместо того, чтобы рассматривать слова, вы можете рассмотреть пару (word, pos), где pos - тег части речи (вы можете получить теги с помощью nltk.pos_tag(tokens))

Вы также можете попробовать рассмотреть леммы вместо слов.

Вот несколько интересных лекций о моделировании N-грамм:

  1. Введение в N-граммы
  2. Оценка вероятностей N-граммов

Это простой и короткий пример кода (2 грамма) без оптимизации:

from collections import defaultdict
import nltk
import math

ngram = defaultdict(lambda: defaultdict(int))
corpus = "The cat is cute. He jumps and he is happy."
for sentence in nltk.sent_tokenize(corpus):
    tokens = map(str.lower, nltk.word_tokenize(sentence))
    for token, next_token in zip(tokens, tokens[1:]):
        ngram[token][next_token] += 1
for token in ngram:
    total = math.log10(sum(ngram[token].values()))
    ngram[token] = {nxt: math.log10(v) - total for nxt, v in ngram[token].items()}
person clemtoy    schedule 05.08.2015
comment
нет ли существующих инструментов, которые работают на уровне слов? - person stackit; 06.08.2015
comment
@stackit Я думаю, но я никогда раньше не выполнял эту задачу, поэтому не знаю. Я думаю, что это довольно легко кодировать. Я отредактировал свой вопрос, чтобы предложить код. Очевидно, он не оптимизирован ... Я не могу вам сказать больше, извините ... - person clemtoy; 06.08.2015
comment
хорошо, хороший код, но почему логические вероятности приближаются к 0? а другие нет, нужно ли сглаживание? также он будет работать только для скользящего окна unigram, если я использую вложенный dict, чтобы иметь NGRAM для произвольного N, также это кажется очень распространенной конструкцией в языковом моделировании, nltk имеет пакет ngrammodel, который может использоваться вместо или любой другой существующий конструкция, которая имеет ту же функциональность, что и приведенный выше код? - person stackit; 13.08.2015
comment
связанный вопрос о вознаграждении: stackoverflow.com/questions/ 31986466 / - person stackit; 17.08.2015
comment
@stackit, вы должны добавить небольшую дельту, чтобы избежать log(0) ... На самом деле, сохранение вероятностей в виде журнала необязательно, но сложения легче, чем умножения, как это объясняется в лекции (насколько я помню). - person clemtoy; 17.08.2015