В этом блоге мы будем использовать набор данных Yelp-round 10 review, чтобы узнать, является ли отзыв положительным или отрицательным.

Данные выглядят так:

Проще говоря, мы классифицируем отзыв как положительный, если он имеет более 3 звезд, и отрицательный, если он имеет меньше или равно 3 звезд. Следовательно, это Контролируемая задача.

Чтобы построить и обучить модель, мы сначала очищаем текст и преобразуем его в последовательности. Каждый комментарий к обзору имеет ограничение в 50 слов. Короткие тексты менее 50 слов дополняются нулями, а длинные обрезаются. Начнем шаг за шагом.

Необработанные текстовые данные необходимо очищать и корректировать перед прохождением через любую модель машинного обучения или глубокого обучения. Итак, изначально мы удаляем все числовые и пустые места в наших данных (train.csv).

df = pd.read_csv(‘train.csv’) # reading data df.dropna(labels=["stars"].isnumeric()) # remove numeric df.dropna(labels=["stars"].!="") #remove spaces from stars(reviews) df.dropna(labels=["text"].!=""()) # remove spaces from text

Затем мы преобразуем рейтинговые звезды в два класса: один положительный (звезды › 3) и другой отрицательный (звезды ‹= 3).

labels = df['stars'].map(lambda x : 1 if int(x) > 3 else 0)

Теперь в def clean_text() мы включаем небольшую обработку

text = text.translate(string.punctuation) # remove puncuation
text = text.lower().split() # convert to lower case & split them
# remove stopwords (words like -for,a,an,the,etc.) stops = set(stopwords.words("english")) text = [w for w in text if not w in stops and len(w) >= 3] text = " ".join(text)
# stemming text=text.split() stemmer = SnowballStemmer('english') stemmed_words = [stemmer.stem(word) for word in text] text = " ".join(stemmed_words)

Мы применяем эту функцию к тексту

df['text'] = df['text'].map(lambda x: clean_text(x))

2.СОЗДАЙТЕ МОДЕЛЬ :

Использование CNN в дополнение к LSTM в некоторой степени повышает скорость обучения. ConvNets предназначены только для изображений. Сверточные нейронные сети (CNN) пропускают ядро/фильтр по данным и вычисляют представление более высокого уровня. Несмотря на то, что у них нет возможности обработки последовательности LSTM, они на удивление хорошо работают с текстом.

def create_model(): model=Sequential() model.add(Embedding(vocabulary_size,100,input_length=50)) model.add(Dropout(0.2)) model.add(Conv1D(64, 5, activation='relu')) model.add(MaxPooling1D(pool_size=4)) model.add(LSTM(100)) model.add(Dense(1,activation='sigmoid')) model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy']) return model

Здесь,

— Слой внедрения: первый аргумент (vocabulary_size) — это количество различных слов в обучающем наборе. Второй аргумент (100) указывает размер векторов встраивания. Аргумент input_length определяет размер каждой входной последовательности.

— Мы используем слой Conv1D с размером ввода 64 и фильтруем как 5*5 с активацией как relu. Хотя объяснение этих терминов займет уйму времени, обратитесь к документации keras.

— Мы включаем слой LSTM из 100 единиц.

— И скомпилировать нашу модель с Адамом в качестве оптимизатора с потерей cross_entropy. На самом деле, если мы включим только LSTM, оптимизатор Rmsprop, как правило, работает хорошо.

3. ВРЕМЯ ТРЕНИРОВКИ:

model=create_model() model.fit(data, np.array(labels),validation_split=0.4,epochs=3)

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

Train on 1004322 samples, validate on 669548 samples Epoch 1/3 1004322/1004322 [==============================] - 20429s - loss: 0.2981 - acc: 0.8711 - val_loss: 0.2786 - val_acc: 0.8814 Epoch 2/3 1004322/1004322 [==============================] - 3363s - loss: 0.2657 - acc: 0.8871 - val_loss: 0.2774 - val_acc: 0.8820 Epoch 3/3 1004322/1004322 [==============================] - 11838s - loss: 0.2495 - acc: 0.8954 - val_loss: 0.2768 - val_acc: 0.8841

Вуаля! Мы добились точности 88 % благодаря правильной настройке параметров и оптимизации (поэкспериментируйте, чтобы достичь еще большего).

#plot words conv_tsne_embds = TSNE(n_components=2).fit_transform(conv_embds) plot_words(conv_tsne_embds, 0, 2000, 1)

СЕЙЧАС, визуализируя это,

Теперь мы попробуем другой подход, используя встраивание слов из предварительно обученного метода GloVe… Это метод, основанный на прогнозировании, в текстовых RNN…

Перчатка имеет размер вектора вложения 50, 100, 200 и 300 измерений. Мы идем со 100-мерной версией.

embed_index = dict() f=open('glove.6B/glove.6B.100d.txt') #need to download its weights for line in f: values = line.split() word = values[0] coefs=np.asarray(values[1:], dtype='float32') embed_index[word]=coefs f.close()

Получить список слов

word_list = [] for word, i in tokenizer.word_index.items(): word_list.append(word)

Нужно создать матрицу для слов…

embed_matrix=np.zeros((vocabulary_size, 100)) for word, index in tokenizer.word_index.items(): if index > vocabulary_size - 1: break else: embed_vector = embed_index.get(word) if embed_vector is not None: embed_matrix[index]=embed_vector

Затем создайте модель, подходящую для вышеуказанного…

model_2=Sequential() model_2.add(Embedding(vocabulary_size,100,input_length=50,weights=[embedding_matrix],trainable=False)) model_2.add(Dropout(0.2)) model_2.add(Conv1D(64, 5, activation='relu')) model_2.add(MaxPooling1D(pool_size=4)) model_2.add(LSTM(100)) model_2.add(Dense(1, activation='sigmoid')) model_2.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])

Поскольку нас интересует, как модель работает, когда веса не обновляются, мы устанавливаем trainable=False в нашем слое внедрения.

Затем мы подгоняем наши данные к модели…

model_2.fit(data, np.array(labels),validation_split=0.4,epochs = 3)
#plot words glove_tsne_embds = TSNE(n_components=2).fit_transform(glove_emds) plot_words(glove_tsne_embds, 0, 2000, 1)

И визуализируя здесь, мы получаем

Если вы хотите узнать о t-sne, прочитайте здесь…

Итак, это был базовый блог по классификации текста с использованием комбинации Cnn+lstm, и весь код можно найти здесь.

ПОЛЕЗНЫЕ РЕСУРСЫ:

https://github.com/bhaveshowal/CNN-text-classification-keras

https://www.kaggle.com/vsmolyakov/keras-cnn-with-fasttext-embeddings

https://richliao.github.io/supervised/classification/2016/11/26/textclassifier-convolutional/

http://debajyotidatta.github.io/nlp/deep/learning/word-embeddings/2016/11/27/Understanding-Convolutions-In-Text/

Первоначально опубликовано на сайте blog.lipishala.com 6 октября 2018 г.