Word2Vec: Embedding Teks Berbahasa Indonesia

Eko Setiawan
9 min readFeb 7, 2023

--

Photo by Romain Vignes on Unsplash

Jika anda pernah atau sedang mempelajari Natural Language Processing (NLP), tentunya anda tahu jika data berbentuk teks perlu diubah dulu menjadi data angka sebelum diproses oleh komputer. Hal ini sebenarnya tidak ekslusif dalam NLP saja, setiap program komputer yang menggunakan data teks dalam operasinya membutuhkan proses khusus agar data-data teks tersebut dalam dimengerti oleh komputer.

Dalam NLP, teknik mengubah data teks menjadi data angka sering disebut dengan word embedding. Ada beberapa teknik mengubah data teks menjadi angka yang sering digunakan, diantaranya yang paling sederhana seperti Label & One Hot Encoding, Bag of Words, TF-IDF, hingga teknik yang lebih kompleks seperti word2vec.

Dari beberapa teknik yang disebutkan diatas, word2vec merupakan teknik embedding dengan kemampuan terbaik dalam merepresentasikan semantik dari kata-kata. Secara singkat, word2vec mengubah setiap kata menjadi vektor dan kata-kata yang memiliki kemiripan makna (serta sering dipakai bersamaan) akan memiliki vektor yang mirip.

Bagi anda yang tertarik untuk mempelajari lebih jauh tentang cara kerja word2vec dapat mengunjungi sumber dibawah ini. Saya tidak menjelaskan secara mendalam tentang cara kerja word2vec karena tujuan dari artikel ini adalah untuk membuat model word embedding dengan word2vec pada data teks berbahasa indonesia.

Oke, sekian pengenalan tentang word embedding dan word2vec. Dari beberapa tutorial yang pernah saya tonton, hampir semuanya menggunakan data teks berbahasa Inggris dalam praktiknya. Karena sedikitnya tutorial atau artikel yang secara spesifik membahas tentang word embedding dengan data bahasa Indonesia, saya memutuskan untuk menulis artikel ini.

Data yang saya gunakan dalam artikel ini merupakan data yang di scrape dari WikiHow. Data ini berisi langkah-langkah melakukan sesuatu dalam bahasa indonesia dan dapat diakses pada github berikut.

Data tersebut harus didownload terlebih dahulu dan diupload ke Google Drive karena saya mengerjakan proyek ini menggunakan Google Colab. Ukuran data bahasa Indonesia yang disediakan sebesar 130,5 MB dengan format file pickle.

Mari kita mulai ngodingnya.

Pra-Proses Data

Langkah pertama yang saya lakukan adalah memasukkan data terlebih dahulu dan melihat format data yang tersedia. Pemilik data ini sendiri sudah memberikan contoh kode untuk memasukkan data ke Jupyter Notebook pada link ini.

# import libraries
import pickle
import os
import pandas as pd
import numpy as np
import re

# setting pandas's columns
pd.set_option('display.max_colwidth', None)

# connecting to google drive
from google.colab import drive
drive.mount('/content/drive',force_remount=True)

# load data
data_path = r'/content/drive/MyDrive/dataset/data_nlp/indonesian.pkl'
with open(data_path, 'rb') as f:
indo_docs=pickle.load(f)

f.close()

Jujur saja, setelah meload data saya sempat kebingungan dengan format penulisan data yang mirip dengan JSON.

Sebagai orang yang terbiasa dengan menyimpan data dalam tabel (DataFramenya pandas), saya memutuskan untuk memindahkan teks yang saya butuhkan ke tabel. Ini mungkin bukan cara terbaik karena bisa saja data dengan format pickle digunakan secara langsung pada GENSIM.

Data ini terdiri dari 16.308 artikel dari WikiHow, masing-masing artikel terdiri dari beberapa langkah yang berisi teks penjelasan dalam bahasa indonesia.

Contoh salah satu artikel pada data

Tiap data point (artikel) terdiri dari link artikel berbahasa indonesia, judul dari tiap metode, kesimpulan dari tiap metode, ringkasan langlah-langkah dari tiap metode, judul dalam bahasa inggris dan link artikel dalam bahasa inggris.

Setiap artikel memiliki jumlah metode yang berbeda-beda, begitu juga jumlah kata-katanya.

Setelah melalui melakukan beberapa percobaan koding, saya memutuskan untuk hanya memindahkan bagian judul dari masing-masing metode (sub_title), kesimpulan dari metode (summary) dan ringkasan langkah-langkah (document) metode tersebut.

def convert_docs_to_df(docs_data):
# list for storing each elements of data
article_sub_title = []
article_summary = []
article_document = []

# looping on each article on data
for doc in list(docs_data.items()):
text = doc[1]
titles = list(text.keys())

# looping on each sub_title / step on article
for sub_title in titles:
article_sub_title.append(sub_title)
article_summary.append(text[sub_title]['summary'])
article_document.append(text[sub_title]['document'])

result = pd.DataFrame({'sub_title' : article_sub_title, 'summary' : article_summary, 'document' : article_document})
return result

# convert the pickle data
data = convert_docs_to_df(indo_docs)
Data WikiHow dalam tabel

Dari 16.308 artikel, ada 47.481 metode yang berhasil diambil dari data pickle. Untuk memperbanyak data teks dalam pelatihan model embedding, saya menggabungkan kesimpulan dari tiap metode (summary) dengan ringkasan langkah-langkah (document).

data['full_document'] = data.summary + " " + data.document

Teks yang ada merupakan teks mentah yang masih terdapat banyak angka, tanda baca, huruf kapital dan karakter lainnya. Skrip Python dibawah ini saya gunakan untuk membersihkan data.

# let's clean the data
def text_cleaning(text):
result = text.lower() # apply lowercas
result = result.replace('-', ' ') # get rid of punctuations
result = result.replace('+', ' ')
result = result.replace('..', ' ')
result = result.replace('.', ' ')
result = result.replace(',', ' ')
result = result.replace('\n', ' ') # get rid of new line
result = re.findall('[a-z\s]', result, flags=re.UNICODE) # only use text character (a-z) and space
result = "".join(result)
final = " ".join(result.split())

return final # clean text

# clean our data
data['cleaned_document'] = data.full_document.apply(lambda r: text_cleaning(r))
Contoh data setelah dibersihkan

Data sudah selesai diproses, mari lanjut dengan membuat model embedding.

Melatih Model Embedding

Refrensi [3]

Untuk membuat model embedding word2vec, saya menggunakan library Gensim. Google Colab secara default telah terinstal Gensim versi 3.6.0, namun karena ada beberapa fitur terbaru yang belum tersedia di versi tersebut, saya menginstal lagi Gensim versi 4.2.0.

!pip install --upgrade gensim==4.2.0

Oh ya, Gensim versi 4.2.0 ini saya pilih karena versi terbaru dari Gensim ada bug pada saat saya load ke Google Colab.

Data teks yang ada di kolom cleaned_document harus dipisah terlebih dahulu masing-masing katanya agar dapat diproses oleh Gensim. Gensim sendiri telah menyediakan fungsi tokenize untuk melakukan hal tersebut.

from gensim.utils import tokenize
data["tokenize_text"] = data.cleaned_document.apply(lambda x: list(tokenize(x)))

data.sample(n=5, random_state=20).iloc[:, -2:]
Data yang telah melewati proses tokenize

Data yang telah dipisah per-kata kini dapat digunakan untuk membuat model embedding. Model embedding dibuat menggunakan API Word2Vec yang disediakan oleh Gensim.

from gensim.models import Word2Vec

# define the model
model_wikihow = Word2Vec(
window=10,
min_count=5,
workers=4,
epochs=10,
)
model_wikihow.build_vocab(data.tokenize_text, progress_per=1000)

# train the model
model_wikihow.train(data.tokenize_text, total_examples=model_wikihow.corpus_count, epochs=model_wikihow.epochs)

model_wikihow_path = r'/content/drive/MyDrive/proyek_pribadi/NLP/model_file/word2vec-wikihow-indonesia-3.model'

# save the model
model_wikihow.save(model_wikihow_path)

# load the model
model_wikihow = Word2Vec.load(model_wikihow_path)

Proses pelatihan yang saya lakukan menggunakan CPU Google Colab membutuhkan waktu sekitar 5 menit. Model yang telah selesai dilatih sebaiknya disimpan terlebih dahulu dengan ekstensi .model sebelum digunakan.

Hal pertama yang saya uji dari model ini adalah melihat kemampuan model ini untuk mencarikan kata-kata yang memiliki kemiripan makna.

model_wikihow.wv.most_similar("pintar")
Kata-kata yang memiliki kemiripan makna dengan kata “pintar” menurut word2vec WikiHow

Terlihat bahwa word2vec menempatkan kata “cerdas” sebagai kata yang paling mirip dengan kata “pintar”.

Perlu diingat juga bahwa word2vec membangun vektor yang merepresentasikan tiap kata berdasarkan rangkaian urutan kemunculan tiap kata dalam teks.

Dengan demikian, kata-kata yang sering disebutkan secara bersamaan akan memiliki vektor yang hampir mirip. Oleh karena itulah kata-kata seperti “smartphone” dan “handphone” muncul sebagai kata yang mirip dengan kata “pintar”. Hal ini terjadi karena dalam bahasa Indonesia ada kata “smartphone pintar” atau “handphone pintar”.

Mari kita lihat lagi contoh lain.

model_wikihow.wv.most_similar("pria")
Kata-kata yang mirip dengan kata “pria”

Walaupun secara semantik “pria” berbeda dengan “wanita”, ada kesamaan lain yang dicerna oleh word2vec secara tidak langsung, yaitu dalam konteks jenis kelamin.

Catatan: Bukan berarti bahwa word2vec mengerti dengan jenis kelamin, wanita muncul memang karena sering disebut secara bersamaan dengan pria dalam data pelatihan.

Bahasa yang digunakan oleh manusia untuk berkomunikasi merupakan hal yang sangat kompleks. Ada banyak faktor dan konteks yang menentukan arti semantik dari sebuah kata.

Perlu diingat juga bahwa Word2Vec hanya mempelajari kata-kata yang ada dalam teks berdasarkan urutannya dan membuatkan vektor untuk masing-masing kata. Word2Vec bukanlah algoritma yang menjadi “mengerti suatu bahasa” seperti manusia

Sehingga cukup bisa dimengerti mengapa model Gensim di atas menganggap kata “pria” hampir mirip dengan “wanita”.

Sekarang mari kita coba salah satu operasi paling terkenal dari Word2Vec, yaitu:

Raja — Pria + Wanita = ?

Maksudnya adalah jika kita menghilangkan elemen “Pria” dari kata “Raja” dan menggantikannya dengan “Wanita”, apa kira-kira kata yang akan kita dapatkan?

model_wikihow.wv.most_similar(positive=['raja', 'wanita'], negative=['pria'], topn=1)
Model WikiHow menjawab “Ratu”

Visualiasi Kata-kata bahasa Indonesia

Tidak lengkap rasanya jika kita tidak mencoba untuk memvisualisasikan vektor dari kata-kata berbahasa Indonesisa dalam sebuah grafik.

Namun perlu diingat bahwa setiap kata yang kita berikan ke model Wikihow akan dibuatkan vektor berukuran (n=100). Agar vektor-vektor tersebut dapat divisualisasikan dalam grafik 2 dimensi, vektor tersebut harus direduksi menjadi 2 dimensi.

Dalam Machine Learning, teknik mereduksi ukuran vektor yang cukup populer adalah Principal Component Analysis (PCA).

Adapun kata-kata yang akan saya visualisasikan adalah sebagai berikut:

words = ['cabai', 'terong', 'pedas', 'manis', 'asin', 'apel', 'pisang', 'anggur', 
'pesawat', 'mobil', 'mesin', 'motor', 'harimau', 'singa', 'kucing',
'jerapah', 'zebra', 'rumah', 'gedung', 'cantik', 'ganteng', 'gajah',
'kelinci', 'anjing', 'sapi', 'kerbau', 'bawang', 'kunyit', 'merica']

Untuk semua kata yang akan dijadikan vektor menggunakan model Wikihow harus:

  • Terdiri dari satu kata
  • Tanda tanda baca
  • Menggunakan huruf kecil

Kog harus gitu???

Karena model Wikihow saya latih dengan data yang mengikuti ketiga aturan itu, jika diberikan kata-kata yang tidak mengikuti aturan di atas atau tidak ada dalam vocabulary model Wikihow, maka akan ada error.

# Store the words vector in list
word_vector = []

for word in words:
word_vector.append(model_wikihow.wv.get_vector(word))

Setiap kata-kata di list words diubah dalam vektor menggunakan model Wikihow.

Contoh vektor yang dihasilkan

Vektor dengan ukuran n=100 tersebut akan ditransformasikan menjadi vektor n=2 menggunakan API PCA dari library Scikit Learn.

from sklearn.decomposition import PCA

# transforming words vector
pca = PCA(n_components=2)
result = pca.fit_transform(word_vector)
Hasil Principal Component Analysis

Vektor dari tiap kata-kata sudah sesuai dengan ketentuan, kita dapat menggunakan scatter plot untuk melihat distribusi dari tiap kata. Saya menggunakan library plotly untuk membuat grafik berikut.

import plotly.express as px

# Create the scatter plot
fig = px.scatter(x=result[:, 0], y=result[:, 1])

# Annotate each data point
for i, txt in enumerate(words):
fig.add_annotation(
x=result[i, 0],
y=result[i, 1],
text=txt,
xref="x",
yref="y",
showarrow=True,
arrowhead=7,
ax=20,
ay=-30
)

# adjust graph size
fig.update_layout(
height=1200,
width=1200,
title='Visualisasi Kata-kata Indonesia'
)

# Show the plot
fig.show()
Plot hubungan kata-kata bahasa Indonesia (menurut model Wikihow)

Dari gambar di atas dapat dilihat bahwa performa model Wikihow dalam mengelompokkan kata-kata Indonesia cukup baik.

Di kanan bawah terlihat ada kelompok alat transportasi dan benda mati lainnya. Di kanan atas, hewan seperti kelinci, kucing dan anjing menempati gugus yang sama, hal ini mungkin terjadi karena hubungan ketiga hewan tersebut sebagai hewan peliharaan.

Di tengah kita dapat melihat gugus yang terdiri dari hewan liar seperti harimau, singa, gajah dan lainnya. Ada juga gugus yang terdiri dari bumbu dapur, buah dan rasa.

Namun kata “cantik” dan “ganteng” tidak menempati gugus yang cukup intuitif, hal ini menunjukkan bahwa model Wikihow masih memiliki kelemahan dalam merepresentasikan kata sifat.

Oke, sampai disini proses saya mengulik performa model Wikihow.

Proses membuat model word embedding bahasa Indonesia dengan data WikiHow telah selesai dilakukan. Model embedding ini dapat digunakan untuk memproses teks dalam proyek-proyek NLP seperti analisis sentimen, chatbot dan lainnya.

Terima kasih.

--

--