<jupyter_start><jupyter_text>Majority of tweets are neutral and positive. Looks like there are not much negative tweets on Bitcoin! No wonder the price is skyrocketing!<jupyter_code># text length
df['text_length'] = df['tweet'].apply(len)
df[['label','text_length','tweet']].head()
g = sns.FacetGrid(df,col='label')
g.map(plt.hist,'text_length')<jupyter_output><empty_output><jupyter_text>As expected, most tweets are very short in length. We are going to clean up the tweets, remove special chars, stop words, URL links, etc..<jupyter_code>from nltk.corpus import stopwords

import re

def clean_text(s):
    s = re.sub(r'http\S+', '', s)
    s = re.sub('(RT|via)((?:\\b\\W*@\\w+)+)', ' ', s)
    s = re.sub(r'@\S+', '', s)
    s = re.sub('&amp', ' ', s)
    return s
df['clean_tweet'] = df['tweet'].apply(clean_text)

text = df['clean_tweet'].to_string().lower()
# Encode Categorical Variable
X = df['clean_tweet']
y = pd.get_dummies(df['label']).values
num_classes = df['label'].nunique()
seed = 101 # fix random seed for reproducibility
np.random.seed(seed)
# Split Train Test sets
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, 
                                                    test_size=0.2,
                                                    stratify=y,
                                                    random_state=seed)
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
# Tokenize Text
from keras.preprocessing.text import Tokenizer
max_features = 20000
tokenizer = Tokenizer(num_words=max_features)
tokenizer.fit_on_texts(list(X_train))
X_train = tokenizer.texts_to_sequences(X_train)
X_test = tokenizer.texts_to_sequences(X_test)
totalNumWords = [len(one_comment) for one_comment in X_train]
plt.hist(totalNumWords,bins = 30)
plt.show()
from keras.preprocessing import sequence
max_length = 30
X_train = sequence.pad_sequences(X_train, maxlen=max_length)
X_test = sequence.pad_sequences(X_test, maxlen=max_length)
print(X_train.shape,X_test.shape)

from keras.models import Sequential
from keras.layers import Dense,Embedding,Conv1D,MaxPooling1D,LSTM
from sklearn.metrics import accuracy_score,confusion_matrix,classification_report
from keras.callbacks import EarlyStopping
from keras.optimizers import Adam

batch_size = 128
epochs = 10<jupyter_output><empty_output><jupyter_text>This deep learning model will have 2 CNN layers, 1 LSTM layer, and final dense layer for classification<jupyter_code>max_features = 20000
embed_dim = 50

np.random.seed(seed)

model = Sequential()
model.add(Embedding(max_features, embed_dim, input_length=X_train.shape[1]))

model.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=2))  
model.add(LSTM(50, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
early_stopping = EarlyStopping(monitor='val_loss', patience=2, mode='min')

history = model.fit(X_train, y_train, 
                    validation_data=(X_test, y_test), 
                    epochs=epochs,
                    callbacks=early_stopping,
                    batch_size=batch_size, verbose=2)
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['Train', 'Val'], loc='upper left')
plt.show()
#Loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['Train', 'Val'], loc = 'upper left')
plt.show()
# predict class with test set
y_pred_test =  np.argmax(model.predict(X_test), axis=1)
print('Accuracy:\t{:0.1f}%'.format(accuracy_score(np.argmax(y_test,axis=1),y_pred_test)*100))
plt.tight_layout()
#confusion matrix
confmat = confusion_matrix(np.argmax(y_test,axis=1), y_pred_test)
confmat
#classification report
print('\n')
print(classification_report(np.argmax(y_test,axis=1), y_pred_test))

    
cm = pd.DataFrame(confmat , index = [i for i in df['label'].unique()], 
                  columns = [i for i in df['label'].unique()])

plt.figure(figsize = ( 9 ,7))
sns.heatmap(cm,annot=True , fmt="d")
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1404920671418717, 'fraction_numerical': 0.012876523338698551, 'mean_word_length': 4.8389261744966445, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '291664', 'license': 'Apache-2.0', 'n_tokens_mistral': 1573, 'n_tokens_neox': 1482, 'n_words': 297, 'path': 'tweet-sentiment-analysis-using-cnn-lstm_new.ipynb', 'repo_name': 'PraveenRS01/NLP_Project_using_LSTM', 'size': '4349'}