Некоторое время назад во время проекта коллега использовал когнитивный API Azure для анализа настроений в форме обратной связи. Мне было любопытно, как сделать это с нуля, и хотя наличие API очень удобно, если вы хотите сделать с ним что-то особенное, вам нужно иметь возможность его адаптировать. И то, что я хотел сделать, - это попытаться извлечь сантименты из сообщений чата разногласий, а не из среднего обзора.
И хотя у них нет такой же структуры и контекста, как у прямого обзора, между очень эмоционально нагруженными комментариями есть сходства, и это те, которые я хотел уловить.
Поэтому я провел небольшое исследование и нашел для начала два очень многообещающих набора данных.
Данные
Первым набором данных был набор данных настроений IMDB при обзоре, он пригодился, потому что это были данные прямого обзора. И хотя я не собирался анализировать обзоры, слова и контекст каждого обзора похожи на то, из чего может состоять очень положительно или отрицательно нагруженный комментарий, поэтому я использовал этот набор данных в качестве индекса слов. И, как плюс, этот набор данных теперь поставляется с Keras! Выиграть!
word_dict = imdb.get_word_index() def encode_sentence(text): result = [] arr = text_to_word_sequence(text, lower=True, split=" ") for word in arr: w = encode_word(word) if w is not None: result.append(w) return result def encode_word(word): if word not in word_dict: return None return word_dict[word]
Второй набор - это набор данных настроений Twitter, который состоит из 1,5 миллионов твитов и соответствующих меток настроений. Это набор данных, который я использовал для обучения.
def build_dataset(max_len): df = pd.read_csv("data/twitter.csv", delimiter=",", names=["y", "X"], usecols=[1,3], header=None, nrows=6000) Xts = df["X"].values arr = [] for text in Xts: arr.append(encode_sentence(text)) X = sequence.pad_sequences(arr, maxlen=max_len) y = df["y"].values return (X, y)
Вы можете найти ссылку на этот набор данных здесь: http://thinknook.com/twitter-sentiment-analysis-training-corpus-dataset-2012-09-22/
Модель
def build_model(words, vec_len, review_len): model = Sequential() model.add(Embedding(words, vec_len, input_length=review_len)) model.add(Dropout(0.25)) model.add(Conv1D(32, 3, padding="same")) model.add(MaxPooling1D(pool_size=2)) model.add(Conv1D(16, 3, padding="same")) model.add(Flatten()) model.add(Dropout(0.25)) model.add(Dense(100, activation="sigmoid")) model.add(Dropout(0.25)) model.add(Dense(1, activation="sigmoid")) model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"]) model.summary() return model
Как вы можете видеть, модель представляет собой линейную модель Кераса, начинающуюся с ввода встраивания слова, проходящую через несколько одномерных сверток и максимальных пулов, прежде чем она будет сглажена, пройдена через активированный сигмовидной кишкой плотный слой и завершится одним нейроном, активируемым сигмовидной кишкой, который это наш результат.
Обучение
Я обучил сеть более чем 20 эпохам из 6000 твитов и словарю, составленному из 10000 наиболее распространенных слов, используемых в обзорах IMDB. Вы можете увеличить это, но я был на ноутбуке с одним графическим процессором 940mx, поэтому у меня не было такой доступной вычислительной мощности. «Обзоры» здесь - это твиты, которые, очевидно, имеют максимальную длину 128 символов.
# Parameters words = 10000 review_len = 128 vec_len = 300 patience = 5 batch_size = 15 epochs = 20 # Load data X, y = build_dataset(review_len) # Build model model = build_model(words, vec_len, review_len) # Early stopping early_stopping_monitor = EarlyStopping(patience=patience, monitor="loss", mode="auto") # Fit model model.fit(X, y, epochs=epochs, callbacks=[early_stopping_monitor], batch_size=batch_size, verbose=1, validation_split=0.25)
Результаты и тестирование
Я интегрировал модель в рудиментарного бота Discord на базе nodejs и протестировал с несколькими предложениями.
Полученный результат соответствует тому, что я хотел, он оценивает отрицательные комментарии близко к 0, а положительные комментарии - к 1.
Хотя это не идеальная модель и, вероятно, слишком много подходит, она служит хорошим введением в анализ настроений для тех, кто хочет начать, получайте удовольствие!
Github
Https://github.com/dscplatform/discordbot/tree/master/cognitive/emotion