Anda di halaman 1dari 9

Pengantar Pemrosesan Teks dengan Keras (Bagian 2: Representasi... https://yudiwbs.wordpress.com/2019/02/21/pengantar-pemrosesan...

Blog Yudi Wibisono


…tentang apa saja ….

Pengantar Pemrosesan Teks dengan Keras


(Bagian 2: Representasi Teks, Klasifikasi
dengan Feedforward NN )
Ini adalah lanjutan dari bagian 1.  Sebaiknya baca bagian1 tersebut jika belum 
mengenal tentang konsep tensor, dimensi, shape pada Keras.

Representasi Teks

Teks perlu dikonversi menjadi angka sebelum menjadi input neural network.
Keras menyediakan class Tokenizer. Tokenizer ini berfungsi untuk
mengkonversi teks menjadi urutan integer indeks kata atau vektor binary,
word count atau tf-idf.

Contoh penggunaannya adalah sebagai berikut:

1 from keras.preprocessing.text import Tokenizer


2 tokenizer = Tokenizer()
3 texts = ["Budi makan nasi","Rudi makan nasi, nasi goreng."
4 tokenizer.fit_on_texts(texts)
5  
6 seq = tokenizer.texts_to_sequences(texts)
7 #kalimat baru
8 seq1 = tokenizer.texts_to_sequences(["nasi panas sekali"])
9 print("Index: "+
+str(tokenizer.word_index))
10 print("Seq. corpus:"+
+str(seq))
11 print("Seq. untuk 'nasi panas sekali':"+
+str(seq1))

Hasilnya akan seperti ini:

1 Indeks: {'rudi': 4, 'budi': 3, 'nasi': 1, 'makan': 2, 'goreng': 5}


2 Seq. corpus':[[3, 2, 1], [4, 2, 1, 1, 5]]
3 Seq. untuk 'nasi panas sekali':[[1]]
4 Catatan: "panas" dan "sekali" tidak ada di kosakata jadi tidak ada inde

Dapat dilihat kosakata corpus diubah menjadi indeks (indeks pertama “nasi”,
kedua “makan” dan seterusnya). Kalimat kemudian diubah menjadi list urutan

1 of 9 2/23/21, 10:49 AM
Pengantar Pemrosesan Teks dengan Keras (Bagian 2: Representasi... https://yudiwbs.wordpress.com/2019/02/21/pengantar-pemrosesan...

dari indeks. List sequence ini kemudian dapat dikonversi menjadi  vektor
matriks numpy dengan sequences_to_matrix. Terdapat empat pilihan: tf-idf,
binary, count, freq.

Lanjutkan kode sebelumnya untuk mengubah representasi teks berupa urutan


indeks menjadi matriks tf-idf sampai frekuensi:

1 encoded_tfidf = tokenizer.sequences_to_matrix(seq,mode=="tfidf"
2 print("tfidf:")
3 print(encoded_tfidf)
4 encoded_binary = tokenizer.sequences_to_matrix(seq,mode=="binary"
5 print("binary:")
6 print(encoded_binary)
7 encoded_count = tokenizer.sequences_to_matrix(seq,mode=="count"
8 print("count:")
9 print(encoded_count)
10 encoded_freq = tokenizer.sequences_to_matrix(seq,mode=
="freq"
11 print("freq:")
12 print(encoded_freq)

Hasilnya:

1 tfidf:
2 [[0.         0.51082562 0.51082562 0.69314718 0.         0.        ]
3 [0.         0.86490296 0.51082562 0.         0.69314718 0.69314718]]
4 binary:
5 [[0. 1. 1. 1. 0. 0.]
6 [0. 1. 1. 0. 1. 1.]]
7 count:
8 [[0. 1. 1. 1. 0. 0.]
9 [0. 2. 1. 0. 1. 1.]]
10 freq:
11 [[0.         0.33333333 0.33333333 0.33333333 0.         0.        ]
12 [0.         0.4        0.2        0.         0.2        0.2

Hasil sudah berbentuk numpy array. Dapat dilihat padding dilakukan otomatis
untuk menyamakan dimensi dengan shape (2,6). Data ini dapat langsung
digunakan dalam proses pembuatan model. Alternatif lain adalah
menggunakan embedded layer yang akan dibahas dalam posting berikutnya.

Jika proses padding ingin dilakukan secara manual, Keras menyediakan


pad_sequences. Contoh penggunaan pad_sequences :

1 from keras.preprocessing.sequence import pad_sequences


2 print("Sebelum padding:")
3 print(seq)
4 X = pad_sequences(seq)
5 print("Sesudah padding:")
6 print(X)
7 print(X.shape)

Hasilnya:

2 of 9 2/23/21, 10:49 AM
Pengantar Pemrosesan Teks dengan Keras (Bagian 2: Representasi... https://yudiwbs.wordpress.com/2019/02/21/pengantar-pemrosesan...

1 Sebelum padding:
2 [[3, 2, 1], [4, 2, 1, 1, 5]]
3 Sesudah padding:
4 [[0 0 3 2 1]
5 [4 2 1 1 5]]
6 Shape: (2, 5)

Klasifikasi Teks

Dalam bagian ini, akan dilakukan klasifikasi teks menggunakan data SMS spam
berbahasa Indonesia dengan arsitektur yang paling sederhana yaitu feed
forward NN.

Data dapat didownload di:http://bit.ly/yw_sms_spam_indonesia

Jumlah sample 1143 dan ada tiga kelas dalam dataset ini:

0: sms normal (569 instance)


1: fraud atau penipuan (335 instance)
2: promo (239 instance)

Langkah pertama adalah meload data dari file csv, dapat digunakan library csv.
Tambahkan cell berikut.

1 import csv
2 nama_file = "C:\\yudiwbs\\data\\sms\\dataset_sms_spam_v1.csv"
3 data  = []
4 label = []
5 with open(nama_file, 'r', encoding=
='utf-8') as csvfile:
6 reader = csv.reader(csvfile, delimiter=
=',', quotechar=
='"')
7 next(reader) #skip header
8 for row in reader:
9 data.append(row[0])
10 label.append(row[1])
11 #test lihat dua data pertama
12 print(data[:2])
13 print(label[:2])
14 #Catatan: parameter encoding dapat dibuang jika muncul error

Alternatif lain adalah menggunakan pandas untuk membaca csv:

1 import pandas as pd
2 df = pd.read_csv(nama_file).values
3 data = df[:, 0]
4 label = df[:, 1]

Selanjutnya konversi label dari “1”, “2”, “3” menjadi representasi tensor:

1 from keras.utils import to_categorical

3 of 9 2/23/21, 10:49 AM
Pengantar Pemrosesan Teks dengan Keras (Bagian 2: Representasi... https://yudiwbs.wordpress.com/2019/02/21/pengantar-pemrosesan...

2 label = to_categorical(label)
3 print(label.shape)
4 print(label)

Hasilnya adalah Tensor 2D dengan shape (1143, 3) untuk label, karena ada 1143
instance dengan 3 nilai label yang mungkin (normal, fraud, promo)

Split data menjadi train dan test menggunakan scikit learn, 80% menjadi data
train, 20% menjadi data test.

1 #split jadi train-test


2 from sklearn.model_selection import train_test_split
3 X_train, X_test, y_train, y_test = train_test_split(data, label,
4 test_size=
=0.2,
5 random_state=
=123)

Konversi data teks menjadi tf-idf dan tensor. Pastikan Fit hanya dilakukan pada
data train untuk mencegah informasi di data test “bocor”.

1 #konversi teks ke tfidf


2 from keras.preprocessing.text import Tokenizer
3 tokenizer = Tokenizer()
4 #fit hanya berdasarkan data train
5 tokenizer.fit_on_texts(X_train)
6 #konversi train
7 seq_x_train = tokenizer.texts_to_sequences(X_train)
8 X_enc_train = tokenizer.sequences_to_matrix(seq_x_train,mode
9 #konversi test
10 seq_x_test  = tokenizer.texts_to_sequences(X_test)
11 X_enc_test  = tokenizer.sequences_to_matrix(seq_x_test,mode
12  
13 print(X_enc_train.shape)
14 print(X_enc_test.shape)
15 print(X_enc_train)

Hasilnya adalah tensor 2D dengan shape (914, 4384) untuk data train dan
tensor 2D (229, 4384) untuk data test.

Selanjutnya siapkan model dengan menambahkan layer

1 from keras import models


2 from keras import layers
3  
4 _,jum_fitur = X_enc_train.shape
5 model = models.Sequential()
6 model.add(layers.Dense(32,activation=='relu',input_shape=
=(jum_fitur,)))
7 model.add(layers.Dense(4,activation=
='relu'))
8 model.add(layers.Dense(3,activation=
='softmax'))  #karena kelasnya ada
9 model.compile(optimizer=
="adam",
10 loss=
='categorical_crossentropy',
11 metrics=
=['accuracy'])

Ada empat layer: layer pertama adalah layer input hasil encode tf-idf

4 of 9 2/23/21, 10:49 AM
Pengantar Pemrosesan Teks dengan Keras (Bagian 2: Representasi... https://yudiwbs.wordpress.com/2019/02/21/pengantar-pemrosesan...

sebelumnya: 4384 fitur. Mengapa input_shape tidak menggunakan sample


dimension atau sample axis seperti (914, 4384)? karena jumlah samples tidak
penting didefinisikan dalam layer input. Dengan teknik mini-batch, sample
dapat diproses sedikit demi sedikit, jadi jumlahnya bisa berbeda-beda.

Activation softmax digunakan karena jumlah label ada 3 (normal, fraud dan
promo). Jika jumlah label dua (binary classification) maka dapat digunakan
activation sigmoid. Setelah layer didefinisikan, maka layer dapat dicompile.
Loss categorical_crossentropy dipilih karena terdapat tiga kelas, sedangkan jika
untuk binary class dapat digunakan binary_crossentropy.

Kode untuk melakukan training adalah sebagai berikut:

1 history = model.fit(X_enc_train,y_train,
2 epochs=
=3, batch_size=
=2,
3 validation_split=
=0.2)
4  
5 results = model.evaluate(X_enc_test, y_test)
6 print("Hasil  [loss,acc] untuk data test:")
7 print(results)

Satu epoch adalah satu iterasi yang diperlukan untuk memproses seluruh
training data. Jika jumlah data training 1000, dan batch_size 20, maka untuk
memproses setiap epoch akan diperlukan 1000/20 = 50 steps update bobot.
Pada setiap step bobot network akan di-update.

Semakin kecil batch size, semakin kecil memori yang diperlukan dan proses
akan konvergen lebih cepat. Kelemahannya, akan memerlukan semakin
banyak steps dalam setiap epoch (waktu training semakin lama). Parameter
validation_split menentukan persentase data yang akan digunakan untuk data
validasi.

Data validasi diambil dari data train dan digunakan untuk meminimalkan nilai
loss pada saat training, val_acc dan val_loss adalah metrik untuk data validasi
ini. Setelah proses selesai baru kinerja diukur pada data test.

Setelah training selesai, hasilnya adalah sebagai berikut, untuk data test
didapat loss 0.33 dan akurasi 0.926 (komputer yang berbeda dapat
menghasilkan hasil berbeda):

Proses training dapat memerlukan waktu lama, untuk menyimpan model dan
hasil tokenizer ke dalam file gunakan kode berikut:

1 import pickle

5 of 9 2/23/21, 10:49 AM
Pengantar Pemrosesan Teks dengan Keras (Bagian 2: Representasi... https://yudiwbs.wordpress.com/2019/02/21/pengantar-pemrosesan...

2 model.save('model_spam_v1.h5')
3 with open('tokenizer.pickle', 'wb') as handle:
4 pickle.dump(tokenizer, handle, protocol=
=pickle.HIGHEST_PROTOCOL)

Berikut adalah kode untuk me-load model, tokenizer dan memprediksi label
untuk data baru:

1 from keras.models import load_model


2 import pickle
3 model = load_model('model_spam_v1.h5')
4 with open('tokenizer.pickle', 'rb') as handle:
5 tokenizer = pickle.load(handle)
6  
7 s  = ["Anda mendapat hadiah 100 juta","Beli paket Flash mulai 1GB"
8 seq_str = tokenizer.texts_to_sequences(s)
9 enc_str = tokenizer.sequences_to_matrix(seq_str,mode=
="tfidf"
10 enc_str.shape
11 pred = model.predict_classes(enc_str)
12 print("Prediksi kelas string ' {} ' adalah {}".format(s,pred))

Hasilnya:
Prediksi kelas string ‘ [‘Anda mendapat hadiah 100 juta, ‘Beli paket Flash mulai
1GB’, ‘Nanti ketemuan dimana?’] ‘ adalah [1 2 0]

Bersambung..  (word embedding, RNN)

Update Juni 2020: artikel ini tidak akan dibuat kelanjutannya, tapi materi
lengkap tentang ini bisa dilihat di: https://docs.google.com/document
/d/1SQkzjjBdjCNO7cexAAy9s0tGvTsKf1WUJiPrkKPLI-4/edit?usp=sharing

! Twitter " Facebook

Suka

8 blogger menyukai ini.

Pengolahan Teks (Text Word2Vec Wikipedia Pengantar Pemrosesan


Processing) Bahasa Indonesia dengan Teks dengan Keras (Bagian
dalam "penelitian" Python Gensim 1: Tensor, Batch, Layer dan
dalam "kuliah" Learning)
dalam "deep learning"

 21 Februari 2019  yudiwbs  bahasa indonesia, deep learning, kuliah, penelitian, text

6 of 9 2/23/21, 10:49 AM
Pengantar Pemrosesan Teks dengan Keras (Bagian 2: Representasi... https://yudiwbs.wordpress.com/2019/02/21/pengantar-pemrosesan...

processing

13 tanggapan untuk “Pengantar Pemrosesan Teks dengan


Keras (Bagian 2: Representasi Teks, Klasifikasi dengan
Feedforward NN )”

Tri
17 Maret 2019 pukul 12:07

Artikel yg sangat bagus, menjelaskan jargon2 deep learning dengan bahasa yg


mudah dipahami. Ditunggu artikel yg selanjutnya Pak! p.s. ada sedikit typo di
dimensi shape

yudiwbs 
18 Maret 2019 pukul 13:49

Makasih. Yg mana ya? tadi dicari nggak kelihatan.

Tri
19 Maret 2019 pukul 21:44

“dimensi dengan shape (2,6)” seharusnya (2,5) bukan? atau saya yang keliru,
maklum baru belajar

yudiwbs 
20 Maret 2019 pukul 18:05

Kalau melihat ouputnya memang (2,6), walaupun jumlah vocabnya 5.


Indeks pertama selalu bernilai nol. Tapi saya juga tidak tahu kenapa shape
output sequences_to_matrix tsb tidak (2,5) saja ya. Nanti saya coba lihat
dokumentasinya.

Fariz Bram
11 Juni 2019 pukul 12:36

artikel yang selalu bermanfaat tentang NLP-Python, sukses terus pak Yudi.

7 of 9 2/23/21, 10:49 AM
Pengantar Pemrosesan Teks dengan Keras (Bagian 2: Representasi... https://yudiwbs.wordpress.com/2019/02/21/pengantar-pemrosesan...

saya mahasiswa dari surabaya yang sedang riset di bidang NLP, sangat
terbantu dengan adanya artikel2 dari bapak.

Ahmad Kanzu
18 Oktober 2019 pukul 15:47

“Bersambung.. (word embedding, RNN)”. Belum ada artikelnya ya pak?

yudiwbs 
19 Oktober 2019 pukul 21:47

maaf memang belum. Keburu ada beberapa kerjaan yg tidak terkait dengan
NLP jadi ya begitu

toriqahmads
23 Juni 2020 pukul 23:27

Mohon maaf, saya masih belum paham untuk layernya

model.add(layers.Dense(32,activation=’relu’,input_shape=(jum_fitur,)))
model.add(layers.Dense(4,activation=’relu’))
model.add(layers.Dense(3,activation=’softmax’))

Knp layernya diisi dengan 32, 4, 3?


Boleh minta tolong untuk penjelasan detailnya?

Terima kasih banyak

yudiwbs 
24 Juni 2020 pukul 07:39

Coba-coba. Ini salah satu masalah utama di deep learning. Perlu coba-coba
konfigurasi. Memang sudah ada usaha dan riset tentang ini (coba googling
tentang AutoML), tapi sepertinya masih belum optimal juga.

toriqahmads
24 Juni 2020 pukul 12:19

8 of 9 2/23/21, 10:49 AM
Pengantar Pemrosesan Teks dengan Keras (Bagian 2: Representasi... https://yudiwbs.wordpress.com/2019/02/21/pengantar-pemrosesan...

Berarti nilai itu didapat melalui beberapa percobaan ya pak?


Jika dirasa output yg dihasilkan sudah bagus maka nilai itu yg dipakai?

yudiwbs 
24 Juni 2020 pukul 12:35

Ya betul, bukan beberapa lagi tapi banyak percobaan.

Afolra (@afolra)
22 September 2020 pukul 20:23

Maaf Pak, saya mau tanya, apakah ada link google docs untuk modul pelatihan
bagian 1? Karena dari link yang terlampir saya hanya dapat mengakses bagian
2 dan 3. Terima kasih, Pak

yudiwbs 
23 September 2020 pukul 09:53

Bagian pertama tentang machine learning secara umum (non teks)

Blog di WordPress.com.

9 of 9 2/23/21, 10:49 AM

Anda mungkin juga menyukai