Дата публикации Jul 4, 2017
Послеиспользование вложения слов в систему рекомендацийТеперь я хочу использовать эти вложения для создания нейронной сети для обработки естественного языка.
Содержание:
0. Настройка и вложение слов
Соревнование:Правильно оцените, являются ли вопросы по Quora дубликатами друг друга.
Данные, предоставленные Kaggle, поступают в CSV-файл с пятью строками:
id 3
qid1 7
qid2 8
question1 Why am I mentally very lonely? How can I solve...
question2 Find the remainder when [math]23^{24}[/math] i...
is_duplicate 0
где is_duplicate равно 1, если вопросы имеют одинаковое намерение, и 0, если нет. Я хочу использовать эти данные, чтобы предсказать, являются ли вопросы в наборе тестов дубликатами.
Для начала мне нужно превратить имеющиеся у меня данные из этого CSV-файла во что-то, что я могу передать в нейронную сеть.
Первым шагом к этому является превращение слов в вопросах в нечто, что моя нейронная сеть может более легко сравнить. К счастью, это уже было сделано для меня, используя вложения слов (которые я исследуюВот), которые превращают слова в плавающие массивы.
Нейронные сети Keras также любят получать все свои входные данные одинакового размера. Поскольку не все вопросы имеют одинаковую длину, мне нужно выбрать длину вопроса (сколько слов в вопросе я введу в свою нейронную сеть).
Чтобы найти наилучшую длину вопроса, давайте посмотрим, как длины вопросов меняются в наборе данных:
The longest question length is 237 words
The mean question lengths are 10.9422317754 and 11.1820410203
Это не очень полезно. Я также могу изобразить частоты длин вопросов:
Это гораздо более показательно! У этого набора данных очень длинный хвост, но подавляющее большинство вопросов короче 35 слов. Будет гораздо более вычислительно эффективнее выбрать это в качестве моей максимальной длины вопроса, чем 237 слов (я буду использовать 300-мерное вложение слов, поэтому таким образом я буду тренировать более 35 * 300 массивов вместо 237 * 300).
MAX_LENGTH = 35
Теперь, когда я определил эту длину, я хочу превратить мои вопросы в 35-элементные массивы, определяемые встраиванием слов.
Неэффективный подход заключается в передаче строк в нейронную сеть и наличии слоя внедрения со словарем для встраивания слов. Лучший подход состоит в том, чтобы представлять каждое слово целым числом, и иметь словарь, который переводит каждое слово в целое число.
У Keras есть функция Tokenizer, которая делает именно это. Я могу выбрать, сколько слов я хочу превратить в индексы (в моем случае я выбираю 20 000 самых распространенных слов в наборе данных)
tokenizer = Tokenizer(nb_words = 20000)
tokenizer.fit_on_texts(train.question1 + train.question2)q1sequence = tokenizer.texts_to_sequences(train.question1)
q2sequence = tokenizer.texts_to_sequences(train.question2)word_index = tokenizer.word_index
word_index
теперь словарь, который связывает каждое слово с уникальным целым числом (например, 'replaces': 28265
).
Keras также имеет функцию, гарантирующую, что все входные последовательности имеют одинаковую длину:
q1_input = pad_sequences(q1sequence, maxlen = MAX_LENGTH)
q2_input = pad_sequences(q2sequence, maxlen = MAX_LENGTH)
Я почти готов тренировать нейронную сеть!
Последний шаг состоит в том, чтобы взять эти входные данные, которые теперь имеют длину 35 массивов целых чисел (где каждое целое число может быть связано со словом), и добавить полезную информацию, захваченную встраиванием слова.
Я не могу просто сделать массив для входных данных, который включает в себя вложения слов, так как результирующий массив настолько велик, что занимает всю память python (я пробовал это, и это было 18 ГБ, когда я сохранил его в виде текстового файла).
Лучшим подходом является добавление слоя внедрения в мою нейронную сеть, где каждому входу дают только свои вложения при прохождении через сеть. Для этого мне нужно сделать еще один словарь, который принимает целые числа вq1_input
а такжеq2_input
и переводит их в соответствующие слова.
Первый шаг - открыть вложения Glove, представляющие собой текстовый файл, и превратить их в словарь. Затем я могу создать матрицу вложения, которая содержит все вложения Glove и связывает их (по индексу) со всеми словами вword_index
,
Конечно, не каждое слово в моих данных будет иметь эквивалент GloVe (например, некоторые люди неправильно вводят слова); если это так, я оставляю вектор как только нули.
С помощью этой матрицы внедрения я могу создать слой внедрения, который будет входным слоем моей нейронной сети:
embedding_layer = Embedding(len(word_index) + 1,
EMBEDDING_DIM,
weights=[embedding_matrix],
input_length=MAX_LENGTH,
trainable=False)
Теперь у меня есть все для обучения нейронной сети!
Рекуррентные нейронные сети (которые я смотрю наВот) сделатьтоннасмысла; чтобы моя нейронная сеть понимала смысл вопроса, необходимо вспомнить, что было первым словом, даже когда оно доходило до десятого слова.
Я также хочу, чтобы моя нейронная сеть рассмотрела два вопроса по отдельности, чтобы извлечь из них смысл, прежде чем рассматривать их вместе.
Обучение этой нейронной сети в течение 5 эпох дало потерю проверки 1.4161:
Epoch 5/5
322894/322894 [==============================] - 131s - loss: 0.6615 - val_loss: 1.4161
Это не очень хороший результат, но имеет смысл, если учесть, как я подошел к проблеме; Я вообще не обрабатывал вопросы. Это должно снизить точность моей сети. Например, на Quora люди будут склонны к орфографическим ошибкам.
На самом деле, из 96 500 слов в моемword_index
словарь, 36 169 не имеют перчаточных эквивалентов. Это означает, что более 1/3 встроенных массивов, отправляемых в мою нейронную сеть, это просто нули!
Давайте посмотрим на некоторые вопросы, которые есть в наборе данных Quora:
question 1: Which one dissolve in water quikly sugar, salt, methane and carbon di oxide?
question 2: Which fish would survive in salt water?
Слово «быстро» написано с ошибкой и не имеет эквивалента GloVe, хотя ясно, что авторпредназначеныписать «быстро», что делает.
К счастью, пользователь Kaggle (Currie32) уже нашелхороший способочистить текст, который я могу просто внедрить в мою модель. Избавляется от стоп-слов (например,the
) и очищает текст от более явных орфографических ошибок. Например, одна и та же пара вопросов после очистки
question 1: one dissolve in water quickly sugar salt methane carbon di oxide
question 2: fish would survive in salt water
Запуск модели на чистом тексте (примечание: это требуетword_index
словарь и матрица встраивания) приводит к потере проверки 1.0955 через 5 эпох, что заметно повышает производительность:
Хотя эта производительность немного хуже, чем у лучших результатов Kaggle, потери при проверке не сходятся вообще.
Примечание: как причуды Кераса, эта модель тренируетсясущественнолучше на Tensorflow, чем на Theano.
Хотя это неплохая модель (ее точность составляет 81%), это далеко от лучших представлений Kaggle. Чтобы конкурировать с таблицей лидеров Kaggle, есть еще одна вещь, которую я должен учитывать при обучении моей нейронной сети:
Kaggle определяет утечку как «создание неожиданной дополнительной информации в данных обучения». Другими словами, помимо самих вопросов, что я могу извлечь из данных обучения, которые мне дали, чтобы улучшить мою модель?
Поскольку эти функции были случайно созданы при проведении конкурса, они не отражают набор данных (т. Е. Quora не сможет использовать эти функции самостоятельно, чтобы определить, являются ли вопросы дубликатами, эти функции уникальны для того, как этот набор данных будет быть созданным).
Есть две дополнительные функции, которые оказываются очень предсказуемыми, являются ли вопросы дубликатами:
Простое добавление этих двух утечек уменьшило мою потерю проверки до0.7754
после 5 эпох! (В сравнении с1.0955
для очищенного набора данных, и1.4161
изначально при использовании бэкэнда Theano).
Несколько выводов из этого:
question1 + question2
и вход для вопроса 2 былquestion 2 + question 1
; Оглядываясь назад, это вполне имеет смысл, поскольку порядок вопроса не должен иметь никакого отношения к тому, считает ли моя сеть их дубликатами, и это легко увеличивает объем обучающих данных, доступных для моей сети.
© machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map