<jupyter_start><jupyter_text><jupyter_code>import numpy as np
import pandas as pd
import re
import nltk
from nltk.corpus import stopwords
import tensorflow
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense
from nltk import PorterStemmer
from nltk.sentiment.vader import SentimentIntensityAnalyzer
#from nltk.sentiment.util import *
import pandas as pd
from google.colab import drive
drive.mount("/content/gdrive")
# we have give a csv file which consists of all information about
# the products reviews
# loading the data using pandas' read_csv file.
import pandas as pd
data=pd.read_csv('/content/gdrive/MyDrive/ML/Amazon_Unlocked_Mobile.csv')
data.head()
data.describe()
len(data)
reviews=pd.DataFrame(data['Reviews'][:10000])
reviews
data.isnull().sum()<jupyter_output><empty_output><jupyter_text>As you can see there are 65171 Null values in Brand Name column, if we drop these Null values it means we will drop 65171 row which is a big loss of data. So instead of droping these Null values we will change the Null values into another Unknown brand Name, like this we will save our data<jupyter_code>data['Brand Name'].fillna('Unknown', inplace = True)

data['Rating'].value_counts().plot.bar(color='Blue')

data['sentiments'] = data['Rating'].apply(lambda x: 1 if x>=3 else 0)
data.head()
print(data['sentiments'].value_counts())
data['sentiments'].value_counts().plot.bar(color='Blue')
import nltk
nltk.download('vader_lexicon')
sentiment = SentimentIntensityAnalyzer()<jupyter_output>[nltk_data] Downloading package vader_lexicon to /root/nltk_data...
[nltk_data]   Package vader_lexicon is already up-to-date!<jupyter_text>Sentiment Scores:Compound score: is the sum of all of the lexicon ratings which have been standardised to range between -1 and 1<jupyter_code># only for Zero row of the reviews column
sentiment.polarity_scores(reviews.loc[0,'Reviews'])['compound']

for sentences in reviews['Reviews']:
    s = sentiment.polarity_scores(sentences)
    for k in sorted(s):
        print('{0}: {1}, '.format(k, s[k]))
    print(sentences)
reviews['polarity_score'] = reviews['Reviews'].apply(lambda x: sentiment.polarity_scores(str(x))['compound'])

reviews['neutral'] = reviews['Reviews'].apply(lambda x:sentiment.polarity_scores(str(x))['neu'])
reviews['negative'] = reviews['Reviews'].apply(lambda x:sentiment.polarity_scores(str(x))['neg'])
reviews['positive'] = reviews['Reviews'].apply(lambda x:sentiment.polarity_scores(str(x))['pos'])

reviews.head()
reviews['sentiment']=''
reviews.head()
reviews.loc[reviews.polarity_score>0,'sentiment']='Positive'
reviews.loc[reviews.polarity_score==0,'sentiment']='Neutral'
reviews.loc[reviews.polarity_score<0,'sentiment']='Negative'
reviews.head()
import matplotlib.pyplot as plt
%matplotlib inline
reviews.sentiment.value_counts().plot(kind='bar', title="Sentiment analysis")<jupyter_output><empty_output><jupyter_text>Separate Dependent and Idependent Features<jupyter_code># Dependent Features
y = data['sentiments']

# Independent Features
X = data.drop('sentiments', axis=1)<jupyter_output><empty_output><jupyter_text>Porter StemmerChange the words into its root words<jupyter_code>nltk.download('stopwords')

messages = X.copy()
stopwords = set(stopwords.words('english'))
ps = PorterStemmer()
corpus = []
for i in range(0, len(messages)):
    review = re.sub('[^a-zA-Z]', ' ', str(messages['Reviews'][i]))
    review = review.lower()
    review = review.split()
    
    review = [ps.stem(word) for word in review if not word in stopwords]
    review = ' '.join(review)
    corpus.append(review)
corpus[1]<jupyter_output><empty_output><jupyter_text>Tokenizing<jupyter_code>voc_size = 50000
max_length = 150
embedding_features = 32
tokenizer = Tokenizer(num_words = voc_size, oov_token="<OOV>")
tokenizer.fit_on_texts(corpus)<jupyter_output><empty_output><jupyter_text>Here, the value of oov_token is set to be ‘OOV’. That means any unknown words will be replaced by oov_token Embedding<jupyter_code>sequences = tokenizer.texts_to_sequences(corpus)
embedded_docs = pad_sequences(sequences, maxlen=max_length, padding='post', truncating='post')
embedded_docs[0]
X_final = np.array(embedded_docs)
y_final = np.array(y)
X_final.shape, y_final.shape<jupyter_output><empty_output><jupyter_text>Model Creation<jupyter_code>from tensorflow.keras.layers import Dropout
model = Sequential()
model.add(Embedding(voc_size, embedding_features, input_length=max_length))
model.add(Dropout(0.33))
model.add(LSTM(100))
model.add(Dropout(0.33))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.33))
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.33))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss = 'binary_crossentropy', optimizer='adam', metrics = ['accuracy'])
print(model.summary())<jupyter_output>Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 embedding (Embedding)       (None, 150, 32)           1600000   
                                                                 
 dropout (Dropout)           (None, 150, 32)           0         
                                                                 
 lstm (LSTM)                 (None, 100)               53200     
                                                                 
 dropout_1 (Dropout)         (None, 100)               0         
                                                                 
 dense (Dense)               (None, 64)                6464      
                                                                 
 dropout_2 (Dropout)         (None, 64)                0         
                                                        [...]<jupyter_text>Split Data into Train and Test<jupyter_code>from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_final, y_final, test_size=0.33, random_state=42)<jupyter_output><empty_output><jupyter_text>Model Training<jupyter_code>model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs = 10, batch_size=64)<jupyter_output>Epoch 1/10
4333/4333 [==============================] - 948s 218ms/step - loss: 0.5472 - accuracy: 0.7660 - val_loss: 0.5452 - val_accuracy: 0.7646
Epoch 2/10
4333/4333 [==============================] - 930s 215ms/step - loss: 0.5266 - accuracy: 0.7690 - val_loss: 0.5215 - val_accuracy: 0.7646
Epoch 3/10
4333/4333 [==============================] - 927s 214ms/step - loss: 0.5310 - accuracy: 0.7658 - val_loss: 0.5457 - val_accuracy: 0.7646
Epoch 4/10
4333/4333 [==============================] - 946s 218ms/step - loss: 0.5443 - accuracy: 0.7658 - val_loss: 0.5447 - val_accuracy: 0.7646
Epoch 5/10
4333/4333 [==============================] - 941s 217ms/step - loss: 0.5334 - accuracy: 0.7659 - val_loss: 0.5438 - val_accuracy: 0.7654
Epoch 6/10
4333/4333 [==============================] - 938s 216ms/step - loss: 0.5349 - accuracy: 0.7701 - val_loss: 0.5429 - val_accuracy: 0.7661
Epoch 7/10
4333/4333 [==============================] - 956s 221ms/step - loss: 0.4879 - accuracy: 0.7871 - val_[...]<jupyter_text>Performance Metrics and Accuracy<jupyter_code>y_predict = ((model.predict(X_test)>0.5).astype('int32'))<jupyter_output><empty_output><jupyter_text>Confusion Matrix<jupyter_code>from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, y_predict)<jupyter_output><empty_output><jupyter_text>Accuracy Score<jupyter_code>from sklearn.metrics import accuracy_score
accuracy_score(y_test, y_predict)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1514066496163683, 'fraction_numerical': 0.046419437340153455, 'mean_word_length': 4.224448897795591, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 54, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 15, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '361198', 'license': 'Apache-2.0', 'n_tokens_mistral': 2792, 'n_tokens_neox': 2483, 'n_words': 539, 'path': 'amazon_reviews_sentiment_analysis.ipynb', 'repo_name': 'appaniakhil/Sentiment-Analysis-on-Amazon-mobile-reviews-dataset-431k-reviews-using-LSTMS', 'size': '7820'}