Путаница в моделировании языка NLTK

#python #machine-learning #nlp #nltk

#python #машинное обучение #nlp #nltk

Вопрос:

Я хочу обучить языковую модель с использованием NLTK на python, но столкнулся с несколькими проблемами. прежде всего, я не знаю, почему мои слова превращаются просто в символы, когда я пишу что-то подобное :

 s = "Natural-language processing (NLP) is an area of computer science " 
"and artificial intelligence concerned with the interactions " 
"between computers and human (natural) languages."
s = s.lower();


paddedLine = pad_both_ends(word_tokenize(s),n=2);

train, vocab = padded_everygram_pipeline(2, paddedLine)
print(list(vocab))
lm = MLE(2);
lm.fit(train,vocab)
  

и напечатанный вокабуляр — это что-то вроде этого, что явно неверно (я не хочу работать с символами!), это часть вывода.:

 <s>', '<', 's', '>', '</s>', '<s>', 'n', 'a', 't', 'u', 'r', 'a', 'l', '-', 'l', 'a', 'n', 'g', 'u', 'a', 'g', 'e', '</s>', '<s>', 'p', 'r', 'o', 'c', 'e', 's', 's', 'i', 'n', 'g', '</s>', '<s>', '(', '</s>', '<s>', 'n', 'l', 'p', '</s>', '<s>', ')', '</s>'
  

почему мои входные данные превращаются в символы?
я выполнил эту работу другим способом, но безуспешно :

 paddedLine = pad_both_ends(word_tokenize(s),n=2);
#train, vocab = padded_everygram_pipeline(2, tokens)
#train = everygrams(paddedLine,max_len = 2);

train = ngrams(paddedLine,2);
vocab = Vocabulary(paddedLine,unk_cutoff = 1);
print(list(train))

lm = MLE(2);
lm.fit(train,vocab)
  

когда я запускаю этот код, мой поезд — это абсолютное ничто, пустое! он показывает мне «[]» !!
проблема заключается в том, что когда я комментирую эту строку из приведенного выше кода:

 vocab = Vocabulary(paddedLine,unk_cutoff = 1);
  

теперь мои данные о поезде в порядке, и что-то вроде этого является правильным :

 [('<s>', 'natural-language'), ('natural-language', 'processing'), ('processing', '('), ('(', 'nlp'), ('nlp', ')'), (')', 'is'), ('is', 'an'), ('an', 'area'), ('area', 'of'), ('of', 'computer'), ('computer', 'science'), ('science', 'and'), ('and', 'artificial'), ('artificial', 'intelligence'), ('intelligence', 'concerned'), ('concerned', 'with'), ('with', 'the'), ('the', 'interactions'), ('interactions', 'between'), ('between', 'computers'), ('computers', 'and'), ('and', 'human'), ('human', '('), ('(', 'natural'), ('natural', ')'), (')', 'languages'), ('languages', '.'), ('.', '</s>')]
  

что с этим не так?
кстати, я должен сказать, что я не эксперт в python или NLTK, и это мой первый опыт.
Следующий вопрос заключается в том, как я могу использовать сглаживание кнесера-Нея или сглаживание add-one в модели языка обучения?
и правильно ли я обучаю языковую модель?
мои обучающие данные просты :

 "Natural-language processing (NLP) is an area of computer science " 
    "and artificial intelligence concerned with the interactions " 
    "between computers and human (natural) languages."
  

Спасибо.

Комментарии:

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

2. @Inder я отредактировал сообщение.

3. Я не могу воспроизвести проблему, то, что я сделал, было word_tokenize(s) , и это дало маркированные слова.

4. @Inder не могли бы вы опубликовать свой код, чтобы я мог его протестировать, пожалуйста?

5. Пожалуйста, объясните, о чем вы спрашиваете.

Ответ №1:

padded_everygram_pipeline Функция ожидает список из n-граммов. Вы должны исправить свой первый фрагмент кода следующим образом. Кроме того, генераторы python являются ленивыми последовательностями, вы не можете повторять их более одного раза.

 from nltk import word_tokenize
from nltk.lm import MLE
from nltk.lm.preprocessing import pad_both_ends, padded_everygram_pipeline

s = "Natural-language processing (NLP) is an area of computer science " 
    "and artificial intelligence concerned with the interactions " 
    "between computers and human (natural) languages."
s = s.lower()

paddedLine = [list(pad_both_ends(word_tokenize(s), n=2))]

train, vocab = padded_everygram_pipeline(2, paddedLine)

lm = MLE(2)

lm.fit(train, vocab)

print(lm.counts)

  

Комментарии:

1. Мне кажется, что есть еще одна ошибка: строка сначала дополняется pad_both_ends() , а затем с padded_everygram_pipeline() , так что, если я прав, будет двойное заполнение.

Ответ №2:

Множественные ошибки в приведенном выше ответе:

  1. «функция padded_everygram_pipeline ожидает список из списка n-граммов» -> Нет, если вы имеете в виду ввод, ей просто нужен список из списка обозначенных слов. Не n-граммы. Он генерирует n-граммов 2) Вам не нужно выполнять заполнение, поскольку padded_everygram_pipeline уже делает это за вас. Поэтому нет необходимости в padded_everygram_pipeline(2, paddedLine) — единственном правильном способе сделать это для одного предложения с:

      tokens = [list((word_tokenize(s))]
     train_data_bigram, padded_sent_list = padded_everygram_pipeline(2, tokens)
      

    #Чтобы проверить каждую строку в результате, вы можете использовать следующее

    для ngramlize_sent в train_data_bigram:

      #prints unigrams and bigrams
    
     print(list(ngramlize_sent))
    
     print()
      

    print(‘—-‘)

    #печатает дополненное предложение, т. е. само предложение дополнено

    список (padded_sent_list)

    lm = MLE(2)

    lm.fit(train_data_bigram, padded_sent_list)

    печать (lm.counts)

Аналогичным образом вы можете изменить 2 на 3 в обоих местах и в конечном итоге протестировать это с помощью модели trigram.