Я хочу обучить Нейтральную сеть для Мульти-классификационный анализ настроений с использованием встраивания слов для твитов.
Вот мой код:
import pandas as pd
import numpy as np
import re
from nltk.corpus import stopwords
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from tensorflow.python.keras.preprocessing.text import Tokenizer
from tensorflow.python.keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers import Dense, Embedding, LSTM, GRU
from keras.layers.embeddings import Embedding
from keras.wrappers.scikit_learn import KerasClassifier
from keras.utils import np_utils
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.pipeline import Pipeline
Импорт данных
df = pd.DataFrame()
df = pd.read_csv('Tweets.csv', encoding='utf-8')
очистка твитов
def remove_mentions(input_text):
return re.sub(r'@\w+', '', input_text)
def remove_stopwords(input_text):
stopwords_list = stopwords.words('english')
whitelist = ["n't", "not", "no"]
words = input_text.split()
clean_words = [word for word in words if (word not in stopwords_list or word in whitelist) and len(word) > 1]
return " ".join(clean_words)
df.text = df.text.apply(remove_stopwords).apply(remove_mentions)
df.text = [tweet for tweet in df.text if type(tweet) is str]
X = df['text']
y = df['airline_sentiment']
Разделение моих данных на поезд иtest
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.25, random_state=37)
One-Hot Кодировать поле «Чувство»
Первоначально метки имеют тип строки: «нейтральный», «положительный», «отрицательный».Поэтому я сначала преобразовываю их в целое число, а затем применяю горячую кодировку:
le = LabelEncoder()
y_train_num = le.fit_transform(y_train.values)
y_test_num = le.fit_transform(y_test.values)
nb_classes = 3
y_train = np_utils.to_categorical(y_train_num, nb_classes)
y_test = np_utils.to_categorical(y_test_num, nb_classes)
Подготовка к встраиванию слов
tokenizer_obj = Tokenizer()
tokenizer_obj.fit_on_texts(X)
max_length = max([len(tweet.split()) for tweet in X])
print("max_length=%s" % (max_length))
vocab_size = len(tokenizer_obj.word_index) + 1
print("vocab_size=%s" % (vocab_size))
X_train_tokenized = tokenizer_obj.texts_to_sequences(X_train)
X_test_tokenized = tokenizer_obj.texts_to_sequences(X_test)
X_train_pad = pad_sequences(X_train_tokenized, maxlen=max_length, padding='post')
X_test_pad = pad_sequences(X_test_tokenized, maxlen=max_length, padding='post')
Определение и применение моей модели NN
EMBEDDING_DIM = 100
model = Sequential()
model.add(Embedding(vocab_size, EMBEDDING_DIM, input_length=max_length))
model.add(Dense(8, input_dim=4, activation='relu'))
model.add(Dense(3, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
model.fit(X_train_pad, y_train, batch_size=128, epochs=25, validation_data=(X_test_pad, y_test), verbose=2)
Причина, по которой я выбрал свой последний слой, чтобы иметь 3 выходных единицы, состоит в том, что это задача мультиклассификации, и у меня есть 3 класса.
Вот сводка модели:
Layer (type) Output Shape Param #
=================================================================
embedding_1 (Embedding) (None, 23, 100) 1488200
_________________________________________________________________
dense_1 (Dense) (None, 23, 8) 808
_________________________________________________________________
dense_2 (Dense) (None, 23, 3) 27
=================================================================
Total params: 1,489,035
Trainable params: 1,489,035
Non-trainable params: 0
_________________________________________________________________
Когда код достигает model.fit()
, я получаю следующую ошибку:
ValueError: Error when checking target: expected dense_2 to have 3 dimensions, but got array with shape (10980, 3)
Что я делаю не так?