Есть много вариантов того, как это сделать, и они зависят от количества данных, которые у вас есть, и времени, которое вы хотите инвестировать в это. Я попытаюсь дать вам основной путь, который вы можете улучшить самостоятельно, приведя некоторые альтернативы. Я не буду предполагать наличие предварительных знаний о моделировании текста с помощью глубокого обучения.
Один из способов — смоделировать проблему как многоклассовую классификацию, где классы/типы меток — это все возможные теги POS. Существует два наиболее распространенных способа обрамления модели глубокого обучения. Один из них — оконная модель. Другой — теггер последовательности, использующий рекуррентную единицу.
Давайте предположим простейшую из них — модель окна. Затем вы можете сделать следующее:
Структурирование данных
- Разбейте корпус на окна из
W
слов (например, 3 слова), где центральное слово — это то, которое вы хотите классифицировать, а остальные — в контексте. Назовем эту часть данных X
.
- Для каждого окна получите тег POS для центрального слова. Назовем эту часть данных
y
Кодирование данных
Кодирование X в виде векторов
Теперь нейросети нужно X
закодировать как последовательность векторов. Обычный выбор - кодировать каждое слово как встраивание слова.
Для этого сначала вы токенизируете свой текст и кодируете каждое слово как целочисленный идентификатор слова (например, каждое появление «кошки» будет числом 7). Если у вас нет собственного токенизатора, вы можете использовать токен, поставляемый с Keras. Это принимает текст и возвращает последовательность целых чисел/идентификаторов слов.
Во-вторых, вы можете захотеть дополнить и обрезать каждую последовательность идентификаторов слов, чтобы все экземпляры имели одинаковую длину (примечание: есть и другие способы справиться с этим). пример из imdb_lstm.py:
(X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features)
print(len(X_train), 'train sequences')
print(len(X_test), 'test sequences')
print('Pad sequences (samples x time)')
X_train = sequence.pad_sequences(X_train, maxlen=maxlen)
X_test = sequence.pad_sequences(X_test, maxlen=maxlen)
print('X_train shape:', X_train.shape)
print('X_test shape:', X_test.shape)
Затем вы можете использовать слой Embedding для преобразования последовательности дополненных/усеченных идентификаторов слов в последовательность встраивания слов. Пример из imdb_lstm.py:
model = Sequential()
model.add(Embedding(max_features, 128, dropout=0.2))
model.add(LSTM(128, dropout_W=0.2, dropout_U=0.2)) # try using a GRU instead, for fun
Здесь выходные данные Embedding используются для передачи в LSTM. Я перечисляю другие варианты моделей в конце.
Кодировка г
Чтобы выполнить многоклассовую классификацию с помощью Keras, обычно используется categorical_crossentropy, которая ожидает, что метка будет горячим вектором, длина которого равна количеству возможных категорий (количество возможных тегов POS в вашем случае). Вы можете использовать to_categorical keras. Обратите внимание, что он ожидает целочисленный вектор, где каждое целое число представляет класс (например, NNP может быть 0, VBD может быть 1 и т. д.):
def to_categorical(y, nb_classes=None):
'''Convert class vector (integers from 0 to nb_classes) to binary class matrix, for use with categorical_crossentropy.
# Arguments
y: class vector to be converted into a matrix
nb_classes: total number of classes
# Returns
A binary matrix representation of the input.
'''
Варианты модели
Поскольку в этой строке решения вы в основном выполняете классификацию по нескольким классам, вы можете в основном использовать imdb_ любые примеры из примеры keras. На самом деле это примеры классификации двоичного текста. Чтобы сделать их мультиклассовыми, вам нужно использовать softmax вместо сигмоида в качестве окончательной функции активации и categorical_crossentropy вместо binary_crossentropy, как в mnist_ примеры:
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='adadelta',
metrics=['accuracy'])
person
Daniel Adiwardana
schedule
15.11.2016