<jupyter_start><jupyter_text>Natural Language Processing <NAME>  Import Library<jupyter_code>import pandas as pd
import numpy as np
import string
import matplotlib.pyplot as plt
import tensorflow as tf
import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense,Embedding,LSTM, Dropout
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

import plotly.graph_objects as go

%matplotlib inline
import nltk
nltk.download('stopwords')
nltk.download('punkt')
from google.colab import drive
drive.mount('/content/drive/')<jupyter_output>Drive already mounted at /content/drive/; to attempt to forcibly remount, call drive.mount("/content/drive/", force_remount=True).<jupyter_text>Import DatasetThe dataset was obtained from Kaggle under the title Amazon Fine Food Reviews<jupyter_code>df = pd.read_csv('/content/drive/My Drive/dataset/Reviews.csv')
df.head()
df.shape<jupyter_output><empty_output><jupyter_text>Data Preprocessing<jupyter_code>df.isna().sum()
df = df.dropna()
df['Text'] = df['Text'] + ' ' + df['Summary']
df = df.drop(['Id','ProductId','UserId','ProfileName','HelpfulnessNumerator','HelpfulnessDenominator','Time','Summary'],axis=1)
df.head()
df = df[df["Score"]!=3]
df["Score"] = df["Score"].apply(lambda x : 1 if x>3 else 0)
class_dist = df['Score'].value_counts()

def ditribution_plot(x,y,name):
    fig = go.Figure([
        go.Bar(x=x, y=y)
    ])

    fig.update_layout(title_text=name)
    fig.show()

ditribution_plot(x= class_dist.index, y= class_dist.values, name= 'Class Distribution')
#dikarenakan data yang terlalu besar dan class distribution yang tidak seimbang maka kita harus mengurangi total data menjadi 5000 setiap kelasnya agar pemodelan berlangsung dengan cepat
df_zero = df[df['Score'] == 0].head(5000)
df_one = df[df['Score'] == 1].head(5000)
df = pd.concat([df_zero,df_one],axis=0)
class_dist = df['Score'].value_counts()
ditribution_plot(x= class_dist.index, y= class_dist.values, name= 'Class Distribution')<jupyter_output><empty_output><jupyter_text>Text Preprocessing<jupyter_code># remove punctuation and numbers in string
def clean(text) :
  for separator in string.punctuation:
    text = text.replace(separator,' ')
  
  words = []
  for word in text.split():
    word = word.strip()
    result_word = ''.join(i for i in word if not i.isdigit())
    words.append(result_word)
  
  return ' '.join(words)

df['Text'] = df['Text'].apply(lambda x: clean(x))
stop_words = set(stopwords.words('english'))
df['Text'] = df['Text'].apply(lambda x :  [w.lower() for w in word_tokenize(x) if not w.lower() in stop_words])
# back to normal string
df['Text'] = df['Text'].apply(lambda x :  ' '.join(x))
X = df['Text'].values
y = df['Score'].values
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, random_state = 1)<jupyter_output><empty_output><jupyter_text>Tokenization<jupyter_code>tokenizer = Tokenizer(num_words=20000, oov_token='x')
tokenizer.fit_on_texts(X_train) 
tokenizer.fit_on_texts(X_test)

sekuens_latih = tokenizer.texts_to_sequences(X_train)
sekuens_test = tokenizer.texts_to_sequences(X_test)

padded_latih = pad_sequences(sekuens_latih) 
padded_test = pad_sequences(sekuens_test)<jupyter_output><empty_output><jupyter_text>Make LSTM Based Model<jupyter_code>model = Sequential([
    Embedding(input_dim=20000, output_dim=16),
    LSTM(32),
    Dense(64, activation='relu'),
    Dropout(0.5),
    Dense(1, activation='sigmoid')
])
model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])<jupyter_output><empty_output><jupyter_text>Callback To Control Train<jupyter_code>Callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3, mode='min')<jupyter_output><empty_output><jupyter_text>Train LSTM Model<jupyter_code>history = model.fit(padded_latih, y_train, epochs=32, 
                    validation_data=(padded_test, y_test),callbacks=Callback)<jupyter_output>Epoch 1/32
250/250 [==============================] - 10s 35ms/step - loss: 0.4692 - accuracy: 0.7731 - val_loss: 0.2839 - val_accuracy: 0.8805
Epoch 2/32
250/250 [==============================] - 8s 32ms/step - loss: 0.1893 - accuracy: 0.9264 - val_loss: 0.2477 - val_accuracy: 0.9030
Epoch 3/32
250/250 [==============================] - 8s 32ms/step - loss: 0.0925 - accuracy: 0.9715 - val_loss: 0.2737 - val_accuracy: 0.9030
Epoch 4/32
250/250 [==============================] - 8s 32ms/step - loss: 0.0435 - accuracy: 0.9886 - val_loss: 0.3555 - val_accuracy: 0.8980
Epoch 5/32
250/250 [==============================] - 8s 32ms/step - loss: 0.0198 - accuracy: 0.9952 - val_loss: 0.4171 - val_accuracy: 0.8960<jupyter_text>Visualize the Training History of Model<jupyter_code>def graph(history):
    fig, ax = plt.subplots(1, 2, figsize=(15,5))
    ax[0].set_title('loss')
    ax[0].plot(history.epoch, history.history["loss"], label="Train loss")
    ax[0].plot(history.epoch, history.history["val_loss"], label="Validation loss")
    ax[1].set_title('acc')
    ax[1].plot(history.epoch, history.history["accuracy"], label="Train acc")
    ax[1].plot(history.epoch, history.history["val_accuracy"], label="Validation acc")
    ax[0].legend()
    ax[1].legend()
graph(history)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16580597565473995, 'fraction_numerical': 0.04039099963113242, 'mean_word_length': 6.033722438391699, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '293681', 'license': 'MIT', 'n_tokens_mistral': 2103, 'n_tokens_neox': 1920, 'n_words': 385, 'path': 'Learn Machine Learning Development/NLP Classification - Amazon Fine Food Review.ipynb', 'repo_name': 'irzanfn/Dicoding', 'size': '5439'}