BELAJAR ANALISIS DAN BAHASA PEMROGRAMAN

Klasifikasi Text Menggunakan RNN LSTM Python

Klasifikasi teks atau klasifikasi dokumen dapat dilakukan dengan berbagai cara dalam Machine Learning.

Artikel ini bertujuan untuk sama sama belajar bagaimana Recurrent Neural Network (RNN) menggunakan arsitektur Long Short Term Memory (LSTM) dapat diimplementasikan menggunakan Keras dan tensorflow untuk klasifikasi. Kita akan menggunakan sumber data yang di ambil dari Kaggle yaitu data Consumer Complaints Dataset for NLP yang bisa kalian akses disini.

Kalian juga bisa menggunakan Kaggle langsung seperti contoh yang akan kita gunakan di bawah. Jadi tidak perlu mendownload datanya kita akan langsung mencobanya di Kaggle karena support gpunya lumayan untuk training data. Kalian bisa copy code nya disini

The Data

Biro Perlindungan Keuangan Konsumen (CFPB) adalah agen federal AS yang bertindak sebagai mediator ketika timbul perselisihan antara lembaga keuangan dan konsumen. Melalui formulir web, konsumen dapat mengirimkan narasi perselisihan atau complaint mereka kepada agensi. 

Karena kesamaan antara kelas-kelas tertentu serta beberapa ketidakseimbangan kelas, maka digabungkan menjadi lima kelas:

  • credit reporting
  • debt collection
  • mortgages and loans (includes car loans, payday loans, student loans, etc.)
  • credit cards
  • retail banking (includes checking/savings accounts, as well as money transfers, Venmo, etc.) 

Dalam case yang akan kita kerjakan yaitu komplain konsumen, model mencoba untuk memprediksi produk mana yang menjadi keluhan. Ini adalah masalah klasifikasi teks dengan banyak kelas. Lets GO

Kita coba read dulu datanya sambil liat datanya itu seperti apa sih

data = pd.read_csv('../input/consume-complaints-dataset-fo-nlp/
                   complaints_processed.csv')
data.info()

data.head()
Oke kita sudah coba cek datanya bisa dilihat kalau datanya itu ada 3 kolom Unnamed:0, product dan narative dengan total row itu 162421.

data_n = data.drop(['Unnamed: 0'], axis= 1)
data_n.groupby(['product']).count()
import plotly.express as px
fig = px.bar(data_n.groupby(['product']).count(),
             labels={
                     "product": "Product",
                     "value": "Count of Complaint",
                     "variable": "Variable"
                 },
                title="Count Complaint in Each Product")
fig.show()

Disini kita coba lihat total kelasnya ada berapa dan ada berapa complaint total nya. Berarti credit_reporting mempunyai jumlah paling banyak yaitu 91172


Text Pre-processing

def print_plot(index):
    example = data_n[data_n.index == index][['narrative', 'product']].values[0]
    if len(example) > 0:
        print(example[0])
        print('Product:', example[1])
print_plot(10)

Next step kita akan coba cleaning datanya mungkin ada kata atau huruf yang masih kapital, mungkin juga ada simbol - simbol dll. Nantinya ini semua akan kita bersihkan .

Teks Pre-Processing kita akan mencakup langkah-langkah berikut:

  • Ubah semua teks menjadi huruf kecil.
  • Ganti simbol REPLACE_BY_SPACE_RE ('[/(){}\[\]\|@,;]') dengan spasi dalam teks.
  • Hapus simbol yang ada di BAD_SYMBOLS_RE ('[^0-9a-z #+_]') dari teks.
  • Hapus stop words.
  • Hapus angka dalam teks.

data_n = data_n.reset_index(drop=True)
REPLACE_BY_SPACE_RE = re.compile('[/(){}\[\]\|@,;]')
BAD_SYMBOLS_RE = re.compile('[^0-9a-z #+_]')
STOPWORDS = set(stopwords.words('english'))

def clean_text(text):
    """
        text: a string
        
        return: modified initial string
    """
    text = str(text)
    text = text.lower() # lowercase text
    text = REPLACE_BY_SPACE_RE.sub(' ', text) 
    # replace REPLACE_BY_SPACE_RE symbols by space in text. 
    # substitute the matched string in REPLACE_BY_SPACE_RE with space.
    
    text = BAD_SYMBOLS_RE.sub('', text) 
    # remove symbols which are in BAD_SYMBOLS_RE from text. 
    # substitute the matched string in BAD_SYMBOLS_RE with nothing. 
    #text = text.replace('x', '')
    #text = re.sub(r'\W+', '', text)
    text = ' '.join(word for word in text.split() if word not in STOPWORDS) 
    # remove stopwors from text
    return text
data_n['narrative'] = data_n['narrative'].apply(clean_text)
data_n['narrative'] = data_n['narrative'].str.replace('\d+', '')
print_plot(30)

Kita cek lagi data diatas sepertinya sudah aman ya 


LSTM Modeling

  • Membuat vektor teks komplain konsumen, dengan mengubah setiap teks menjadi urutan bilangan bulat atau menjadi vektor.
  • Batasi kumpulan data hingga 5.000 kata teratas.
  • Tetapkan jumlah maksimum kata dalam setiap keluhan pada 250.

# The maximum number of words to be used. (most frequent)
MAX_NB_WORDS = 50000
# Max number of words in each complaint.
MAX_SEQUENCE_LENGTH = 250
# This is fixed.
EMBEDDING_DIM = 100

tokenizer = Tokenizer(num_words=MAX_NB_WORDS, 
                      filters='!"#$%&()*+,-./:;<=>?@[\]^_`{|}~', 
                      lower=True)
tokenizer.fit_on_texts(data_n['narrative'].values)
word_index = tokenizer.word_index
print('Found %s unique tokens.' % len(word_index))

  • Truncate danpad urutan input sehingga semuanya memiliki panjang yang sama untuk pemodelan.

X = tokenizer.texts_to_sequences(data_n['narrative'].values)
X = pad_sequences(X, maxlen=MAX_SEQUENCE_LENGTH)
print('Shape of data tensor:', X.shape)
  • Mengubah label kategorikal menjadi angka.
Y = pd.get_dummies(data_n['product']).values
print('Shape of label tensor:', Y.shape)

  • Train test split.

X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size = 0.10, random_state = 42)
print(X_train.shape,Y_train.shape)
print(X_test.shape,Y_test.shape)
  • Lapisan pertama adalah embedded layer yang menggunakan 100 vektor panjang untuk mewakili setiap kata.
  • SpatialDropout1D melakukan variational dropout dalam model NLP.
  • Lapisan berikutnya adalah lapisan LSTM dengan 256 unit memori.
  • Lapisan berikutnya adalah lapisan LSTM dengan 128 unit memori.
  • Output layer harus membuat 5 nilai output, satu untuk setiap kelas.
  • Fungsi aktivasi adalah softmax untuk klasifikasi multi-kelas.
  • Karena merupakan masalah klasifikasi multi-kelas, categorical_crossentropy digunakan sebagai loss function.
## Model Architecture
model = tf.keras.Sequential([
    tf.keras.layers.Embedding(MAX_NB_WORDS, EMBEDDING_DIM,
                              input_length=X.shape[1]),
    tf.keras.layers.SpatialDropout1D(0.2),
    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(256, 
                                                       return_sequences=True)),
    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(128)),
    #tf.keras.layers.Dense(128, activation='softmax'),
    tf.keras.layers.Dense(5, activation='softmax')
])
model.summary()
model.compile(loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True), 
              optimizer='Nadam', metrics=["CategoricalAccuracy"])
## Make sure to use GPU before running this cell. 
num_epochs = 5
batch_size = 128
## For early stopping to ensure it doesnt overfit
callback = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=2)
history = model.fit(X_train, Y_train, 
                    epochs=num_epochs, batch_size=batch_size,
                    validation_split=0.1,
                    callbacks=[EarlyStopping(monitor='val_loss',
                                             patience=3,
                                             min_delta=0.0001)])


accr = model.evaluate(X_test,Y_test)
print('Test set\n  Loss: {:0.3f}\n  Accuracy: {:0.3f}'.format(accr[0],accr[1]))

plt.title('Loss')
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='test')
plt.legend()
plt.show();

plt.title('Accuracy')
plt.plot(history.history['categorical_accuracy'], label='train')
plt.plot(history.history['val_categorical_accuracy'], label='test')
plt.legend()
plt.show();
Plot menunjukkan bahwa model memiliki sedikit masalah pemasangan, lebih banyak data dapat membantu, tetapi lebih banyak epoch tidak akan membantu menggunakan data saat ini.
new_complaint = ['I am a victim of identity theft and someone stole my 
                 identity and personal information to open up a Visa credit 
                 card account with Bank of America. The following Bank of America 
                 Visa credit card account do not belong to me : XXXX.']
seq = tokenizer.texts_to_sequences(new_complaint)
padded = pad_sequences(seq, maxlen=MAX_SEQUENCE_LENGTH)
pred = model.predict(padded)
labels = ['credit_card',
'credit_reporting',
'debt_collection',
'mortgages_and_loans',
'retail_banking']
print(pred, labels[np.argmax(pred)])

Reference : https://machinelearningmastery.com/sequence-classification-lstm-recurrent-neural-networks-python-keras/





Klasifikasi Text Menggunakan RNN LSTM Python Klasifikasi Text Menggunakan RNN LSTM Python Reviewed by Jimmy Pujoseno on May 31, 2022 Rating: 5

No comments:

Recent Post

Powered by Blogger.