AI-For-Beginners/translations/id/lessons/5-NLP/13-TextRep/TextRepresentationTF.ipynb

647 lines
26 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Tugas klasifikasi teks\n",
"\n",
"Dalam modul ini, kita akan memulai dengan tugas klasifikasi teks sederhana berdasarkan dataset **[AG_NEWS](http://www.di.unipi.it/~gulli/AG_corpus_of_news_articles.html)**: kita akan mengklasifikasikan judul berita ke dalam salah satu dari 4 kategori: Dunia, Olahraga, Bisnis, dan Sains/Teknologi.\n",
"\n",
"## Dataset\n",
"\n",
"Untuk memuat dataset, kita akan menggunakan API **[TensorFlow Datasets](https://www.tensorflow.org/datasets)**.\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"from tensorflow import keras\n",
"import tensorflow_datasets as tfds\n",
"\n",
"# In this tutorial, we will be training a lot of models. In order to use GPU memory cautiously,\n",
"# we will set tensorflow option to grow GPU memory allocation when required.\n",
"physical_devices = tf.config.list_physical_devices('GPU') \n",
"if len(physical_devices)>0:\n",
" tf.config.experimental.set_memory_growth(physical_devices[0], True)\n",
"\n",
"dataset = tfds.load('ag_news_subset')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Kita sekarang dapat mengakses bagian pelatihan dan pengujian dari dataset dengan menggunakan `dataset['train']` dan `dataset['test']` masing-masing:\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Length of train dataset = 120000\n",
"Length of test dataset = 7600\n"
]
}
],
"source": [
"ds_train = dataset['train']\n",
"ds_test = dataset['test']\n",
"\n",
"print(f\"Length of train dataset = {len(ds_train)}\")\n",
"print(f\"Length of test dataset = {len(ds_test)}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Mari cetak 10 berita utama baru pertama dari dataset kita:\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3 (Sci/Tech) -> b'AMD Debuts Dual-Core Opteron Processor' b'AMD #39;s new dual-core Opteron chip is designed mainly for corporate computing applications, including databases, Web services, and financial transactions.'\n",
"1 (Sports) -> b\"Wood's Suspension Upheld (Reuters)\" b'Reuters - Major League Baseball\\\\Monday announced a decision on the appeal filed by Chicago Cubs\\\\pitcher Kerry Wood regarding a suspension stemming from an\\\\incident earlier this season.'\n",
"2 (Business) -> b'Bush reform may have blue states seeing red' b'President Bush #39;s quot;revenue-neutral quot; tax reform needs losers to balance its winners, and people claiming the federal deduction for state and local taxes may be in administration planners #39; sights, news reports say.'\n",
"3 (Sci/Tech) -> b\"'Halt science decline in schools'\" b'Britain will run out of leading scientists unless science education is improved, says Professor Colin Pillinger.'\n",
"1 (Sports) -> b'Gerrard leaves practice' b'London, England (Sports Network) - England midfielder Steven Gerrard injured his groin late in Thursday #39;s training session, but is hopeful he will be ready for Saturday #39;s World Cup qualifier against Austria.'\n"
]
}
],
"source": [
"classes = ['World', 'Sports', 'Business', 'Sci/Tech']\n",
"\n",
"for i,x in zip(range(5),ds_train):\n",
" print(f\"{x['label']} ({classes[x['label']]}) -> {x['title']} {x['description']}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Vektorisasi Teks\n",
"\n",
"Sekarang kita perlu mengubah teks menjadi **angka** yang dapat direpresentasikan sebagai tensor. Jika kita ingin representasi pada tingkat kata, kita perlu melakukan dua hal:\n",
"\n",
"* Menggunakan **tokenizer** untuk membagi teks menjadi **token**.\n",
"* Membuat **kosakata** dari token-token tersebut.\n",
"\n",
"### Membatasi Ukuran Kosakata\n",
"\n",
"Dalam contoh dataset AG News, ukuran kosakata cukup besar, lebih dari 100 ribu kata. Secara umum, kita tidak memerlukan kata-kata yang jarang muncul dalam teks — hanya beberapa kalimat yang akan memilikinya, dan model tidak akan belajar dari kata-kata tersebut. Oleh karena itu, masuk akal untuk membatasi ukuran kosakata ke angka yang lebih kecil dengan memberikan argumen pada konstruktor vektorisasi:\n",
"\n",
"Kedua langkah tersebut dapat ditangani menggunakan lapisan **TextVectorization**. Mari kita buat objek vektorisasi, lalu panggil metode `adapt` untuk memproses semua teks dan membangun kosakata:\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"vocab_size = 50000\n",
"vectorizer = keras.layers.experimental.preprocessing.TextVectorization(max_tokens=vocab_size)\n",
"vectorizer.adapt(ds_train.take(500).map(lambda x: x['title']+' '+x['description']))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Catatan** bahwa kami hanya menggunakan sebagian kecil dari keseluruhan dataset untuk membangun kosakata. Kami melakukannya untuk mempercepat waktu eksekusi dan agar Anda tidak perlu menunggu terlalu lama. Namun, kami mengambil risiko bahwa beberapa kata dari keseluruhan dataset tidak akan dimasukkan ke dalam kosakata, dan akan diabaikan selama pelatihan. Oleh karena itu, menggunakan ukuran kosakata penuh dan menjalankan seluruh dataset selama `adapt` seharusnya dapat meningkatkan akurasi akhir, meskipun tidak secara signifikan.\n",
"\n",
"Sekarang kita dapat mengakses kosakata yang sebenarnya:\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['', '[UNK]', 'the', 'to', 'a', 'in', 'of', 'and', 'on', 'for']\n",
"Length of vocabulary: 5335\n"
]
}
],
"source": [
"vocab = vectorizer.get_vocabulary()\n",
"vocab_size = len(vocab)\n",
"print(vocab[:10])\n",
"print(f\"Length of vocabulary: {vocab_size}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Dengan menggunakan vectorizer, kita dapat dengan mudah mengkodekan teks apa pun ke dalam serangkaian angka:\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<tf.Tensor: shape=(7,), dtype=int64, numpy=array([ 112, 3695, 3, 304, 11, 1041, 1], dtype=int64)>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"vectorizer('I love to play with my words')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Representasi teks Bag-of-words\n",
"\n",
"Karena kata-kata mewakili makna, terkadang kita dapat memahami arti dari sebuah teks hanya dengan melihat kata-kata individualnya, tanpa memperhatikan urutannya dalam kalimat. Sebagai contoh, saat mengklasifikasikan berita, kata-kata seperti *cuaca* dan *salju* kemungkinan besar menunjukkan *ramalan cuaca*, sementara kata-kata seperti *saham* dan *dolar* akan mengarah pada *berita keuangan*.\n",
"\n",
"Representasi vektor **Bag-of-words** (BoW) adalah representasi vektor tradisional yang paling sederhana untuk dipahami. Setiap kata dikaitkan dengan indeks vektor, dan elemen vektor berisi jumlah kemunculan setiap kata dalam dokumen tertentu.\n",
"\n",
"![Gambar yang menunjukkan bagaimana representasi vektor bag-of-words disimpan dalam memori.](../../../../../translated_images/id/bag-of-words-example.606fc1738f1d7ba9.webp) \n",
"\n",
"> **Note**: Anda juga dapat memikirkan BoW sebagai jumlah dari semua vektor one-hot-encoded untuk setiap kata dalam teks.\n",
"\n",
"Di bawah ini adalah contoh cara menghasilkan representasi bag-of-words menggunakan pustaka python Scikit Learn:\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1, 1, 0, 2, 0, 0, 0, 0, 0]], dtype=int64)"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.feature_extraction.text import CountVectorizer\n",
"sc_vectorizer = CountVectorizer()\n",
"corpus = [\n",
" 'I like hot dogs.',\n",
" 'The dog ran fast.',\n",
" 'Its hot outside.',\n",
" ]\n",
"sc_vectorizer.fit_transform(corpus)\n",
"sc_vectorizer.transform(['My dog likes hot dogs on a hot day.']).toarray()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Kita juga dapat menggunakan vektorisasi Keras yang telah kita definisikan di atas, mengonversi setiap nomor kata menjadi one-hot encoding dan menjumlahkan semua vektor tersebut:\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0., 5., 0., ..., 0., 0., 0.], dtype=float32)"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def to_bow(text):\n",
" return tf.reduce_sum(tf.one_hot(vectorizer(text),vocab_size),axis=0)\n",
"\n",
"to_bow('My dog likes hot dogs on a hot day.').numpy()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Catatan**: Anda mungkin terkejut bahwa hasilnya berbeda dari contoh sebelumnya. Alasannya adalah dalam contoh Keras, panjang vektor sesuai dengan ukuran kosakata, yang dibangun dari seluruh dataset AG News, sementara dalam contoh Scikit Learn, kami membangun kosakata dari teks sampel secara langsung.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Melatih Klasifikasi BoW\n",
"\n",
"Sekarang setelah kita mempelajari cara membangun representasi bag-of-words dari teks kita, mari kita latih sebuah klasifikasi yang menggunakannya. Pertama, kita perlu mengubah dataset kita menjadi representasi bag-of-words. Hal ini dapat dilakukan dengan menggunakan fungsi `map` seperti berikut:\n"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"batch_size = 128\n",
"\n",
"ds_train_bow = ds_train.map(lambda x: (to_bow(x['title']+x['description']),x['label'])).batch(batch_size)\n",
"ds_test_bow = ds_test.map(lambda x: (to_bow(x['title']+x['description']),x['label'])).batch(batch_size)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sekarang mari kita definisikan jaringan neural classifier sederhana yang mengandung satu lapisan linear. Ukuran input adalah `vocab_size`, dan ukuran output sesuai dengan jumlah kelas (4). Karena kita sedang menyelesaikan tugas klasifikasi, fungsi aktivasi akhirnya adalah **softmax**:\n"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"938/938 [==============================] - 66s 70ms/step - loss: 0.6144 - acc: 0.8427 - val_loss: 0.4416 - val_acc: 0.8697\n"
]
},
{
"data": {
"text/plain": [
"<keras.callbacks.History at 0x20c70a947f0>"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model = keras.models.Sequential([\n",
" keras.layers.Dense(4,activation='softmax',input_shape=(vocab_size,))\n",
"])\n",
"model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])\n",
"model.fit(ds_train_bow,validation_data=ds_test_bow)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Karena kita memiliki 4 kelas, akurasi di atas 80% adalah hasil yang baik.\n",
"\n",
"## Melatih sebuah classifier sebagai satu jaringan\n",
"\n",
"Karena vectorizer juga merupakan lapisan Keras, kita dapat mendefinisikan sebuah jaringan yang menyertakannya, dan melatihnya secara end-to-end. Dengan cara ini, kita tidak perlu memvektorisasi dataset menggunakan `map`, kita cukup memberikan dataset asli ke input jaringan.\n",
"\n",
"> **Note**: Kita tetap harus menerapkan map pada dataset kita untuk mengubah bidang dari dictionary (seperti `title`, `description`, dan `label`) menjadi tuple. Namun, saat memuat data dari disk, kita dapat membangun dataset dengan struktur yang diperlukan sejak awal.\n"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"model\"\n",
"_________________________________________________________________\n",
" Layer (type) Output Shape Param # \n",
"=================================================================\n",
" input_1 (InputLayer) [(None, 1)] 0 \n",
" \n",
" text_vectorization (TextVec (None, None) 0 \n",
" torization) \n",
" \n",
" tf.one_hot (TFOpLambda) (None, None, 5335) 0 \n",
" \n",
" tf.math.reduce_sum (TFOpLam (None, 5335) 0 \n",
" bda) \n",
" \n",
" dense_2 (Dense) (None, 4) 21344 \n",
" \n",
"=================================================================\n",
"Total params: 21,344\n",
"Trainable params: 21,344\n",
"Non-trainable params: 0\n",
"_________________________________________________________________\n",
"938/938 [==============================] - 73s 77ms/step - loss: 0.6057 - acc: 0.8414 - val_loss: 0.4202 - val_acc: 0.8736\n"
]
},
{
"data": {
"text/plain": [
"<keras.callbacks.History at 0x20c721521f0>"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def extract_text(x):\n",
" return x['title']+' '+x['description']\n",
"\n",
"def tupelize(x):\n",
" return (extract_text(x),x['label'])\n",
"\n",
"inp = keras.Input(shape=(1,),dtype=tf.string)\n",
"x = vectorizer(inp)\n",
"x = tf.reduce_sum(tf.one_hot(x,vocab_size),axis=1)\n",
"out = keras.layers.Dense(4,activation='softmax')(x)\n",
"model = keras.models.Model(inp,out)\n",
"model.summary()\n",
"\n",
"model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])\n",
"model.fit(ds_train.map(tupelize).batch(batch_size),validation_data=ds_test.map(tupelize).batch(batch_size))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Bigram, Trigram, dan N-gram\n",
"\n",
"Salah satu keterbatasan pendekatan bag-of-words adalah bahwa beberapa kata merupakan bagian dari ekspresi multi-kata. Sebagai contoh, kata 'hot dog' memiliki arti yang sepenuhnya berbeda dibandingkan dengan kata 'hot' dan 'dog' dalam konteks lain. Jika kita selalu merepresentasikan kata 'hot' dan 'dog' menggunakan vektor yang sama, hal ini dapat membingungkan model kita.\n",
"\n",
"Untuk mengatasi masalah ini, **representasi n-gram** sering digunakan dalam metode klasifikasi dokumen, di mana frekuensi setiap kata, pasangan kata, atau tiga kata menjadi fitur yang berguna untuk melatih classifier. Dalam representasi bigram, misalnya, kita akan menambahkan semua pasangan kata ke dalam kosakata, selain kata-kata asli.\n",
"\n",
"Di bawah ini adalah contoh cara menghasilkan representasi bigram bag-of-words menggunakan Scikit Learn:\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Vocabulary:\n",
" {'i': 7, 'like': 11, 'hot': 4, 'dogs': 2, 'i like': 8, 'like hot': 12, 'hot dogs': 5, 'the': 16, 'dog': 0, 'ran': 14, 'fast': 3, 'the dog': 17, 'dog ran': 1, 'ran fast': 15, 'its': 9, 'outside': 13, 'its hot': 10, 'hot outside': 6}\n"
]
},
{
"data": {
"text/plain": [
"array([[1, 0, 1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],\n",
" dtype=int64)"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bigram_vectorizer = CountVectorizer(ngram_range=(1, 2), token_pattern=r'\\b\\w+\\b', min_df=1)\n",
"corpus = [\n",
" 'I like hot dogs.',\n",
" 'The dog ran fast.',\n",
" 'Its hot outside.',\n",
" ]\n",
"bigram_vectorizer.fit_transform(corpus)\n",
"print(\"Vocabulary:\\n\",bigram_vectorizer.vocabulary_)\n",
"bigram_vectorizer.transform(['My dog likes hot dogs on a hot day.']).toarray()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Kelemahan utama pendekatan n-gram adalah ukuran kosakata mulai tumbuh dengan sangat cepat. Dalam praktiknya, kita perlu menggabungkan representasi n-gram dengan teknik reduksi dimensi, seperti *embeddings*, yang akan kita bahas di unit berikutnya.\n",
"\n",
"Untuk menggunakan representasi n-gram dalam dataset **AG News** kita, kita perlu meneruskan parameter `ngrams` ke konstruktor `TextVectorization` kita. Panjang kosakata bigram **jauh lebih besar**, dalam kasus kita lebih dari 1,3 juta token! Oleh karena itu, masuk akal untuk membatasi token bigram dengan jumlah yang wajar.\n",
"\n",
"Kita bisa menggunakan kode yang sama seperti di atas untuk melatih classifier, namun, itu akan sangat tidak efisien dalam penggunaan memori. Di unit berikutnya, kita akan melatih classifier bigram menggunakan embeddings. Sementara itu, Anda dapat bereksperimen dengan pelatihan classifier bigram di notebook ini dan melihat apakah Anda bisa mendapatkan akurasi yang lebih tinggi.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Menghitung Vektor BoW Secara Otomatis\n",
"\n",
"Dalam contoh di atas, kita menghitung vektor BoW secara manual dengan menjumlahkan one-hot encoding dari masing-masing kata. Namun, versi terbaru TensorFlow memungkinkan kita untuk menghitung vektor BoW secara otomatis dengan memberikan parameter `output_mode='count'` ke konstruktor vectorizer. Hal ini membuat proses mendefinisikan dan melatih model kita menjadi jauh lebih mudah:\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training vectorizer\n",
"938/938 [==============================] - 7s 7ms/step - loss: 0.5929 - acc: 0.8486 - val_loss: 0.4168 - val_acc: 0.8772\n"
]
},
{
"data": {
"text/plain": [
"<keras.callbacks.History at 0x20c725217c0>"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model = keras.models.Sequential([\n",
" keras.layers.experimental.preprocessing.TextVectorization(max_tokens=vocab_size,output_mode='count'),\n",
" keras.layers.Dense(4,input_shape=(vocab_size,), activation='softmax')\n",
"])\n",
"print(\"Training vectorizer\")\n",
"model.layers[0].adapt(ds_train.take(500).map(extract_text))\n",
"model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])\n",
"model.fit(ds_train.map(tupelize).batch(batch_size),validation_data=ds_test.map(tupelize).batch(batch_size))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Frekuensi istilah - frekuensi dokumen terbalik (TF-IDF)\n",
"\n",
"Dalam representasi BoW, kemunculan kata diberi bobot menggunakan teknik yang sama tanpa memandang kata itu sendiri. Namun, jelas bahwa kata-kata yang sering muncul seperti *a* dan *in* jauh kurang penting untuk klasifikasi dibandingkan istilah-istilah khusus. Dalam sebagian besar tugas NLP, beberapa kata lebih relevan daripada yang lain.\n",
"\n",
"**TF-IDF** adalah singkatan dari **term frequency - inverse document frequency**. Ini adalah variasi dari bag-of-words, di mana alih-alih menggunakan nilai biner 0/1 untuk menunjukkan kemunculan kata dalam sebuah dokumen, digunakan nilai floating-point yang berkaitan dengan frekuensi kemunculan kata dalam korpus.\n",
"\n",
"Secara formal, bobot $w_{ij}$ dari sebuah kata $i$ dalam dokumen $j$ didefinisikan sebagai:\n",
"$$\n",
"w_{ij} = tf_{ij}\\times\\log({N\\over df_i})\n",
"$$\n",
"di mana\n",
"* $tf_{ij}$ adalah jumlah kemunculan $i$ dalam $j$, yaitu nilai BoW yang telah kita lihat sebelumnya\n",
"* $N$ adalah jumlah dokumen dalam koleksi\n",
"* $df_i$ adalah jumlah dokumen yang mengandung kata $i$ dalam seluruh koleksi\n",
"\n",
"Nilai TF-IDF $w_{ij}$ meningkat secara proporsional dengan jumlah kemunculan kata dalam sebuah dokumen dan disesuaikan dengan jumlah dokumen dalam korpus yang mengandung kata tersebut, yang membantu mengoreksi fakta bahwa beberapa kata muncul lebih sering daripada yang lain. Sebagai contoh, jika sebuah kata muncul di *setiap* dokumen dalam koleksi, $df_i=N$, dan $w_{ij}=0$, maka istilah-istilah tersebut akan sepenuhnya diabaikan.\n",
"\n",
"Anda dapat dengan mudah membuat vektorisasi TF-IDF dari teks menggunakan Scikit Learn:\n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0.43381609, 0. , 0.43381609, 0. , 0.65985664,\n",
" 0.43381609, 0. , 0. , 0. , 0. ,\n",
" 0. , 0. , 0. , 0. , 0. ,\n",
" 0. ]])"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.feature_extraction.text import TfidfVectorizer\n",
"vectorizer = TfidfVectorizer(ngram_range=(1,2))\n",
"vectorizer.fit_transform(corpus)\n",
"vectorizer.transform(['My dog likes hot dogs on a hot day.']).toarray()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Dalam Keras, lapisan `TextVectorization` dapat secara otomatis menghitung frekuensi TF-IDF dengan melewatkan parameter `output_mode='tf-idf'`. Mari ulangi kode yang kita gunakan di atas untuk melihat apakah menggunakan TF-IDF meningkatkan akurasi:\n"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training vectorizer\n",
"938/938 [==============================] - 12s 12ms/step - loss: 0.4197 - acc: 0.8662 - val_loss: 0.3432 - val_acc: 0.8849\n"
]
},
{
"data": {
"text/plain": [
"<keras.callbacks.History at 0x20c729dfd30>"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model = keras.models.Sequential([\n",
" keras.layers.experimental.preprocessing.TextVectorization(max_tokens=vocab_size,output_mode='tf-idf'),\n",
" keras.layers.Dense(4,input_shape=(vocab_size,), activation='softmax')\n",
"])\n",
"print(\"Training vectorizer\")\n",
"model.layers[0].adapt(ds_train.take(500).map(extract_text))\n",
"model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])\n",
"model.fit(ds_train.map(tupelize).batch(batch_size),validation_data=ds_test.map(tupelize).batch(batch_size))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Kesimpulan\n",
"\n",
"Meskipun representasi TF-IDF memberikan bobot frekuensi pada kata-kata yang berbeda, mereka tidak mampu merepresentasikan makna atau urutan. Seperti yang dikatakan oleh ahli linguistik terkenal J. R. Firth pada tahun 1935, \"Makna lengkap dari sebuah kata selalu bersifat kontekstual, dan tidak ada studi tentang makna yang terlepas dari konteks yang dapat dianggap serius.\" Kita akan mempelajari cara menangkap informasi kontekstual dari teks menggunakan pemodelan bahasa di bagian selanjutnya dari kursus ini.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Penafian**: \nDokumen ini telah diterjemahkan menggunakan layanan penerjemahan AI [Co-op Translator](https://github.com/Azure/co-op-translator). Meskipun kami berusaha untuk memberikan hasil yang akurat, harap diperhatikan bahwa terjemahan otomatis mungkin mengandung kesalahan atau ketidakakuratan. Dokumen asli dalam bahasa aslinya harus dianggap sebagai sumber yang otoritatif. Untuk informasi yang bersifat kritis, disarankan menggunakan jasa penerjemahan profesional oleh manusia. Kami tidak bertanggung jawab atas kesalahpahaman atau penafsiran yang keliru yang timbul dari penggunaan terjemahan ini.\n"
]
}
],
"metadata": {
"interpreter": {
"hash": "0cb620c6d4b9f7a635928804c26cf22403d89d98d79684e4529119355ee6d5a5"
},
"kernel_info": {
"name": "conda-env-py37_tensorflow-py"
},
"kernelspec": {
"display_name": "py37_tensorflow",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.12"
},
"nteract": {
"version": "nteract-front-end@1.0.0"
},
"coopTranslator": {
"original_hash": "19b43951d55b377a76209c24c1f017e4",
"translation_date": "2025-08-29T16:42:58+00:00",
"source_file": "lessons/5-NLP/13-TextRep/TextRepresentationTF.ipynb",
"language_code": "id"
}
},
"nbformat": 4,
"nbformat_minor": 4
}