Введение

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

Для простоты я классифицирую комментарии обзора на два класса: положительные и отрицательные. Отзывы со звездочкой выше трех считаются положительными, а отзывы со звездочкой меньше или равной трех - отрицательными. Таким образом, проблема обучения с учителем.

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

  • Часть-1: В этой части я строю нейронную сеть с LSTM, и встраивание слов было изучено при настройке нейронной сети.
  • Часть 2: В этой части я добавляю дополнительный одномерный сверточный слой поверх слоя LSTM, чтобы сократить время обучения.
  • Часть-3: В этой части-3 я использую ту же сетевую архитектуру, что и часть-2, но использую предварительно обученное встраивание 100-размерных слов перчатки в качестве начального ввода.
  • Часть 4. В части 4 я использую word2vec для изучения встраивания слов.

Импорт библиотек

В следующих фрагментах кода я использовал Kears для разработки моделей. Я использовал «Plotly» для построения интерактивных визуализаций слов. Для этой цели также можно использовать эффект боке. Библиотека «NLTK» использовалась для токенизации предложения и удаления стоп-слов.

# Keras
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers import Dense, Flatten, LSTM, Conv1D, MaxPooling1D, Dropout, Activation
from keras.layers.embeddings import Embedding
## Plotly
import plotly.offline as py
import plotly.graph_objs as go
py.init_notebook_mode(connected=True)
# Others
import nltk
import string
import numpy as np
import pandas as pd
from nltk.corpus import stopwords

from sklearn.manifold import TSNE

Обработка данных

Обработка данных имеет жизненно важное значение и должна быть важным этапом в исследовательском анализе данных в любом проекте по науке о данных. Если проект связан с необработанными текстовыми данными, очистка и обработка являются обязательными. В следующих подразделах я шаг за шагом опишу, как удалить ненужную информацию из необработанных комментариев.

1. Удалите числовые и пустые тексты.

Сначала прочтите данные:

df = pd.read_csv(‘train.csv’, sep = ‘|’, names = [‘stars’, ‘text’], error_bad_lines=False)

После прочтения данных я отбрасываю все нулевые значения с помощью функции pandas ‘dropna’. Затем отфильтруйте строки с нечисловыми символами в столбце со звездочкой. Точно так же я также отфильтровал все строки с пустыми комментариями.

df= df.dropna()
df = df[df.stars.apply(lambda x: x.isnumeric())]
df = df[df.stars.apply(lambda x: x !="")]
df = df[df.text.apply(lambda x: x !="")]

2. Преобразование оценок в классы (положительный = 1 и отрицательный = 0).

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

  • (1) Положительно: комментарии со звездами ›3 и
  • (2) Отрицательные: комментарии со звездочками ‹= 3
labels = df['stars'].map(lambda x : 1 if int(x) > 3 else 0)

2. Удалите ненужный текст.

При интеллектуальном анализе текста предварительная обработка и очистка должны выполняться поэтапно. Регулярное выражение становится важной частью этого шага. Regex может находить шаблон в необработанном, беспорядочном тексте и выполнять соответствующие действия. Недавно я опубликовал статью об использовании регулярных выражений в командной строке под названием Анализ текста в командной строке в статье На пути к науке о данных. Возможно, вам это будет интересно.

Из-за вычислительных затрат я использую 20000 лучших уникальных слов. Сначала токенизируйте комментарии, а затем преобразуйте их в последовательности. Я оставляю 50 слов, чтобы ограничить количество слов в каждом комментарии.

### Text Normalizing function. Part of the following function was taken from this link. 
def clean_text(text):
    
    ## Remove puncuation
    text = text.translate(string.punctuation)
    
    ## Convert words to lower case and split them
    text = text.lower().split()
    
    ## Remove stop words
    stops = set(stopwords.words("english"))
    text = [w for w in text if not w in stops and len(w) >= 3]
    
    text = " ".join(text)
    ## Clean the text
    text = re.sub(r"[^A-Za-z0-9^,!.\/'+-=]", " ", text)
    text = re.sub(r"what's", "what is ", text)
    text = re.sub(r"\'s", " ", text)
    text = re.sub(r"\'ve", " have ", text)
    text = re.sub(r"n't", " not ", text)
    text = re.sub(r"i'm", "i am ", text)
    text = re.sub(r"\'re", " are ", text)
    text = re.sub(r"\'d", " would ", text)
    text = re.sub(r"\'ll", " will ", text)
    text = re.sub(r",", " ", text)
    text = re.sub(r"\.", " ", text)
    text = re.sub(r"!", " ! ", text)
    text = re.sub(r"\/", " ", text)
    text = re.sub(r"\^", " ^ ", text)
    text = re.sub(r"\+", " + ", text)
    text = re.sub(r"\-", " - ", text)
    text = re.sub(r"\=", " = ", text)
    text = re.sub(r"'", " ", text)
    text = re.sub(r"(\d+)(k)", r"\g<1>000", text)
    text = re.sub(r":", " : ", text)
    text = re.sub(r" e g ", " eg ", text)
    text = re.sub(r" b g ", " bg ", text)
    text = re.sub(r" u s ", " american ", text)
    text = re.sub(r"\0s", "0", text)
    text = re.sub(r" 9 11 ", "911", text)
    text = re.sub(r"e - mail", "email", text)
    text = re.sub(r"j k", "jk", text)
    text = re.sub(r"\s{2,}", " ", text)
    ## Stemming
    text = text.split()
    stemmer = SnowballStemmer('english')
    stemmed_words = [stemmer.stem(word) for word in text]
    text = " ".join(stemmed_words)
return text
# apply the above function to df['text']
df['text'] = df['text'].map(lambda x: clean_text(x))

В приведенном выше фрагменте кода я использовал одну из эффективных встроенных функций panda, «карту», ​​которая будет использоваться в серии pandas (один столбец). «Карта» использует внешнюю функцию, которая принимает строковый аргумент и выполняет некоторые шаги по очистке. Сначала функция удаляет все знаки препинания, затем переводит все слова в нижний регистр. Я использовал список стоп-слов «NLTK», чтобы удалить их из текста. Позже функция выполняет некоторые операции с регулярным выражением, чтобы очистить ненужную часть текста. Наконец, я использовал «SnowballStemmer», чтобы обозначить слова. Стемминг - еще одна важная часть НЛП.

3. Токенизация и создание последовательности

Токенизация предложений - одна из важнейших частей обработки естественного языка. Токенизация делит предложение на список слов. Я использовал функцию токенизатора Keras для разметки строк и использовал другую важную функцию, «text_to_sequences», для создания последовательностей слов. Более подробную информацию можно найти на сайте Kears.

### Create sequence
vocabulary_size = 20000
tokenizer = Tokenizer(num_words= vocabulary_size)
tokenizer.fit_on_texts(df['text'])
sequences = tokenizer.texts_to_sequences(df['text'])
data = pad_sequences(sequences, maxlen=50)

Создайте нейронную сеть с LSTM

В следующем фрагменте кода я использовал библиотеку Keras для создания классификатора нейронной сети. Сеть начинается со слоя встраивания. Слой позволяет системе расширять каждый токен до более крупного вектора, позволяя сети представлять слово значимым образом. Уровень принимает 20000 в качестве первого аргумента, который является размером нашего словаря, и 100 в качестве второго входного параметра, который является размером встраивания. Третий параметр - input_length, равный 50, который представляет собой длину каждой последовательности комментариев.

## Network architecture
model = Sequential()
model.add(Embedding(20000, 100, input_length=50))
model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
## Fit the model
model.fit(data, np.array(labels), validation_split=0.4, epochs=3)
### Training output
Train on 1004322 samples, validate on 669548 samples
Epoch 1/3
1004322/1004322 [==============================] - 7913s - loss: 0.2875 - acc: 0.8776 - val_loss: 0.2553 - val_acc: 0.8934
Epoch 2/3
1004322/1004322 [==============================] - 7931s - loss: 0.2454 - acc: 0.8978 - val_loss: 0.2469 - val_acc: 0.8975
Epoch 3/3
1004322/1004322 [==============================] - 11974s - loss: 0.2291 - acc: 0.9057 - val_loss: 0.2530 - val_acc: 0.8977

Визуализация встраивания слов

В этом подразделе я хочу визуализировать веса встраивания слов, полученные из обученных моделей. Вложения слов со 100 измерениями сначала сокращаются до двух измерений с помощью t-SNE. В TensorFlow есть отличный инструмент для отличной визуализации вложений, но я просто использовал Plotly для визуализации слова в 2D-пространстве здесь, в этом уроке.

1. Получите утяжелители из перчатки.

word_embds = model.layers[0].get_weights()[

2. Составьте список слов.

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

3. Диаграмма рассеяния первых двух компонентов TSNE.

X_embedded = TSNE(n_components=2).fit_transform(word_weights)
number_of_words = 1000
trace = go.Scatter(
    x = X_embedded[0:number_of_words,0], 
    y = X_embedded[0:number_of_words, 1],
    mode = 'markers',
    text= word_list[0:number_of_words]
)
layout = dict(title= 't-SNE 1 vs t-SNE 2 for sirst 1000 words ',
              yaxis = dict(title='t-SNE 2'),
              xaxis = dict(title='t-SNE 1'),
              hovermode= 'closest')
fig = dict(data = [trace], layout= layout)
py.iplot(fig)

Хотите найти поблизости кого-нибудь, кто тоже интересуется машинным обучением?

Я собираюсь закончить эту статью, поделившись интересной информацией о xoolooloo. Это поисковая система на основе местоположения, которая находит местных жителей по схожим и множественным интересам. Например, если вы читаете эту статью, вас наверняка интересуют наука о данных, теория графов, машинное обучение. Таким образом, вы можете найти людей с этими интересами в вашем районе; зайдите на www.xoolooloo.com

Заключение

Большое спасибо за чтение. Полный код можно найти на Github. Поскольку мы выполнили некоторую необходимую обработку и очистку, а также построили модель нейронной сети с LSTM, в следующем руководстве я расскажу, как добавить дополнительный одномерный сверточный слой поверх слоя LSTM, чтобы сократить время обучения. А до тех пор, если у вас есть какие-либо вопросы, не стесняйтесь их задавать. Пожалуйста, комментируйте, если вы видите опечатки, ошибки или у вас есть предложения получше. Вы можете связаться со мной:

Email: [email protected]
LinkedIn: https://www.linkedin.com/in/sabber-ahamed/
Github: https://github.com/msahamed
Medium: https://medium.com/@sabber/