Loading the lesson...
In the print dialog, choose "Save as PDF" as the destination.
Arabic NLP - Lesson 4
Building an Arabic sentiment classifier with Keras: trainable vs. pretrained embeddings and LSTM layers
tensorflow, keras, numpy, pandas, scikit-learn, gensim, nltkISRIStemmer!pip install tensorflow keras numpy pandas scikit-learn gensim requests tqdm nltk
import nltk
nltk.download('stopwords')
from nltk.stem.isri import ISRIStemmerSS2030) - Arabic tweets with binary sentiment labelsCSV, missing values droppeddf = pd.read_csv(csv_path, encoding="utf-8")
df = df.dropna()
# columns: text, Sentiment (1 = positive)Raw tweet
Strip punctuation
، . ؟ ! and newlines
Tokenize
split on whitespace
Remove stopwords
Arabic stopword list
Stem
ISRIStemmer
Processed text
stemmer = ISRIStemmer()
stop_words = set(stopwords.words("arabic"))
def preprocess_arabic_text(text):
text = text.replace("،", "").replace(".", "").replace("؟", "").replace("!", "")
words = text.split()
words = [stemmer.stem(w) for w in words if w not in stop_words]
return " ".join(words)Keras Tokenizer builds a word index capped at the top 10K wordstrain_test_splittokenizer = Tokenizer(num_words=10000)
tokenizer.fit_on_texts(df["processed_text"])
X_sequences = tokenizer.texts_to_sequences(df["processed_text"])
X_padded = pad_sequences(X_sequences, maxlen=100)Embedding
10000 x 300, trainable=True
LSTM(64)
return_sequences=True
LSTM(32)
Dense(1)
sigmoid
trainable_model = Sequential([
Embedding(input_dim=10000, output_dim=300, trainable=True),
LSTM(64, return_sequences=True),
LSTM(32),
Dense(1, activation='sigmoid')
])
trainable_model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])32Epoch 5/5 - accuracy: 0.9962 - val_accuracy: 0.8496
Trainable Embedding Model Accuracy: 0.85Word2Vec model for Arabic, trained on Twitter data (CBOW, 300 dimensions)gensimword2vec_model = gensim.models.Word2Vec.load(
'./aravec/full_grams_cbow_300_twitter.mdl')(vocab_size + 1) x 300AraVecAraVec: copy its vector into that word's rowembedding_matrix = np.zeros((len(tokenizer.word_index) + 1, embedding_dim))
for word, i in tokenizer.word_index.items():
if word in word2vec_model.wv:
embedding_matrix[i] = word2vec_model.wv[word]
# Embedding matrix shape: (11710, 300)AraVec vectors and frozen (trainable=False)Dropout, plus an extra Dense layerEmbedding
AraVec weights, trainable=False
LSTM(128)
return_sequences=True
Dropout(0.3)
LSTM(64)
Dense(32)
relu
Dense(1)
sigmoid
pretrained_model = Sequential([
Embedding(input_dim=len(tokenizer.word_index) + 1, output_dim=300,
weights=[embedding_matrix], trainable=False),
LSTM(128, return_sequences=True),
Dropout(0.3),
LSTM(64),
Dense(32, activation='relu'),
Dense(1, activation='sigmoid')
])32Epoch 5/5 - accuracy: 0.9760 - val_accuracy: 0.8555
Pretrained Word2Vec Model Accuracy: 0.86| Model | Test Accuracy |
|---|---|
| Trainable embedding (from scratch) | 0.85 |
Pretrained AraVec (frozen) | 0.86 |
Dropout in Model 2 further regularizes the deeper LSTM stackPreprocess
Tokenize / pad
Embed
LSTM
Classify
ISRI stemmingAraVec embeddings (frozen) transfer external knowledge and slightly boost accuracyLSTM layers with Dropout helps build deeper, more regularized sequence modelsMahmoud Abas|Intro To NN