Итак, если вам интересно, что такое «сентиментальный анализ»?

Что ж, анализ настроений включает построение системы для сбора и определения эмоционального тона слов. На высоком уровне анализ тональности подразумевает использование обработки естественного языка, анализа текста, компьютерной лингвистики для систематического выявления, извлечения, количественной оценки и изучения аффективные состояния и субъективная информация.

Я участвовал в программе Реально или нет? НЛП с катастрофическими твитами » kaggle, и моя публичная оценка составила 0,79589. Я использовал SPACY для NLP и Universal Sentence Encoder для трансферного обучения.

Базовое исследование твитов

Самые распространенные ключевые слова

Я нанес большинство общих ключевых слов в набор данных поезда, основываясь на их появлении в твитах.

from collections import Counter
train.keyword = train['keyword'].str.replace("[^a-zA-Z#]", " ")
keyword = train.keyword[train.keyword.notnull()].tolist()
keyword = Counter(keyword)
keywords = pd.DataFrame(keyword.most_common(10), columns=['Keyword', 'Count'])
sns.set(rc={'figure.figsize':(14,6)})
sns.barplot(data = keywords, x = 'Keyword', y = 'Count')
plt.title("Most Common Keywords")
plt.show()

Wordcloud твитов

Облако слов - это новое визуальное представление текстовых данных, обычно используемое для изображения метаданных ключевых слов.

Распределение цели

Сбалансированное распределение зависимой переменной необходимо, потому что функция потерь обычно представляет собой сумму всех точек данных, поэтому модель будет иметь тенденцию уделять больше внимания данным большинства классов, а не данным меньшинств.

sns.countplot(train['target'])
plt.title("Distribution Of Target")
sns.set(rc={'figure.figsize':(10,8)})
plt.show()

НЛП со спа-центром

spaCy - ведущая библиотека для НЛП, которая быстро стала одним из самых популярных фреймворков Python. Большинство людей находят его интуитивно понятным, и в нем есть отличная документация.

spaCy использует модели, которые зависят от языка и имеют разный размер. Вы можете загрузить модель spaCy с помощью spacy.load.

import spacy
nlp = spacy.load('en')

Предварительная обработка текста

Есть несколько типов предварительной обработки, чтобы улучшить то, как мы моделируем с помощью слов. Первый - «лемматизация». «Лемма» слова - это его основная форма. Например, «прогулка» - это лемма слова «ходьба». Итак, если вы лемматизируете слово «ходьба», вы превратите его в «ходьба».

Также часто удаляются игнорируемые слова. Стоп-слова - это слова, которые часто встречаются в языке и не содержат много информации. Английские стоп-слова включают «the», «is», «and», «but», «not».

С токеном spaCy token.lemma_ возвращает лемму, а token.is_stop возвращает логическое значение True, если токен является стоп-словом (и False в противном случае).

from spacy.lang.en.stop_words import STOP_WORDS
stopwords = list(STOP_WORDS)
import string
punct=string.punctuation


def text_data_cleaning(sentence):
    doc = nlp(sentence)
    
    tokens = []
    for token in doc:
        if token.lemma_ != "-PRON-":
            temp = token.lemma_.lower().strip()
        else:
            temp = token.lower_
        tokens.append(temp)
    
    cleaned_tokens = []
    for token in tokens:
        if token not in stopwords and token not in punct:
            cleaned_tokens.append(token)
    return " ".join(cleaned_tokens)

Объедините ключевые слова и текст вверху, применив функцию очистки текста.

train.keyword = train.keyword.fillna("")
train['new_text'] = train.text
test.keyword = test.keyword.fillna("")
test['text'] = test.text
test['text'] = test.text.apply(lambda x: text_data_cleaning(x))

Данные обучения и тестирования

Я разделил помеченные данные, которые у нас есть, на две части, одна из которых может «обучать» данные, а другая, чтобы дать нам представление о том, насколько хорошо работает наша модель. Данные обучения проинформируют нашу модель о том, какие функции наиболее важны. Я сохраняю последние 20% данных, чтобы проверить точность нашей модели.

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(train.new_text.values, train.target.values, random_state = 42, test_size=0.2)
test_data = test.text.values

Универсальный кодировщик предложений

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

Керас встречает универсальный кодировщик предложений

Загрузил универсальный кодировщик предложений как переменную embed, чтобы он хорошо работал с Keras, необходимо обернуть его слоем Keras Lambda и явно передать его ввод как строку.

module_url = "https://tfhub.dev/google/universal-sentence-encoder/4"
embed = hub.KerasLayer(module_url, trainable=False, name='USE_embedding')
def build_model(embed):
    model = Sequential([
        Input(shape=[], dtype=tf.string),
        embed,
        Dense(1024, activation='elu'),
        BatchNormalization(),
        Dropout(0.5),
        Dense(512, activation='elu'),
        BatchNormalization(),
        Dropout(0.35),
        Dense(256, activation='relu'),
        BatchNormalization(),
        Dropout(0.1),
        Dense(1, activation='sigmoid')
    ])
    model.compile(Adam(lr=0.001), loss='binary_crossentropy', metrics=['accuracy'])
    
    return model
model = build_model(embed)
model.summary()

Глубокое обучение Архитектура модели

Мы можем просмотреть сводную информацию о модели и понять, что только слои Keras можно обучать, именно так работает задача трансферного обучения, гарантируя неизменность весов универсального кодировщика предложений.

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
USE_embedding (KerasLayer)   (None, 512)               256797824 
_________________________________________________________________
dense (Dense)                (None, 1024)              525312    
_________________________________________________________________
batch_normalization (BatchNo (None, 1024)              4096      
_________________________________________________________________
dropout (Dropout)            (None, 1024)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 512)               524800    
_________________________________________________________________
batch_normalization_1 (Batch (None, 512)               2048      
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 256)               131328    
_________________________________________________________________
batch_normalization_2 (Batch (None, 256)               1024      
_________________________________________________________________
dropout_2 (Dropout)          (None, 256)               0         
_________________________________________________________________
dense_3 (Dense)              (None, 1)                 257       
=================================================================
Total params: 257,986,689
Trainable params: 1,185,281
Non-trainable params: 256,801,408
_________________________________________________________________

Ранняя остановка

Ранняя остановка - это, по сути, остановка тренировки, когда ваши потери начинают увеличиваться или, другими словами, точность проверки начинает снижаться.

earlyStopping = EarlyStopping(monitor='val_loss', patience=10, verbose=1, mode='min')
mcp_save = ModelCheckpoint('model.hdf5', save_best_only=True, monitor='val_loss', mode='min')
reduce_lr_loss = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=7, verbose=2, epsilon=1e-4, mode='min')

Обучение модели

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

with tf.compat.v1.Session() as session:
    tf.compat.v1.keras.backend.set_session(session)
    session.run([tf.compat.v1.global_variables_initializer(), tf.compat.v1.tables_initializer()])
    history = model.fit(
        X_train, y_train,
        validation_data=(X_test,y_test),
        epochs=35,
        callbacks=[earlyStopping,reduce_lr_loss,mcp_save],
        batch_size=128
    )

История обучения модели

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

Точность

В sklearn есть функция sklearn.metrics.classification_report, которая вычисляет несколько типов прогнозных оценок для модели классификации. Итак, здесь я проверяю, как именно работает наша модель.

precision    recall  f1-score   support

           0       0.81      0.88      0.84       874
           1       0.81      0.72      0.76       649

    accuracy                           0.81      1523
   macro avg       0.81      0.80      0.80      1523
weighted avg       0.81      0.81      0.81      1523

И наконец, давайте посмотрим на прогнозы.

with tf.Session() as session:
    tf.compat.v1.keras.backend.set_session(session)
    session.run(tf.global_variables_initializer())
    session.run(tf.tables_initializer())
    model.load_weights('model.hdf5')
    sub = model.predict(test_data)
    

subm = pd.DataFrame()
subm['id'] = test['id']
subm['target'] = sub.round().astype(int)
subm.to_csv("pred.csv", index = False)

Заключение

Я построил модель обучения с передачей текста Keras, основанную на универсальном кодировщике предложений, и добился отличного результата в классификации тональности твитов. Универсальный кодировщик предложений может встраивать документы, поэтому не стесняйтесь экспериментировать с другими наборами данных, такими как классификация тем новостей, ответы на вопросы, семантический анализ и т. Д.

Вы можете найти блокнот kaggle здесь.

Спасибо за чтение…