diff --git a/answer_padded.npy b/answer_padded.npy deleted file mode 100644 index 58cbb3c..0000000 Binary files a/answer_padded.npy and /dev/null differ diff --git a/broken_dataset.txt b/broken_dataset.txt deleted file mode 100644 index c1a6c52..0000000 --- a/broken_dataset.txt +++ /dev/null @@ -1 +0,0 @@ -Katak mengalami metamorfosis dari telur, berudu, katak muda, hingga katak dewasa.,multiple_choice,Tahapan apakah yang termasuk dalam metamorfosis katak?,Berudu,Telur|Berudu|Pupa|Imago \ No newline at end of file diff --git a/context_padded.npy b/context_padded.npy deleted file mode 100644 index 316842c..0000000 Binary files a/context_padded.npy and /dev/null differ diff --git a/dataset/training_dataset.json b/dataset/training_dataset.json index b0e5b2a..a1a9a90 100644 --- a/dataset/training_dataset.json +++ b/dataset/training_dataset.json @@ -1,7 +1,7 @@ [ { "context": "Albert Einstein adalah fisikawan teoretis kelahiran Jerman yang mengembangkan teori relativitas, salah satu dari dua pilar fisika modern. Karyanya juga dikenal karena pengaruhnya terhadap filosofi ilmu pengetahuan. Ia menerima Penghargaan Nobel dalam Fisika pada tahun 1921 atas jasanya dalam fisika teoretis.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Siapa yang mengembangkan teori relativitas?", @@ -22,7 +22,7 @@ }, { "context": "Samudra Pasifik adalah yang terbesar dan terdalam di antara divisi samudra di Bumi. Samudra ini membentang dari Samudra Arktik di utara hingga Samudra Selatan di selatan dan berbatasan dengan Asia dan Australia di barat serta Amerika di timur.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Samudra _______ adalah yang terbesar dan terdalam.", @@ -43,7 +43,7 @@ }, { "context": "Proklamasi Kemerdekaan Indonesia dibacakan pada tanggal 17 Agustus 1945 oleh Soekarno dan Mohammad Hatta di Jakarta. Peristiwa ini menandai lahirnya negara Indonesia yang merdeka dari penjajahan.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Proklamasi Kemerdekaan Indonesia terjadi pada tanggal _______.", @@ -69,7 +69,7 @@ }, { "context": "Hukum Newton adalah tiga hukum fisika yang menjadi dasar mekanika klasik. Hukum pertama menyatakan bahwa suatu benda akan tetap diam atau bergerak lurus beraturan kecuali ada gaya luar yang bekerja padanya. Hukum kedua menyatakan bahwa percepatan suatu benda berbanding lurus dengan gaya yang bekerja padanya dan berbanding terbalik dengan massanya. Hukum ketiga menyatakan bahwa setiap aksi memiliki reaksi yang sama besar tetapi berlawanan arah.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Hukum Newton terdiri dari _______ hukum.", @@ -95,7 +95,7 @@ }, { "context": "Budi Utomo adalah organisasi pemuda yang didirikan pada 20 Mei 1908 oleh dr. Wahidin Sudirohusodo dan para mahasiswa STOVIA. Organisasi ini bertujuan untuk meningkatkan pendidikan dan kesejahteraan rakyat Indonesia serta menjadi tonggak awal kebangkitan nasional.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Budi Utomo didirikan pada tanggal _______.", @@ -121,7 +121,7 @@ }, { "context": "Ki Hajar Dewantara adalah pelopor pendidikan di Indonesia dan pendiri Taman Siswa. Ia dikenal dengan semboyannya 'Ing Ngarsa Sung Tuladha, Ing Madya Mangun Karsa, Tut Wuri Handayani', yang menekankan peran guru dalam pendidikan.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Ki Hajar Dewantara mendirikan _______.", @@ -147,7 +147,7 @@ }, { "context": "Teori evolusi dikembangkan oleh Charles Darwin dan dijelaskan dalam bukunya 'On the Origin of Species' yang diterbitkan pada tahun 1859. Teori ini menyatakan bahwa spesies berevolusi melalui seleksi alam, di mana individu dengan karakteristik yang lebih baik memiliki peluang lebih tinggi untuk bertahan hidup dan berkembang biak.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Teori evolusi dikembangkan oleh?", @@ -173,7 +173,7 @@ }, { "context": "BPUPKI (Badan Penyelidik Usaha-Usaha Persiapan Kemerdekaan Indonesia) dibentuk oleh pemerintah Jepang pada 29 April 1945 sebagai bagian dari janji Jepang untuk memberikan kemerdekaan kepada Indonesia. Pembentukan BPUPKI terjadi pada masa Perang Dunia II, ketika Jepang mulai mengalami kekalahan dari Sekutu dan ingin mendapatkan dukungan dari rakyat Indonesia.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Apa kepanjangan dari BPUPKI?", @@ -194,7 +194,7 @@ }, { "context": "Kerajaan Majapahit adalah kerajaan besar Hindu-Buddha yang berpusat di Jawa Timur, berdiri sekitar tahun 1293 hingga 1500 M. Majapahit mencapai puncak kejayaan di bawah pemerintahan Raja Hayam Wuruk dengan patihnya, Gajah Mada.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Kerajaan Majapahit mencapai puncak kejayaannya di bawah raja _______.", @@ -215,7 +215,7 @@ }, { "context": "Kerajaan Sriwijaya adalah kerajaan maritim yang berpusat di Sumatera Selatan dari abad ke-7 hingga abad ke-13. Kerajaan ini menjadi pusat perdagangan dan penyebaran agama Buddha terbesar di Asia Tenggara.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Kerajaan Sriwijaya adalah pusat penyebaran agama _______ terbesar di Asia Tenggara.", @@ -236,7 +236,7 @@ }, { "context": "Candi Borobudur adalah candi Buddha terbesar di dunia yang terletak di Magelang, Jawa Tengah. Dibangun pada abad ke-8 oleh Wangsa Sailendra, candi ini merupakan simbol puncak kebudayaan Buddha di Jawa.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Candi Borobudur dibangun oleh wangsa _______.", @@ -257,7 +257,7 @@ }, { "context": "VOC (Vereenigde Oostindische Compagnie) adalah perusahaan dagang Belanda yang memonopoli perdagangan rempah-rempah di Nusantara dari abad ke-17 hingga awal abad ke-18.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "VOC adalah singkatan dari _______.", @@ -278,7 +278,7 @@ }, { "context": "Pertempuran Surabaya terjadi pada 10 November 1945 antara pasukan Indonesia melawan pasukan sekutu Inggris yang berusaha mengambil alih kota setelah Jepang menyerah dalam Perang Dunia II. Pertempuran ini dikenang sebagai Hari Pahlawan di Indonesia.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Pertempuran Surabaya terjadi pada tanggal _______.", @@ -299,7 +299,7 @@ }, { "context": "Kerajaan Demak adalah kerajaan Islam pertama di Jawa yang berdiri pada akhir abad ke-15. Kerajaan ini terkenal karena penyebaran agama Islam di Jawa melalui Wali Songo.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Kerajaan Demak adalah kerajaan Islam pertama di Jawa.", @@ -314,7 +314,7 @@ }, { "context": "Sumpah Pemuda terjadi pada 28 Oktober 1928, di mana pemuda Indonesia berikrar untuk bersatu dalam satu tanah air, satu bangsa, dan satu bahasa Indonesia.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Sumpah Pemuda menyatakan persatuan dalam satu agama.", @@ -329,7 +329,7 @@ }, { "context": "Gajah Mada adalah seorang patih terkenal dari Kerajaan Majapahit yang berhasil menyatukan sebagian besar wilayah Nusantara melalui politik ekspansinya. Ia terkenal dengan sumpahnya yang disebut Sumpah Palapa.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Gajah Mada berasal dari Kerajaan Majapahit.", @@ -344,7 +344,7 @@ }, { "context": "Kerajaan Aceh mencapai puncak kejayaannya di bawah pemerintahan Sultan Iskandar Muda pada abad ke-17. Aceh menjadi pusat perdagangan dan kebudayaan Islam di wilayah Nusantara.", - "qa_pairs": [ + "question_posibility": [ { "type": "multiple_choice", "question": "Siapakah sultan yang membawa Kerajaan Aceh ke puncak kejayaan?", @@ -360,7 +360,7 @@ }, { "context": "Perang Diponegoro berlangsung dari tahun 1825 hingga 1830. Perang ini dipimpin oleh Pangeran Diponegoro melawan pemerintah kolonial Belanda di Jawa Tengah.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Perang Diponegoro berlangsung selama lima tahun.", @@ -375,7 +375,7 @@ }, { "context": "Candi Prambanan adalah candi Hindu terbesar di Indonesia yang terletak di perbatasan antara Yogyakarta dan Jawa Tengah. Dibangun pada abad ke-9, candi ini merupakan peninggalan Kerajaan Mataram Kuno.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Candi Prambanan dibangun pada abad ke-_______.", @@ -385,7 +385,7 @@ }, { "context": "Pangeran Antasari adalah pahlawan nasional Indonesia yang memimpin perlawanan rakyat Kalimantan Selatan terhadap penjajahan Belanda pada abad ke-19.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Pangeran Antasari berasal dari Kalimantan Selatan.", @@ -401,7 +401,7 @@ }, { "context": "Perjanjian Linggarjati adalah perjanjian yang ditandatangani pada 25 Maret 1947 antara Indonesia dengan Belanda. Perjanjian ini mengakui secara de facto Republik Indonesia yang mencakup Jawa, Sumatra, dan Madura.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Perjanjian Linggarjati ditandatangani pada tahun 1947.", @@ -411,7 +411,7 @@ }, { "context": "Raden Adjeng Kartini adalah tokoh emansipasi wanita Indonesia yang lahir pada 21 April 1879. Ia dikenal melalui surat-suratnya yang memperjuangkan hak perempuan untuk memperoleh pendidikan dan kesetaraan.", - "qa_pairs": [ + "question_posibility": [ { "type": "multiple_choice", "question": "Tanggal berapa diperingati sebagai Hari Kartini di Indonesia?", @@ -422,7 +422,7 @@ }, { "context": "Kerajaan Kutai merupakan kerajaan Hindu tertua di Indonesia yang berdiri sekitar abad ke-4 di Kalimantan Timur. Bukti keberadaan kerajaan ini ditemukan dalam prasasti Yupa.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Kerajaan Kutai adalah kerajaan Hindu tertua di Indonesia yang ditemukan melalui prasasti _______.", @@ -437,7 +437,7 @@ }, { "context": "Raden Ajeng Kartini merupakan tokoh penting dalam sejarah perjuangan emansipasi wanita Indonesia. Ia lahir di Jepara dan dikenal melalui bukunya berjudul 'Habis Gelap Terbitlah Terang'.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Kartini dikenal sebagai pejuang emansipasi wanita.", @@ -447,7 +447,7 @@ }, { "context": "Ekspedisi Palembang dilakukan oleh VOC pada tahun 1659 untuk menguasai perdagangan lada di Sumatera Selatan. Ekspedisi ini berakhir dengan kemenangan VOC dan penegakan monopoli lada di daerah tersebut.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Ekspedisi Palembang terjadi pada tahun _______.", @@ -462,7 +462,7 @@ }, { "context": "Fotosintesis adalah proses pembuatan makanan oleh tumbuhan hijau menggunakan cahaya matahari, air, dan karbon dioksida yang menghasilkan oksigen sebagai produk sampingan.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Fotosintesis terjadi pada siang hari.", @@ -477,7 +477,7 @@ }, { "context": "Sel adalah unit terkecil kehidupan. Sel memiliki berbagai komponen, seperti membran sel, sitoplasma, dan inti sel (nukleus).", - "qa_pairs": [ + "question_posibility": [ { "type": "multiple_choice", "question": "Apa fungsi utama nukleus dalam sel?", @@ -493,7 +493,7 @@ }, { "context": "DNA (asam deoksiribonukleat) adalah molekul yang menyimpan informasi genetik pada hampir semua makhluk hidup.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "DNA ditemukan di dalam nukleus sel.", @@ -503,7 +503,7 @@ }, { "context": "Enzim adalah protein yang berfungsi sebagai katalisator yang mempercepat reaksi kimia dalam tubuh tanpa ikut bereaksi secara permanen.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Enzim berfungsi sebagai _______ yang mempercepat reaksi kimia.", @@ -518,7 +518,7 @@ }, { "context": "Proses respirasi pada manusia terjadi di dalam mitokondria sel, yang menggunakan oksigen untuk menghasilkan energi dalam bentuk ATP.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Respirasi manusia terjadi tanpa menggunakan oksigen.", @@ -534,7 +534,7 @@ }, { "context": "Kloroplas adalah organel yang ditemukan dalam sel tumbuhan yang berfungsi sebagai tempat berlangsungnya fotosintesis.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Kloroplas hanya ditemukan pada sel tumbuhan.", @@ -544,7 +544,7 @@ }, { "context": "Mutasi adalah perubahan yang terjadi pada materi genetik yang dapat menyebabkan variasi genetik dalam suatu populasi.", - "qa_pairs": [ + "question_posibility": [ { "type": "multiple_choice", "question": "Mutasi pada materi genetik dapat menyebabkan apa?", @@ -555,7 +555,7 @@ }, { "context": "Jantung adalah organ vital dalam tubuh manusia yang berfungsi memompa darah ke seluruh tubuh melalui sistem peredaran darah.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Jantung memiliki empat ruang.", @@ -565,7 +565,7 @@ }, { "context": "Hormon insulin dihasilkan oleh pankreas dan berfungsi mengatur kadar gula dalam darah.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Hormon insulin dihasilkan oleh organ _______.", @@ -580,7 +580,7 @@ }, { "context": "Tulang adalah jaringan tubuh manusia yang berfungsi memberi bentuk tubuh, melindungi organ dalam, dan tempat pembentukan sel darah.", - "qa_pairs": [ + "question_posibility": [ { "type": "multiple_choice", "question": "Apa fungsi utama tulang pada manusia?", @@ -601,7 +601,7 @@ }, { "context": "Ginjal adalah organ yang berfungsi menyaring limbah dari darah dan membentuk urin.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Ginjal berfungsi menghasilkan hormon insulin.", @@ -611,7 +611,7 @@ }, { "context": "Paru-paru merupakan organ pernapasan yang bertanggung jawab untuk pertukaran oksigen dan karbon dioksida.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Paru-paru berfungsi untuk pertukaran gas yaitu oksigen dan _______.", @@ -621,7 +621,7 @@ }, { "context": "Sistem saraf manusia terdiri dari sistem saraf pusat dan sistem saraf perifer yang berfungsi mengatur koordinasi tubuh dan merespon rangsangan.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Sistem saraf manusia mencakup otak dan sumsum tulang belakang.", @@ -636,7 +636,7 @@ }, { "context": "Kelenjar tiroid adalah organ yang menghasilkan hormon tiroksin, yang penting untuk mengatur metabolisme tubuh.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Kelenjar tiroid terletak di leher.", @@ -646,7 +646,7 @@ }, { "context": "Eritrosit adalah sel darah merah yang berfungsi membawa oksigen ke seluruh jaringan tubuh.", - "qa_pairs": [ + "question_posibility": [ { "type": "multiple_choice", "question": "Apa fungsi utama eritrosit dalam tubuh manusia?", @@ -662,7 +662,7 @@ }, { "context": "Limfosit merupakan jenis sel darah putih yang berperan penting dalam sistem kekebalan tubuh.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Limfosit berperan dalam sistem kekebalan tubuh.", @@ -672,7 +672,7 @@ }, { "context": "Protein adalah makromolekul yang terdiri dari rantai asam amino dan berfungsi dalam pertumbuhan, perbaikan jaringan, serta produksi enzim.", - "qa_pairs": [ + "question_posibility": [ { "type": "multiple_choice", "question": "Protein terdiri dari rantai molekul apa?", @@ -688,7 +688,7 @@ }, { "context": "VOC (Vereenigde Oostindische Compagnie) adalah perusahaan dagang Belanda yang didirikan pada tahun 1602 dan merupakan salah satu perusahaan multinasional pertama di dunia. VOC memainkan peran penting dalam perdagangan rempah-rempah di Nusantara dan berkontribusi besar terhadap pembentukan sejarah kolonial di Indonesia.", - "qa_pairs": [ + "question_posibility": [ { "type": "multiple_choice", "question": "Apa kepanjangan dari VOC?", @@ -714,7 +714,7 @@ }, { "context": "VOC memiliki hak istimewa dari pemerintah Belanda, termasuk hak untuk mendirikan benteng, mengadakan perjanjian dengan penguasa setempat, dan memiliki angkatan perang sendiri.", - "qa_pairs": [ + "question_posibility": [ { "type": "multiple_choice", "question": "Apa salah satu hak istimewa VOC?", @@ -740,7 +740,7 @@ }, { "context": "VOC mengalami kebangkrutan pada akhir abad ke-18 akibat korupsi, biaya perang yang tinggi, dan persaingan dengan negara lain dalam perdagangan internasional.", - "qa_pairs": [ + "question_posibility": [ { "type": "multiple_choice", "question": "Apa salah satu penyebab kebangkrutan VOC?", @@ -766,7 +766,7 @@ }, { "context": "Pada abad ke-17, VOC menguasai perdagangan rempah-rempah di kepulauan Nusantara dan menerapkan sistem monopoli yang ketat terhadap produk seperti cengkeh, pala, dan lada.", - "qa_pairs": [ + "question_posibility": [ { "type": "multiple_choice", "question": "Produk apa yang dimonopoli oleh VOC?", @@ -787,7 +787,7 @@ }, { "context": "VOC memiliki kebijakan yang dikenal sebagai 'Pelayaran Hongi', di mana armada kapal perang mereka digunakan untuk menghancurkan kebun rempah-rempah yang tidak berada di bawah kendali mereka guna mempertahankan harga tetap tinggi.", - "qa_pairs": [ + "question_posibility": [ { "type": "fill_in_the_blank", "question": "Kebijakan VOC yang bertujuan untuk mempertahankan harga rempah-rempah disebut _______.", @@ -797,7 +797,7 @@ }, { "context": "Pada tahun 1619, Jan Pieterszoon Coen menaklukkan Jayakarta dan menggantinya dengan nama Batavia, yang menjadi pusat kekuasaan VOC di Nusantara.", - "qa_pairs": [ + "question_posibility": [ { "type": "true_false", "question": "Batavia didirikan oleh VOC pada tahun 1619 setelah menaklukkan Jayakarta.", @@ -807,7 +807,7 @@ }, { "context": "Selain berdagang, VOC juga memiliki peran dalam politik di Nusantara, dengan sering kali campur tangan dalam urusan kerajaan lokal untuk memastikan kepentingan ekonomi mereka tetap terjaga.", - "qa_pairs": [ + "question_posibility": [ { "type": "multiple_choice", "question": "Bagaimana VOC mempertahankan kepentingan ekonominya di Nusantara?", @@ -820,5 +820,44 @@ "answer": "Menjalin aliansi dan intervensi politik" } ] + }, + { + "context": "Pada uraian berikut, kalian akan mempelajari ruang lingkup bio logi, memahami objek dan permasalahan biologi pada berbagai tingkat organisasi kehidupan, serta peranannya dalam kehidupan. Kalian juga akan mempelajari metode ilmiah dalam biologi dan bagaimana bersikap ilmiah.", + "question_posibility": [] + }, + { + "context": "Sebagai ilmu pengetahuan alam, biologi menghasilkan hukumhukum yang bersifat universal. Artinya, dilakukan di mana saja, oleh siapa saja, serta kapan saja, secara umum akan mendapatkan hasil yang sama. Dengan istilah lain, dapat dikatakan bahwa biologi memberikan hasil yang bersifat objektif. Hasil temuan tersebut tidak dipengaruhi oleh subjektivitas pelaku eksperimen. Biologi memberikan hasil yang benar secara ilmiah.", + "question_posibility": [] + }, + { + "context": "Dalam mempelajari dan mengembangkan ilmu biologi digunakan metode ilmiah. Oleh karena itu, para biolog harus mampu melakukan kerja ilmiah dalam menyelesaikan masalah atau mencari jawaban permasalahan-permasalahan yang dihadapi dalam penelitiannya.", + "question_posibility": [] + }, + { + "context": "Tahapan dalam metode ilmiah adalah menemukan permasalahan, mengajukan hipotesis, melakukan percobaan untuk menguji hipotesis, menarik kesimpulan, dan membuat laporan percobaan.", + "question_posibility": [ + { + "type": "multiple_choice", + "question": "Apa saja tahapan dalam metode ilmiah", + "options": [ + "Mengamati gejala, membuat laporan, menyusun teori, dan melakukan eksperimen", + "Menemukan permasalahan, mengajukan hipotesis, melakukan percobaan, menarik kesimpulan, dan membuat laporan percobaan", + "Menulis laporan, melakukan wawancara, mengumpulkan opini, dan menguji teori", + "Menentukan kesimpulan terlebih dahulu, kemudian mencari data yang mendukung, lalu membuat laporan" + ], + "answer": "menemukan permasalahan, mengajukan hipotesis, melakukan percobaan, menarik kesumpulan dan membuat laporan percobaan" + } + ] + }, + { + "context": "Tubuh tumbuhan terdiri atas berbagai organ, yaitu akar, batang, dan daun. Pada yang dewasa akan terbentuk bunga serta biji. Sebagai organ fotosintesis, daun disusun oleh berbagai jaringan, yaitu jaringan epidermis, jaringan tiang, jaringan bunga karang, jaringan pengangkut, dan jaringan epidermis. Masing-masing jaringan tersebut disusun oleh sel-sel. Jaringan tiang pada daun misalnya, disusun oleh kumpulan sel yang berbentuk seperti tiang.", + "question_posibility": [ + { + "type": "multiple_choice", + "question": "Tubuh tumbuhan Terdirid ari berbagai organ, kecuali", + "options": ["akar", "batang", "daun", "buah"], + "answer": "buah" + } + ] } ] diff --git a/lstm.ipynb b/lstm.ipynb deleted file mode 100644 index faf2f70..0000000 --- a/lstm.ipynb +++ /dev/null @@ -1,447 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2025-02-05 01:57:25.675154: E external/local_xla/xla/stream_executor/cuda/cuda_driver.cc:152] failed call to cuInit: INTERNAL: CUDA error: Failed call to cuInit: UNKNOWN ERROR (303)\n" - ] - }, - { - "data": { - "text/html": [ - "
Model: \"functional\"\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1mModel: \"functional\"\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n",
-       "┃ Layer (type)         Output Shape          Param #  Connected to      ┃\n",
-       "┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n",
-       "│ encoder_inputs      │ (None, None)      │          0 │ -                 │\n",
-       "│ (InputLayer)        │                   │            │                   │\n",
-       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
-       "│ decoder_inputs      │ (None, None)      │          0 │ -                 │\n",
-       "│ (InputLayer)        │                   │            │                   │\n",
-       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
-       "│ embedding           │ (None, None, 128) │      1,280 │ encoder_inputs[0… │\n",
-       "│ (Embedding)         │                   │            │                   │\n",
-       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
-       "│ not_equal           │ (None, None)      │          0 │ encoder_inputs[0… │\n",
-       "│ (NotEqual)          │                   │            │                   │\n",
-       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
-       "│ decoder_embedding   │ (None, None, 128) │      1,024 │ decoder_inputs[0… │\n",
-       "│ (Embedding)         │                   │            │                   │\n",
-       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
-       "│ encoder_lstm (LSTM) │ [(None, 256),     │    394,240 │ embedding[0][0],  │\n",
-       "│                     │ (None, 256),      │            │ not_equal[0][0]   │\n",
-       "│                     │ (None, 256)]      │            │                   │\n",
-       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
-       "│ decoder_lstm (LSTM) │ [(None, None,     │    394,240 │ decoder_embeddin… │\n",
-       "│                     │ 256), (None,      │            │ encoder_lstm[0][ │\n",
-       "│                     │ 256), (None,      │            │ encoder_lstm[0][ │\n",
-       "│                     │ 256)]             │            │                   │\n",
-       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
-       "│ decoder_dense       │ (None, None, 8)   │      2,056 │ decoder_lstm[0][ │\n",
-       "│ (Dense)             │                   │            │                   │\n",
-       "└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n",
-       "
\n" - ], - "text/plain": [ - "┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n", - "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mConnected to \u001b[0m\u001b[1m \u001b[0m┃\n", - "┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n", - "│ encoder_inputs │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ - │\n", - "│ (\u001b[38;5;33mInputLayer\u001b[0m) │ │ │ │\n", - "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", - "│ decoder_inputs │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ - │\n", - "│ (\u001b[38;5;33mInputLayer\u001b[0m) │ │ │ │\n", - "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", - "│ embedding │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m1,280\u001b[0m │ encoder_inputs[\u001b[38;5;34m0\u001b[0m… │\n", - "│ (\u001b[38;5;33mEmbedding\u001b[0m) │ │ │ │\n", - "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", - "│ not_equal │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ encoder_inputs[\u001b[38;5;34m0\u001b[0m… │\n", - "│ (\u001b[38;5;33mNotEqual\u001b[0m) │ │ │ │\n", - "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", - "│ decoder_embedding │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m1,024\u001b[0m │ decoder_inputs[\u001b[38;5;34m0\u001b[0m… │\n", - "│ (\u001b[38;5;33mEmbedding\u001b[0m) │ │ │ │\n", - "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", - "│ encoder_lstm (\u001b[38;5;33mLSTM\u001b[0m) │ [(\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m), │ \u001b[38;5;34m394,240\u001b[0m │ embedding[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m], │\n", - "│ │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m), │ │ not_equal[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n", - "│ │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m)] │ │ │\n", - "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", - "│ decoder_lstm (\u001b[38;5;33mLSTM\u001b[0m) │ [(\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, │ \u001b[38;5;34m394,240\u001b[0m │ decoder_embeddin… │\n", - "│ │ \u001b[38;5;34m256\u001b[0m), (\u001b[38;5;45mNone\u001b[0m, │ │ encoder_lstm[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n", - "│ │ \u001b[38;5;34m256\u001b[0m), (\u001b[38;5;45mNone\u001b[0m, │ │ encoder_lstm[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n", - "│ │ \u001b[38;5;34m256\u001b[0m)] │ │ │\n", - "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n", - "│ decoder_dense │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m8\u001b[0m) │ \u001b[38;5;34m2,056\u001b[0m │ decoder_lstm[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n", - "│ (\u001b[38;5;33mDense\u001b[0m) │ │ │ │\n", - "└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
 Total params: 792,840 (3.02 MB)\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m792,840\u001b[0m (3.02 MB)\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
 Trainable params: 792,840 (3.02 MB)\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m792,840\u001b[0m (3.02 MB)\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
 Non-trainable params: 0 (0.00 B)\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "None\n", - "Epoch 1/10\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2025-02-05 01:57:27.530017: E tensorflow/core/util/util.cc:131] oneDNN supports DT_BOOL only on platforms with AVX-512. Falling back to the default Eigen-based implementation if present.\n", - "2025-02-05 01:57:27.593630: I tensorflow/core/framework/local_rendezvous.cc:405] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", - "\t [[{{node IteratorGetNext}}]]\n", - "/mnt/disc1/code/lstm-quiz/.venv/lib64/python3.10/site-packages/keras/src/trainers/epoch_iterator.py:151: UserWarning: Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch * epochs` batches. You may need to use the `.repeat()` function when building your dataset.\n", - " self._interrupted_warning()\n" - ] - }, - { - "ename": "ValueError", - "evalue": "math domain error", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[6], line 118\u001b[0m\n\u001b[1;32m 113\u001b[0m target_val \u001b[38;5;241m=\u001b[39m decoder_target_data[split_index:]\n\u001b[1;32m 115\u001b[0m \u001b[38;5;66;03m# ==========================\u001b[39;00m\n\u001b[1;32m 116\u001b[0m \u001b[38;5;66;03m# 6) Fit the Model\u001b[39;00m\n\u001b[1;32m 117\u001b[0m \u001b[38;5;66;03m# ==========================\u001b[39;00m\n\u001b[0;32m--> 118\u001b[0m history \u001b[38;5;241m=\u001b[39m \u001b[43mmodel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfit\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 119\u001b[0m \u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43mencoder_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecoder_train\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 120\u001b[0m \u001b[43m \u001b[49m\u001b[43mtarget_train\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 121\u001b[0m \u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m32\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 122\u001b[0m \u001b[43m \u001b[49m\u001b[43mepochs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m10\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 123\u001b[0m \u001b[43m \u001b[49m\u001b[43mvalidation_data\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[43mencoder_val\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdecoder_val\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtarget_val\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 124\u001b[0m \u001b[43m)\u001b[49m\n\u001b[1;32m 126\u001b[0m \u001b[38;5;66;03m# The accuracy reported is \"sparse_categorical_accuracy\" at the token level.\u001b[39;00m\n\u001b[1;32m 127\u001b[0m \n\u001b[1;32m 128\u001b[0m \u001b[38;5;66;03m# ==========================\u001b[39;00m\n\u001b[1;32m 129\u001b[0m \u001b[38;5;66;03m# 7) Evaluate the Model\u001b[39;00m\n\u001b[1;32m 130\u001b[0m \u001b[38;5;66;03m# ==========================\u001b[39;00m\n\u001b[1;32m 131\u001b[0m \u001b[38;5;66;03m# If you want a quick evaluation on the validation set:\u001b[39;00m\n\u001b[1;32m 132\u001b[0m val_loss, val_accuracy \u001b[38;5;241m=\u001b[39m model\u001b[38;5;241m.\u001b[39mevaluate([encoder_val, decoder_val], target_val)\n", - "File \u001b[0;32m/mnt/disc1/code/lstm-quiz/.venv/lib64/python3.10/site-packages/keras/src/utils/traceback_utils.py:122\u001b[0m, in \u001b[0;36mfilter_traceback..error_handler\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 119\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n\u001b[1;32m 120\u001b[0m \u001b[38;5;66;03m# To get the full stack trace, call:\u001b[39;00m\n\u001b[1;32m 121\u001b[0m \u001b[38;5;66;03m# `keras.config.disable_traceback_filtering()`\u001b[39;00m\n\u001b[0;32m--> 122\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\u001b[38;5;241m.\u001b[39mwith_traceback(filtered_tb) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 123\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[1;32m 124\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m filtered_tb\n", - "File \u001b[0;32m/mnt/disc1/code/lstm-quiz/.venv/lib64/python3.10/site-packages/keras/src/utils/progbar.py:119\u001b[0m, in \u001b[0;36mProgbar.update\u001b[0;34m(self, current, values, finalize)\u001b[0m\n\u001b[1;32m 116\u001b[0m message \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 118\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtarget \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 119\u001b[0m numdigits \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mint\u001b[39m(\u001b[43mmath\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mlog10\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtarget\u001b[49m\u001b[43m)\u001b[49m) \u001b[38;5;241m+\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m 120\u001b[0m bar \u001b[38;5;241m=\u001b[39m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m%\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(numdigits) \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124md/\u001b[39m\u001b[38;5;132;01m%d\u001b[39;00m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;241m%\u001b[39m (current, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtarget)\n\u001b[1;32m 121\u001b[0m bar \u001b[38;5;241m=\u001b[39m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;130;01m\\x1b\u001b[39;00m\u001b[38;5;124m[1m\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mbar\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;130;01m\\x1b\u001b[39;00m\u001b[38;5;124m[0m \u001b[39m\u001b[38;5;124m\"\u001b[39m\n", - "\u001b[0;31mValueError\u001b[0m: math domain error" - ] - } - ], - "source": [ - "# ==========================\n", - "# 1) Install/Import Dependencies\n", - "# ==========================\n", - "# If you are in a brand new environment, uncomment the following line:\n", - "# %pip install tensorflow pandas\n", - "\n", - "import numpy as np\n", - "import pandas as pd\n", - "import tensorflow as tf\n", - "from tensorflow.keras.preprocessing.text import Tokenizer\n", - "from tensorflow.keras.preprocessing.sequence import pad_sequences\n", - "from tensorflow.keras.layers import Input, LSTM, Embedding, Dense\n", - "from tensorflow.keras.models import Model\n", - "\n", - "# ==========================\n", - "# 2) Load Dataset (CSV)\n", - "# ==========================\n", - "# Adjust the file path to your CSV file\n", - "df = pd.read_csv(\"quiz_questions.csv\")\n", - "\n", - "# Extract the paragraphs and questions\n", - "paragraphs = df['paragraph'].astype(str).tolist()\n", - "questions = df['question'].astype(str).tolist()\n", - "\n", - "# (Optional) For demonstration, let's ignore question_type, answer, distractors in this example\n", - "# but you can incorporate them as extra signals if you wish.\n", - "\n", - "# ==========================\n", - "# 3) Tokenize Text\n", - "# ==========================\n", - "# Create two tokenizers: one for paragraphs, one for questions\n", - "num_words = 10000 # Maximum vocabulary size\n", - "\n", - "tokenizer_paragraph = Tokenizer(num_words=num_words, oov_token=\"\")\n", - "tokenizer_paragraph.fit_on_texts(paragraphs)\n", - "paragraph_sequences = tokenizer_paragraph.texts_to_sequences(paragraphs)\n", - "\n", - "tokenizer_question = Tokenizer(num_words=num_words, oov_token=\"\")\n", - "tokenizer_question.fit_on_texts(questions)\n", - "question_sequences = tokenizer_question.texts_to_sequences(questions)\n", - "\n", - "# Get max lengths (for padding)\n", - "max_paragraph_len = max(len(seq) for seq in paragraph_sequences)\n", - "max_question_len = max(len(seq) for seq in question_sequences)\n", - "\n", - "# Pad sequences\n", - "encoder_input_data = pad_sequences(paragraph_sequences, maxlen=max_paragraph_len, padding='post')\n", - "# For decoder data, we usually do teacher forcing:\n", - "# We'll keep one version as input, one version shifted as the target\n", - "decoder_input_data_full = pad_sequences(question_sequences, maxlen=max_question_len, padding='post')\n", - "\n", - "# We create decoder_target_data by shifting to the left by 1 token\n", - "decoder_target_data = np.copy(decoder_input_data_full[:, 1:])\n", - "decoder_input_data = np.copy(decoder_input_data_full[:, :-1])\n", - "\n", - "# Expand target dimension for sparse_categorical_crossentropy\n", - "decoder_target_data = np.expand_dims(decoder_target_data, -1)\n", - "\n", - "# Calculate vocab sizes\n", - "vocab_size_paragraph = min(len(tokenizer_paragraph.word_index) + 1, num_words)\n", - "vocab_size_question = min(len(tokenizer_question.word_index) + 1, num_words)\n", - "\n", - "# ==========================\n", - "# 4) Build Seq2Seq Model\n", - "# ==========================\n", - "embedding_dim = 128\n", - "latent_dim = 256 # LSTM hidden dimension\n", - "\n", - "# ----- Encoder -----\n", - "encoder_inputs = Input(shape=(None,), name=\"encoder_inputs\")\n", - "encoder_embedding = Embedding(input_dim=vocab_size_paragraph,\n", - " output_dim=embedding_dim,\n", - " mask_zero=True)(encoder_inputs)\n", - "\n", - "encoder_lstm = LSTM(latent_dim, return_state=True, name=\"encoder_lstm\")\n", - "_, state_h, state_c = encoder_lstm(encoder_embedding)\n", - "\n", - "encoder_states = [state_h, state_c]\n", - "\n", - "# ----- Decoder -----\n", - "decoder_inputs = Input(shape=(None,), name=\"decoder_inputs\")\n", - "decoder_embedding = Embedding(input_dim=vocab_size_question,\n", - " output_dim=embedding_dim,\n", - " mask_zero=True,\n", - " name=\"decoder_embedding\")(decoder_inputs)\n", - "\n", - "decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True, name=\"decoder_lstm\")\n", - "decoder_outputs, _, _ = decoder_lstm(decoder_embedding,\n", - " initial_state=encoder_states)\n", - "decoder_dense = Dense(vocab_size_question, activation='softmax', name=\"decoder_dense\")\n", - "decoder_outputs = decoder_dense(decoder_outputs)\n", - "\n", - "# Combine into a training model\n", - "model = Model([encoder_inputs, decoder_inputs], decoder_outputs)\n", - "model.compile(optimizer='adam',\n", - " loss='sparse_categorical_crossentropy',\n", - " metrics=['sparse_categorical_accuracy'])\n", - "\n", - "print(model.summary())\n", - "\n", - "# ==========================\n", - "# 5) Train/Test Split (Optional)\n", - "# ==========================\n", - "# For simplicity, let's do a quick train/validation split\n", - "# Adjust split size or do a separate test set for production usage.\n", - "split_index = int(0.8 * len(encoder_input_data))\n", - "encoder_train = encoder_input_data[:split_index]\n", - "decoder_train = decoder_input_data[:split_index]\n", - "target_train = decoder_target_data[:split_index]\n", - "\n", - "encoder_val = encoder_input_data[split_index:]\n", - "decoder_val = decoder_input_data[split_index:]\n", - "target_val = decoder_target_data[split_index:]\n", - "\n", - "# ==========================\n", - "# 6) Fit the Model\n", - "# ==========================\n", - "history = model.fit(\n", - " [encoder_train, decoder_train],\n", - " target_train,\n", - " batch_size=32,\n", - " epochs=10,\n", - " validation_data=([encoder_val, decoder_val], target_val)\n", - ")\n", - "\n", - "# The accuracy reported is \"sparse_categorical_accuracy\" at the token level.\n", - "\n", - "# ==========================\n", - "# 7) Evaluate the Model\n", - "# ==========================\n", - "# If you want a quick evaluation on the validation set:\n", - "val_loss, val_accuracy = model.evaluate([encoder_val, decoder_val], target_val)\n", - "print(f\"Validation Loss: {val_loss:.4f}\")\n", - "print(f\"Validation Accuracy (token-level): {val_accuracy:.4f}\")\n", - "\n", - "# ==========================\n", - "# 8) Build Inference Models\n", - "# ==========================\n", - "# Encoder model for inference\n", - "encoder_model_inf = Model(encoder_inputs, encoder_states)\n", - "\n", - "# Decoder model for inference\n", - "decoder_state_input_h = Input(shape=(latent_dim,), name=\"inference_state_h\")\n", - "decoder_state_input_c = Input(shape=(latent_dim,), name=\"inference_state_c\")\n", - "decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]\n", - "\n", - "dec_emb_inf = decoder_embedding(decoder_inputs)\n", - "decoder_inf_outputs, state_h_inf, state_c_inf = decoder_lstm(\n", - " dec_emb_inf, initial_state=decoder_states_inputs\n", - ")\n", - "decoder_inf_states = [state_h_inf, state_c_inf]\n", - "decoder_inf_outputs = decoder_dense(decoder_inf_outputs)\n", - "\n", - "decoder_model_inf = Model(\n", - " [decoder_inputs] + decoder_states_inputs,\n", - " [decoder_inf_outputs] + decoder_inf_states\n", - ")\n", - "\n", - "# Create index-to-word mapping for the question tokenizer\n", - "index_to_word_question = {idx: word for word, idx in tokenizer_question.word_index.items()}\n", - "# If you used an OOV token, might want to handle that as well.\n", - "\n", - "def generate_question(paragraph_text, max_length=50, start_token=None, end_token=None):\n", - " \"\"\"\n", - " Generate a question from a paragraph using the trained seq2seq model.\n", - " Token-level decoding with greedy search.\n", - " \"\"\"\n", - " # 1) Encode the paragraph\n", - " seq = tokenizer_paragraph.texts_to_sequences([paragraph_text])\n", - " seq = pad_sequences(seq, maxlen=max_paragraph_len, padding='post')\n", - " states_value = encoder_model_inf.predict(seq)\n", - "\n", - " # 2) Start token\n", - " target_seq = np.zeros((1, 1), dtype='int32')\n", - " # If you have a token, set it here\n", - " # e.g., target_seq[0, 0] = tokenizer_question.word_index[\"\"]\n", - "\n", - " decoded_words = []\n", - "\n", - " for _ in range(max_length):\n", - " output_tokens, h, c = decoder_model_inf.predict([target_seq] + states_value)\n", - "\n", - " sampled_token_index = np.argmax(output_tokens[0, -1, :])\n", - " sampled_word = index_to_word_question.get(sampled_token_index, '')\n", - "\n", - " # Stop if we encounter an token or a special index\n", - " if end_token and (sampled_word == end_token):\n", - " break\n", - "\n", - " decoded_words.append(sampled_word)\n", - "\n", - " # Next target\n", - " target_seq = np.zeros((1, 1), dtype='int32')\n", - " target_seq[0, 0] = sampled_token_index\n", - "\n", - " states_value = [h, c]\n", - "\n", - " return ' '.join(decoded_words)\n", - "\n", - "# ==========================\n", - "# 9) Test Inference on a Paragraph\n", - "# ==========================\n", - "test_paragraph = \"Albert Einstein was a theoretical physicist born in Germany...\"\n", - "generated = generate_question(test_paragraph)\n", - "print(\"Generated question:\", generated)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "yups 0\n", - "yups 1\n", - "yups 2\n", - "yups 3\n", - "yups 4\n", - "yups 5\n", - "yups 6\n", - "yups 7\n", - "yups 8\n", - "yups 9\n", - "yups 10\n", - "yups 11\n", - "yups 12\n", - "yups 13\n", - "yups 14\n", - "yups 15\n", - "yups 16\n", - "yups 17\n", - "yups 18\n", - "yups 19\n" - ] - } - ], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": ".venv", - "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.10.16" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/lstm_multi_output_model.h5 b/lstm_multi_output_model.h5 deleted file mode 100644 index a8248b4..0000000 Binary files a/lstm_multi_output_model.h5 and /dev/null differ diff --git a/lstm_multi_output_model.keras b/lstm_multi_output_model.keras index ad43383..00a6876 100644 Binary files a/lstm_multi_output_model.keras and b/lstm_multi_output_model.keras differ diff --git a/lstm_question_generator.keras b/lstm_question_generator.keras deleted file mode 100644 index 7aae8fa..0000000 Binary files a/lstm_question_generator.keras and /dev/null differ diff --git a/main.py b/main.py deleted file mode 100644 index 32a764b..0000000 --- a/main.py +++ /dev/null @@ -1,123 +0,0 @@ -import pandas as pd -import numpy as np -from sklearn.model_selection import train_test_split -import tensorflow as tf -import pickle -from tensorflow.keras.preprocessing.text import Tokenizer -from tensorflow.keras.preprocessing.sequence import pad_sequences -from tensorflow.keras.models import Sequential -from tensorflow.keras.layers import ( - LSTM, - Embedding, - Dense, - SpatialDropout1D, - TimeDistributed, -) -from tensorflow.keras.optimizers import Adam - - -# 1. Load dataset - -df = pd.read_csv("quiz_questions.csv") - -# Pastikan kolom 'paragraph' dan 'question' ada dan tidak kosong -df.dropna(subset=["paragraph", "question"], inplace=True) - - -# 2. Preprocessing text - - -def preprocess_text(text): - # Contoh preprocessing sederhana - text = text.lower() - return text - - -df["paragraph"] = df["paragraph"].astype(str).apply(preprocess_text) -df["question"] = df["question"].astype(str).apply(preprocess_text) - - -# 3. Tokenization - -# Gabung semua teks (paragraph+question) agar vocabulary mencakup kata2 di keduanya -tokenizer = Tokenizer() -tokenizer.fit_on_texts(df["paragraph"].tolist() + df["question"].tolist()) -vocab_size = len(tokenizer.word_index) + 1 # +1 karena index dimulai dari 1 - -# Konversi teks menjadi sequences -X_sequences = tokenizer.texts_to_sequences(df["paragraph"]) -y_sequences = tokenizer.texts_to_sequences(df["question"]) - -# Cari panjang sequence maksimal (agar uniform untuk padding) -max_len_paragraph = max(len(seq) for seq in X_sequences) -max_len_question = max(len(seq) for seq in y_sequences) -max_length = max(max_len_paragraph, max_len_question) - -# Padding sequences (panjangnya disamakan => max_length) -X_padded = pad_sequences(X_sequences, maxlen=max_length, padding="post") -y_padded = pad_sequences(y_sequences, maxlen=max_length, padding="post") - -with open("tokenizer.pkl", "wb") as f: - pickle.dump(tokenizer, f) -print("Tokenizer disimpan ke tokenizer.pkl") - - -# 4. Siapkan X, y - -# Untuk sequence-to-sequence dengan "sparse_categorical_crossentropy", -# idealnya y memiliki shape: (num_samples, max_length, 1) -X = np.array(X_padded) -y = np.expand_dims(np.array(y_padded), axis=-1) - -print("Shape X:", X.shape) -print("Shape y:", y.shape) # (batch_size, max_length, 1) - - -# 5. Split data - -X_train, X_test, y_train, y_test = train_test_split( - X, y, test_size=0.2, random_state=42 -) - -print("Train size:", X_train.shape, y_train.shape) -print("Test size: ", X_test.shape, y_test.shape) - - -# 6. Build Model LSTM - -# Kita pakai 2 LSTM stack, masing2 return_sequences=True -# Supaya output akhirnya tetap "sequence" (batch_size, max_length, hidden_dim) -model = Sequential() -model.add(Embedding(input_dim=vocab_size, output_dim=128)) -model.add(SpatialDropout1D(0.2)) - -model.add(LSTM(128, return_sequences=True)) -model.add(LSTM(128, return_sequences=True)) - -# TimeDistributed Dense agar Dense diaplikasikan per timestep -model.add(TimeDistributed(Dense(vocab_size, activation="softmax"))) - - -# 7. Compile - -model.compile( - loss="sparse_categorical_crossentropy", - optimizer=Adam(learning_rate=0.001), - metrics=["accuracy"], -) - -model.summary() - - -# 8. Train Model - -epochs = 10 -history = model.fit( - X_train, y_train, epochs=epochs, validation_data=(X_test, y_test), batch_size=32 -) - - -# 9. Save Model - -model.save("lstm_question_generator.keras") -print("Training selesai dan model telah disimpan.") diff --git a/normalize_text/normalize.json b/normalize_text/normalize.json new file mode 100644 index 0000000..2abea5a --- /dev/null +++ b/normalize_text/normalize.json @@ -0,0 +1,65 @@ +{ + "yg": "yang", + "gokil": "kocak", + "kalo": "kalau", + "gue": "saya", + "elo": "kamu", + "nih": "ini", + "trs": "terus", + "tdk": "tidak", + "gmna": "bagaimana", + "tp": "tapi", + "jd": "jadi", + "aja": "saja", + "krn": "karena", + "blm": "belum", + "dgn": "dengan", + "skrg": "sekarang", + "msh": "masih", + "lg": "lagi", + "sy": "saya", + "sm": "sama", + "bgt": "banget", + "dr": "dari", + "kpn": "kapan", + "hrs": "harus", + "cm": "cuma", + "sbnrnya": "sebenarnya", + "tdr": "tidur", + "kl": "kalau", + "org": "orang", + "pke": "pakai", + "prnh": "pernah", + "brgkt": "berangkat", + "pdhl": "padahal", + "btw": "ngomong-ngomong", + "dmn": "di mana", + "bsk": "besok", + "td": "tadi", + "dlm": "dalam", + "utk": "untuk", + "spt": "seperti", + "gpp": "tidak apa-apa", + "bs": "bisa", + "jg": "juga", + "dg": "dengan", + "klw": "kalau", + "wkwk": "haha", + "cpt": "cepat", + "knp": "kenapa", + "jgk": "juga", + "plg": "pulang", + "brp": "berapa", + "bkn": "bukan", + "mnt": "minta", + "udh": "sudah", + "sdh": "sudah", + "brkt": "berangkat", + "sprt": "seperti", + "jgn": "jangan", + "mlm": "malam", + "sblm": "sebelum", + "stlh": "setelah", + "mlh": "malah", + "tmn": "teman" +} diff --git a/online mcqs.ipynb b/online mcqs.ipynb new file mode 100644 index 0000000..03a7ac0 --- /dev/null +++ b/online mcqs.ipynb @@ -0,0 +1,265 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "c9142fcb-39a6-42cb-a38c-629ca17c5ac6", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2025-03-17 14:50:32.718599: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n", + "2025-03-17 14:50:32.718943: I external/local_xla/xla/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.\n", + "2025-03-17 14:50:32.721006: I external/local_xla/xla/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.\n", + "2025-03-17 14:50:32.727572: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:477] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n", + "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\n", + "E0000 00:00:1742197832.738194 22019 cuda_dnn.cc:8310] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n", + "E0000 00:00:1742197832.741303 22019 cuda_blas.cc:1418] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n", + "2025-03-17 14:50:32.752422: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n", + "To enable the following instructions: AVX2 AVX_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n" + ] + }, + { + "ename": "OSError", + "evalue": "[E050] Can't find model 'en_core_web_md'. It doesn't seem to be a Python package or a valid path to a data directory.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mOSError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 11\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mrandom\u001b[39;00m\n\u001b[1;32m 10\u001b[0m \u001b[38;5;66;03m# Load spaCy model with word vectors\u001b[39;00m\n\u001b[0;32m---> 11\u001b[0m nlp \u001b[38;5;241m=\u001b[39m \u001b[43mspacy\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43men_core_web_md\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# Use \"en_core_web_md\" or \"en_core_web_lg\" for word vectors\u001b[39;00m\n\u001b[1;32m 13\u001b[0m \u001b[38;5;66;03m# Function to preprocess text\u001b[39;00m\n\u001b[1;32m 14\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mpreprocess_text\u001b[39m(text):\n", + "File \u001b[0;32m/mnt/disc1/code/thesis_quiz_project/lstm-quiz/myenv/lib64/python3.10/site-packages/spacy/__init__.py:51\u001b[0m, in \u001b[0;36mload\u001b[0;34m(name, vocab, disable, enable, exclude, config)\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mload\u001b[39m(\n\u001b[1;32m 28\u001b[0m name: Union[\u001b[38;5;28mstr\u001b[39m, Path],\n\u001b[1;32m 29\u001b[0m \u001b[38;5;241m*\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 34\u001b[0m config: Union[Dict[\u001b[38;5;28mstr\u001b[39m, Any], Config] \u001b[38;5;241m=\u001b[39m util\u001b[38;5;241m.\u001b[39mSimpleFrozenDict(),\n\u001b[1;32m 35\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Language:\n\u001b[1;32m 36\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Load a spaCy model from an installed package or a local path.\u001b[39;00m\n\u001b[1;32m 37\u001b[0m \n\u001b[1;32m 38\u001b[0m \u001b[38;5;124;03m name (str): Package name or model path.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 49\u001b[0m \u001b[38;5;124;03m RETURNS (Language): The loaded nlp object.\u001b[39;00m\n\u001b[1;32m 50\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m---> 51\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mutil\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload_model\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 52\u001b[0m \u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 53\u001b[0m \u001b[43m \u001b[49m\u001b[43mvocab\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mvocab\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 54\u001b[0m \u001b[43m \u001b[49m\u001b[43mdisable\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdisable\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 55\u001b[0m \u001b[43m \u001b[49m\u001b[43menable\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43menable\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 56\u001b[0m \u001b[43m \u001b[49m\u001b[43mexclude\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mexclude\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 57\u001b[0m \u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 58\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/mnt/disc1/code/thesis_quiz_project/lstm-quiz/myenv/lib64/python3.10/site-packages/spacy/util.py:472\u001b[0m, in \u001b[0;36mload_model\u001b[0;34m(name, vocab, disable, enable, exclude, config)\u001b[0m\n\u001b[1;32m 470\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m OLD_MODEL_SHORTCUTS:\n\u001b[1;32m 471\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mIOError\u001b[39;00m(Errors\u001b[38;5;241m.\u001b[39mE941\u001b[38;5;241m.\u001b[39mformat(name\u001b[38;5;241m=\u001b[39mname, full\u001b[38;5;241m=\u001b[39mOLD_MODEL_SHORTCUTS[name])) \u001b[38;5;66;03m# type: ignore[index]\u001b[39;00m\n\u001b[0;32m--> 472\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mIOError\u001b[39;00m(Errors\u001b[38;5;241m.\u001b[39mE050\u001b[38;5;241m.\u001b[39mformat(name\u001b[38;5;241m=\u001b[39mname))\n", + "\u001b[0;31mOSError\u001b[0m: [E050] Can't find model 'en_core_web_md'. It doesn't seem to be a Python package or a valid path to a data directory." + ] + } + ], + "source": [ + "import numpy as np\n", + "import tensorflow as tf\n", + "from tensorflow.keras.preprocessing.text import Tokenizer\n", + "from tensorflow.keras.preprocessing.sequence import pad_sequences\n", + "from tensorflow.keras.models import Sequential\n", + "from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout\n", + "import spacy\n", + "import random\n", + "\n", + "# Load spaCy model with word vectors\n", + "nlp = spacy.load(\"en_core_web_md\") # Use \"en_core_web_md\" or \"en_core_web_lg\" for word vectors\n", + "\n", + "# Function to preprocess text\n", + "def preprocess_text(text):\n", + " doc = nlp(text)\n", + " sentences = [sent.text for sent in doc.sents]\n", + " return sentences\n", + "\n", + "# Function to create training data for LSTM\n", + "def create_training_data(sentences, tokenizer, max_length):\n", + " sequences = tokenizer.texts_to_sequences(sentences)\n", + " padded_sequences = pad_sequences(sequences, maxlen=max_length, padding='post')\n", + " return padded_sequences\n", + "\n", + "# LSTM Model for learning sentence structures\n", + "def build_lstm_model(vocab_size, max_length, embedding_dim):\n", + " model = Sequential([\n", + " Embedding(vocab_size, embedding_dim, input_length=max_length),\n", + " LSTM(128, return_sequences=True),\n", + " Dropout(0.2),\n", + " LSTM(64),\n", + " Dense(64, activation='relu'),\n", + " Dense(vocab_size, activation='softmax')\n", + " ])\n", + " model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\n", + " return model\n", + "\n", + "# Function to find similar words using spaCy\n", + "def find_similar_words(word, num_similar=3):\n", + " word_token = nlp.vocab[word] if word in nlp.vocab else None\n", + " if not word_token or not word_token.has_vector:\n", + " return [\"[Distractor]\"] * num_similar # Return placeholders if no vector is found\n", + "\n", + " # Compute similarity with other words in vocab\n", + " similarities = []\n", + " for token in nlp.vocab:\n", + " if token.is_alpha and token.has_vector and token != word_token:\n", + " similarity = word_token.similarity(token)\n", + " similarities.append((token.text, similarity))\n", + " \n", + " # Sort and return top similar words\n", + " similarities.sort(key=lambda x: x[1], reverse=True)\n", + " return [word for word, _ in similarities[:num_similar]]\n", + "\n", + "# Function to generate MCQs using LSTM and spaCy word embeddings\n", + "def generate_mcqs_lstm(text, tokenizer, max_length, model, num_questions=5):\n", + " sentences = preprocess_text(text)\n", + " selected_sentences = random.sample(sentences, min(num_questions, len(sentences)))\n", + "\n", + " mcqs = []\n", + " for sentence in selected_sentences:\n", + " doc = nlp(sentence)\n", + " nouns = [token.text for token in doc if token.pos_ == \"NOUN\"]\n", + " if len(nouns) < 1:\n", + " continue\n", + "\n", + " subject = random.choice(nouns)\n", + " question_stem = sentence.replace(subject, \"______\")\n", + "\n", + " # Generate similar words using spaCy\n", + " similar_words = find_similar_words(subject, num_similar=3)\n", + "\n", + " answer_choices = [subject] + similar_words\n", + " random.shuffle(answer_choices)\n", + " correct_answer = chr(65 + answer_choices.index(subject))\n", + "\n", + " mcqs.append((question_stem, answer_choices, correct_answer))\n", + "\n", + " return mcqs\n", + "\n", + "# Example usage\n", + "text = \"\"\"Deep learning is a subset of machine learning that uses neural networks. LSTMs are useful for processing sequential data like text. \n", + "Natural language processing involves techniques like tokenization and named entity recognition.\"\"\"\n", + "\n", + "# Tokenizer setup\n", + "tokenizer = Tokenizer()\n", + "tokenizer.fit_on_texts(preprocess_text(text))\n", + "vocab_size = len(tokenizer.word_index) + 1\n", + "max_length = 20\n", + "\n", + "# Train LSTM model (Note: Training requires large datasets)\n", + "model = build_lstm_model(vocab_size, max_length, embedding_dim=100)\n", + "\n", + "# Generate MCQs\n", + "mcqs = generate_mcqs_lstm(text, tokenizer, max_length, model, num_questions=3)\n", + "for i, (q, choices, ans) in enumerate(mcqs, 1):\n", + " print(f\"Q{i}: {q}\")\n", + " print(f\" A) {choices[0]} B) {choices[1]} C) {choices[2]} D) {choices[3]}\")\n", + " print(f\"Correct Answer: {ans}\\n\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "62aae7fc-b921-4439-8396-62d7fd8d25d5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting en-core-web-md==3.8.0\n", + " Downloading https://github.com/explosion/spacy-models/releases/download/en_core_web_md-3.8.0/en_core_web_md-3.8.0-py3-none-any.whl (33.5 MB)\n", + " ---------------------------------------- 0.0/33.5 MB ? eta -:--:--\n", + " --------------------------------------- 0.5/33.5 MB 4.2 MB/s eta 0:00:08\n", + " -- ------------------------------------- 1.8/33.5 MB 5.6 MB/s eta 0:00:06\n", + " --- ------------------------------------ 3.1/33.5 MB 5.8 MB/s eta 0:00:06\n", + " ----- ---------------------------------- 4.2/33.5 MB 5.9 MB/s eta 0:00:05\n", + " ------ --------------------------------- 5.2/33.5 MB 5.5 MB/s eta 0:00:06\n", + " ------- -------------------------------- 6.6/33.5 MB 5.6 MB/s eta 0:00:05\n", + " --------- ------------------------------ 7.6/33.5 MB 5.6 MB/s eta 0:00:05\n", + " ---------- ----------------------------- 8.4/33.5 MB 5.4 MB/s eta 0:00:05\n", + " ----------- ---------------------------- 9.7/33.5 MB 5.5 MB/s eta 0:00:05\n", + " ------------ --------------------------- 10.7/33.5 MB 5.5 MB/s eta 0:00:05\n", + " -------------- ------------------------- 12.1/33.5 MB 5.5 MB/s eta 0:00:04\n", + " --------------- ------------------------ 13.1/33.5 MB 5.5 MB/s eta 0:00:04\n", + " ---------------- ----------------------- 14.2/33.5 MB 5.5 MB/s eta 0:00:04\n", + " ------------------ --------------------- 15.2/33.5 MB 5.4 MB/s eta 0:00:04\n", + " ------------------- -------------------- 16.3/33.5 MB 5.4 MB/s eta 0:00:04\n", + " -------------------- ------------------- 17.6/33.5 MB 5.4 MB/s eta 0:00:03\n", + " ---------------------- ----------------- 18.9/33.5 MB 5.5 MB/s eta 0:00:03\n", + " ------------------------ --------------- 20.2/33.5 MB 5.5 MB/s eta 0:00:03\n", + " ------------------------- -------------- 21.8/33.5 MB 5.6 MB/s eta 0:00:03\n", + " --------------------------- ------------ 23.1/33.5 MB 5.6 MB/s eta 0:00:02\n", + " ---------------------------- ----------- 24.1/33.5 MB 5.7 MB/s eta 0:00:02\n", + " ------------------------------ --------- 25.4/33.5 MB 5.7 MB/s eta 0:00:02\n", + " ------------------------------- -------- 26.5/33.5 MB 5.6 MB/s eta 0:00:02\n", + " -------------------------------- ------- 27.5/33.5 MB 5.6 MB/s eta 0:00:02\n", + " ---------------------------------- ----- 28.8/33.5 MB 5.6 MB/s eta 0:00:01\n", + " ----------------------------------- ---- 29.9/33.5 MB 5.6 MB/s eta 0:00:01\n", + " ------------------------------------ --- 30.9/33.5 MB 5.6 MB/s eta 0:00:01\n", + " -------------------------------------- - 32.0/33.5 MB 5.6 MB/s eta 0:00:01\n", + " --------------------------------------- 33.0/33.5 MB 5.5 MB/s eta 0:00:01\n", + " --------------------------------------- 33.3/33.5 MB 5.5 MB/s eta 0:00:01\n", + " ---------------------------------------- 33.5/33.5 MB 5.4 MB/s eta 0:00:00\n", + "Installing collected packages: en-core-web-md\n", + "Successfully installed en-core-web-md-3.8.0\n", + "\u001b[38;5;2m[+] Download and installation successful\u001b[0m\n", + "You can now load the package via spacy.load('en_core_web_md')\n" + ] + } + ], + "source": [ + "!python -m spacy download en_core_web_md\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "703acaf0-e703-47ae-b4d2-56cd7236fbd4", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cc979d1c-2756-41b6-96de-6c76f2bd5f96", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4f22536a-3967-486c-a6f7-bd677199800a", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "307af48e-a684-4e85-b2df-e963c43ad07c", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bec7b11b-7f3a-4a9e-a568-2e382caaa004", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a5cd5ef2-c48f-4bd0-bf42-12865cc77149", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "myenv", + "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.10.16" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/question_padded.npy b/question_padded.npy deleted file mode 100644 index b8bad3c..0000000 Binary files a/question_padded.npy and /dev/null differ diff --git a/question_type_labels.npy b/question_type_labels.npy deleted file mode 100644 index 6db1732..0000000 Binary files a/question_type_labels.npy and /dev/null differ diff --git a/tokenizer.pkl b/tokenizer.pkl index e793ef0..8e5c4a3 100644 Binary files a/tokenizer.pkl and b/tokenizer.pkl differ diff --git a/training_model.ipynb b/training_model.ipynb index de09828..23827d8 100644 --- a/training_model.ipynb +++ b/training_model.ipynb @@ -2,46 +2,35 @@ "cells": [ { "cell_type": "code", - "execution_count": 22, + "execution_count": 112, "metadata": {}, "outputs": [], "source": [ - "# import library\n", "\n", - "# Data manipulation and visualization\n", - "import pandas as pd\n", "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import json\n", - "\n", - "# Natural language processing\n", "import re\n", "import string\n", "import nltk\n", "from nltk.corpus import stopwords\n", "from nltk.tokenize import word_tokenize\n", - "from nltk.stem import WordNetLemmatizer\n", + "import matplotlib.pyplot as plt\n", "\n", - "# Deep learning\n", "from tensorflow.keras.preprocessing.text import Tokenizer\n", "from tensorflow.keras.preprocessing.sequence import pad_sequences\n", "from tensorflow.keras.models import Model\n", - "from tensorflow.keras.layers import Input, Embedding, LSTM, Dense, Concatenate\n", - "from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\n", - "\n", + "from tensorflow.keras.layers import Input, Embedding, LSTM, Dense\n", "\n", + "from Sastrawi.Stemmer.StemmerFactory import StemmerFactory\n", "from sklearn.model_selection import train_test_split\n", + "import pickle\n", "\n", - "# Metrics for model evaluation\n", - "from sklearn.metrics import classification_report, precision_score, recall_score, accuracy_score\n", - "\n", - "# Utility for serialization\n", - "import pickle\n" + "from sklearn.metrics import classification_report, accuracy_score, precision_score, recall_score\n", + "import nltk" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 113, "metadata": {}, "outputs": [ { @@ -64,7 +53,7 @@ "True" ] }, - "execution_count": 23, + "execution_count": 113, "metadata": {}, "output_type": "execute_result" } @@ -79,131 +68,69 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 114, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - " context \\\n", - "0 Albert Einstein adalah fisikawan teoretis kela... \n", - "1 Samudra Pasifik adalah yang terbesar dan terda... \n", - "2 Proklamasi Kemerdekaan Indonesia dibacakan pad... \n", - "3 Hukum Newton adalah tiga hukum fisika yang men... \n", - "4 Budi Utomo adalah organisasi pemuda yang didir... \n", - "\n", - " qa_pairs \n", - "0 [{'type': 'fill_in_the_blank', 'question': 'Si... \n", - "1 [{'type': 'fill_in_the_blank', 'question': 'Sa... \n", - "2 [{'type': 'fill_in_the_blank', 'question': 'Pr... \n", - "3 [{'type': 'fill_in_the_blank', 'question': 'Hu... \n", - "4 [{'type': 'fill_in_the_blank', 'question': 'Bu... \n", - "\n", - "Total Context: 49\n", - "Total QA Pairs: 95\n" + "Total Context: 54\n", + "Total Possibility Questions: 97\n", + "Total Fill in the Blank Questions: 24\n", + "Total Multiple Choice Questions: 29\n", + "Total True/False Questions: 44\n" ] } ], "source": [ - "# load dataset\n", - "df = pd.read_json(\"dataset/training_dataset.json\")\n", - "print(df.head())\n", - "with open(\"dataset/training_dataset.json\", \"r\", encoding=\"utf-8\") as file:\n", + "import json\n", + "from collections import defaultdict\n", + "\n", + "# path dataset\n", + "file_path = \"dataset/training_dataset.json\"\n", + "\n", + "with open(file_path, \"r\", encoding=\"utf-8\") as file:\n", " dataset = json.load(file)\n", - " \n", - " \n", - "# Menghitung total context\n", + "\n", "total_context = len(dataset)\n", "\n", - "# Menghitung total qa_pairs\n", - "total_qa_pairs = sum(len(entry[\"qa_pairs\"]) for entry in dataset)\n", + "total_question_posibility = sum(len(entry[\"question_posibility\"]) for entry in dataset)\n", "\n", - "# Menampilkan hasil\n", - "print(f\"\\nTotal Context: {total_context}\")\n", - "print(f\"Total QA Pairs: {total_qa_pairs}\")" + "question_type_counts = defaultdict(int)\n", + "for entry in dataset:\n", + " for question in entry[\"question_posibility\"]:\n", + " question_type_counts[question[\"type\"]] += 1\n", + "\n", + "print(f\"Total Context: {total_context}\")\n", + "print(f\"Total Possibility Questions: {total_question_posibility}\")\n", + "print(f\"Total Fill in the Blank Questions: {question_type_counts.get('fill_in_the_blank', 0)}\")\n", + "print(f\"Total Multiple Choice Questions: {question_type_counts.get('multiple_choice', 0)}\")\n", + "print(f\"Total True/False Questions: {question_type_counts.get('true_false', 0)}\")\n" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 115, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Data processing complete!\n", + "Samples: 97\n" + ] + } + ], "source": [ "# Text Preprocessing\n", "stop_words = set(stopwords.words(\"indonesian\")) \n", - "lemmatizer = WordNetLemmatizer()\n", + "factory = StemmerFactory()\n", + "stemmer = factory.create_stemmer()\n", "\n", - "normalization_dict = {\n", - " \"yg\": \"yang\",\n", - " \"gokil\": \"kocak\",\n", - " \"kalo\": \"kalau\",\n", - " \"gue\": \"saya\",\n", - " \"elo\": \"kamu\",\n", - " \"nih\": \"ini\",\n", - " \"trs\": \"terus\",\n", - " \"tdk\": \"tidak\",\n", - " \"gmna\": \"bagaimana\",\n", - " \"tp\": \"tapi\",\n", - " \"jd\": \"jadi\",\n", - " \"aja\": \"saja\",\n", - " \"krn\": \"karena\",\n", - " \"blm\": \"belum\",\n", - " \"dgn\": \"dengan\",\n", - " \"skrg\": \"sekarang\",\n", - " \"msh\": \"masih\",\n", - " \"lg\": \"lagi\",\n", - " \"sy\": \"saya\",\n", - " \"sm\": \"sama\",\n", - " \"bgt\": \"banget\",\n", - " \"dr\": \"dari\",\n", - " \"kpn\": \"kapan\",\n", - " \"hrs\": \"harus\",\n", - " \"cm\": \"cuma\",\n", - " \"sbnrnya\": \"sebenarnya\",\n", - " \"tdr\": \"tidur\",\n", - " \"tdk\": \"tidak\",\n", - " \"kl\": \"kalau\",\n", - " \"org\": \"orang\",\n", - " \"pke\": \"pakai\",\n", - " \"prnh\": \"pernah\",\n", - " \"brgkt\": \"berangkat\",\n", - " \"pdhl\": \"padahal\",\n", - " \"btw\": \"ngomong-ngomong\",\n", - " \"dmn\": \"di mana\",\n", - " \"bsk\": \"besok\",\n", - " \"td\": \"tadi\",\n", - " \"dlm\": \"dalam\",\n", - " \"utk\": \"untuk\",\n", - " \"spt\": \"seperti\",\n", - " \"gpp\": \"tidak apa-apa\",\n", - " \"bs\": \"bisa\",\n", - " \"jg\": \"juga\",\n", - " \"tp\": \"tapi\",\n", - " \"dg\": \"dengan\",\n", - " \"klw\": \"kalau\",\n", - " \"wkwk\": \"haha\",\n", - " \"cpt\": \"cepat\",\n", - " \"knp\": \"kenapa\",\n", - " \"jgk\": \"juga\",\n", - " \"plg\": \"pulang\",\n", - " \"brp\": \"berapa\",\n", - " \"bkn\": \"bukan\",\n", - " \"mnt\": \"minta\",\n", - " \"udh\": \"sudah\",\n", - " \"sdh\": \"sudah\",\n", - " \"brkt\": \"berangkat\",\n", - " \"btw\": \"by the way\",\n", - " \"tdk\": \"tidak\",\n", - " \"sprt\": \"seperti\",\n", - " \"jgn\": \"jangan\",\n", - " \"mlm\": \"malam\",\n", - " \"sblm\": \"sebelum\",\n", - " \"stlh\": \"setelah\",\n", - " \"tdr\": \"tidur\",\n", - " \"mlh\": \"malah\",\n", - " \"tmn\": \"teman\",\n", - "}\n", + "with open(\"normalize_text/normalize.json\", \"r\", encoding=\"utf-8\") as file:\n", + " normalization_dict = json.load(file)\n", "\n", "\n", "def text_preprocessing(text):\n", @@ -219,117 +146,98 @@ " # word tokenize \n", " tokens = word_tokenize(text)\n", " \n", + " \n", " # normalassi kata\n", " tokens = [normalization_dict[word] if word in normalization_dict else word for word in tokens] \n", " \n", " \n", - " # lemmatization\n", - " tokens = [lemmatizer.lemmatize(word) for word in tokens] \n", + " # Lemmatization using Sastrawi (stemming in Indonesian)\n", + " tokens = [stemmer.stem(word) for word in tokens]\n", " \n", " # stopword removal\n", " tokens = [word for word in tokens if word not in stop_words] \n", " \n", - " return tokens\n" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "✅ Data processing complete!\n", - "Samples: 95\n" - ] - } - ], - "source": [ - "# with open(\"dataset/training_dataset.json\", \"r\", encoding=\"utf-8\") as file:\n", - "# dataset = json.load(file)\n", + " return tokens\n", "\n", - "# === Extract Data so that each QA pair has its own context === #\n", + "# text processing all data training\n", "contexts = []\n", "questions = []\n", - "answers = []\n", + "correct_answers = []\n", + "wrong_answers = []\n", "question_types = []\n", "\n", "for entry in dataset:\n", " processed_context = text_preprocessing(entry[\"context\"])\n", - " for qa in entry[\"qa_pairs\"]:\n", + " \n", + " for qa in entry[\"question_posibility\"]:\n", + " processed_question = text_preprocessing(qa[\"question\"])\n", + " processed_answer = text_preprocessing(qa[\"answer\"])\n", + " \n", " contexts.append(processed_context)\n", - " questions.append(text_preprocessing(qa[\"question\"]))\n", - " answers.append(text_preprocessing(qa[\"answer\"]))\n", + " questions.append(processed_question)\n", + " correct_answers.append(processed_answer)\n", " question_types.append(qa[\"type\"])\n", "\n", - "# === Initialize Tokenizer and fit on all text === #\n", - "tokenizer = Tokenizer(oov_token=\"\")\n", - "tokenizer.fit_on_texts(contexts + questions + answers)\n", + " if qa[\"type\"] == \"multiple_choice\":\n", + " incorrect_options = [opt for opt in qa[\"options\"] if opt != qa[\"answer\"]]\n", + " wrong_answers.append(incorrect_options)\n", + " else:\n", + " wrong_answers.append([])\n", + "\n", + "tokenizer = Tokenizer(oov_token=\"\")\n", + "tokenizer.fit_on_texts(contexts + questions + correct_answers)\n", + "\n", "\n", - "# === Convert Text to Sequences === #\n", "context_sequences = tokenizer.texts_to_sequences(contexts)\n", "question_sequences = tokenizer.texts_to_sequences(questions)\n", - "answer_sequences = tokenizer.texts_to_sequences(answers)\n", + "answer_sequences = tokenizer.texts_to_sequences(correct_answers)\n", "\n", - "# === Define Max Length for Padding === #\n", "MAX_LENGTH = 100\n", "context_padded = pad_sequences(context_sequences, maxlen=MAX_LENGTH, padding=\"post\", truncating=\"post\")\n", "question_padded = pad_sequences(question_sequences, maxlen=MAX_LENGTH, padding=\"post\", truncating=\"post\")\n", "answer_padded = pad_sequences(answer_sequences, maxlen=MAX_LENGTH, padding=\"post\", truncating=\"post\")\n", "\n", - "# Encode Question Types\n", "question_type_dict = {\"fill_in_the_blank\": 0, \"true_false\": 1, \"multiple_choice\": 2}\n", "question_type_labels = np.array([question_type_dict[q_type] for q_type in question_types])\n", "\n", - "# Save the processed data (optional)\n", - "np.save(\"context_padded.npy\", context_padded)\n", - "np.save(\"question_padded.npy\", question_padded)\n", - "np.save(\"answer_padded.npy\", answer_padded)\n", - "np.save(\"question_type_labels.npy\", question_type_labels)\n", - "with open(\"tokenizer.pkl\", \"wb\") as handle:\n", - " pickle.dump(tokenizer, handle, protocol=pickle.HIGHEST_PROTOCOL)\n", - "\n", - "print(\"✅ Data processing complete!\")\n", - "print(\"Samples:\", context_padded.shape[0]) # This should now match the number of QA pairs\n" + "print(\"Data processing complete!\")\n", + "print(\"Samples:\", context_padded.shape[0]) \n" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 116, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Training samples: 76\n", - "Testing samples: 19\n" + "Training samples: 77\n", + "Testing samples: 10\n", + "Validation samples: 10\n" ] } ], "source": [ - "# === Split Data into Training and Testing Sets === #\n", - "(context_train, context_test,\n", - " question_train, question_test,\n", - " answer_train, answer_test,\n", - " qtype_train, qtype_test) = train_test_split(\n", - " context_padded,\n", - " question_padded,\n", - " answer_padded,\n", - " question_type_labels,\n", - " test_size=0.2,\n", - " random_state=42\n", + "# split text for testing 8:2\n", + "context_train, context_temp, question_train, question_temp, answer_train, answer_temp, qtype_train, qtype_temp = train_test_split(\n", + " context_padded, question_padded, answer_padded, question_type_labels, test_size=0.2, random_state=42\n", + ")\n", + "\n", + "# split dataset testing and validation 5:5\n", + "context_test, context_val, question_test, question_val, answer_test, answer_val, qtype_test, qtype_val = train_test_split(\n", + " context_temp, question_temp, answer_temp, qtype_temp, test_size=0.5, random_state=42\n", ")\n", "\n", "print(\"Training samples:\", context_train.shape[0])\n", - "print(\"Testing samples:\", context_test.shape[0])\n" + "print(\"Testing samples:\", context_test.shape[0])\n", + "print(\"Validation samples:\", context_val.shape[0])\n" ] }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 120, "metadata": {}, "outputs": [ { @@ -337,131 +245,195 @@ "output_type": "stream", "text": [ "Epoch 1/10\n", - "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 681ms/step - answer_output_accuracy: 0.0297 - answer_output_loss: 6.2965 - loss: 13.6985 - question_output_accuracy: 0.0000e+00 - question_output_loss: 6.3022 - question_type_output_accuracy: 0.2625 - question_type_output_loss: 1.0992 - val_answer_output_accuracy: 0.2044 - val_answer_output_loss: 6.2629 - val_loss: 13.6638 - val_question_output_accuracy: 0.0069 - val_question_output_loss: 6.2961 - val_question_type_output_accuracy: 0.2500 - val_question_type_output_loss: 1.1048\n", + "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 1s/step - answer_output_accuracy: 0.0344 - answer_output_loss: 6.2090 - loss: 13.5239 - question_output_accuracy: 0.0000e+00 - question_output_loss: 6.2154 - question_type_output_accuracy: 0.3004 - question_type_output_loss: 1.0991 - val_answer_output_accuracy: 0.2287 - val_answer_output_loss: 6.1669 - val_loss: 13.4815 - val_question_output_accuracy: 0.0050 - val_question_output_loss: 6.2101 - val_question_type_output_accuracy: 0.3125 - val_question_type_output_loss: 1.1046\n", "Epoch 2/10\n", - "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 305ms/step - answer_output_accuracy: 0.2145 - answer_output_loss: 6.2378 - loss: 13.6041 - question_output_accuracy: 0.0127 - question_output_loss: 6.2865 - question_type_output_accuracy: 0.6076 - question_type_output_loss: 1.0785 - val_answer_output_accuracy: 0.9844 - val_answer_output_loss: 6.1644 - val_loss: 13.5630 - val_question_output_accuracy: 0.0100 - val_question_output_loss: 6.2887 - val_question_type_output_accuracy: 0.3750 - val_question_type_output_loss: 1.1100\n", + "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 526ms/step - answer_output_accuracy: 0.2277 - answer_output_loss: 6.1421 - loss: 13.4196 - question_output_accuracy: 0.0113 - question_output_loss: 6.1984 - question_type_output_accuracy: 0.6445 - question_type_output_loss: 1.0780 - val_answer_output_accuracy: 0.9856 - val_answer_output_loss: 6.0462 - val_loss: 13.3570 - val_question_output_accuracy: 0.0081 - val_question_output_loss: 6.2031 - val_question_type_output_accuracy: 0.3125 - val_question_type_output_loss: 1.1076\n", "Epoch 3/10\n", - "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 297ms/step - answer_output_accuracy: 0.9846 - answer_output_loss: 6.0887 - loss: 13.4154 - question_output_accuracy: 0.0168 - question_output_loss: 6.2692 - question_type_output_accuracy: 0.5542 - question_type_output_loss: 1.0537 - val_answer_output_accuracy: 0.9844 - val_answer_output_loss: 5.8030 - val_loss: 13.2110 - val_question_output_accuracy: 0.0094 - val_question_output_loss: 6.2794 - val_question_type_output_accuracy: 0.4375 - val_question_type_output_loss: 1.1287\n", + "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 528ms/step - answer_output_accuracy: 0.9837 - answer_output_loss: 5.9539 - loss: 13.1879 - question_output_accuracy: 0.0171 - question_output_loss: 6.1802 - question_type_output_accuracy: 0.5799 - question_type_output_loss: 1.0503 - val_answer_output_accuracy: 0.9856 - val_answer_output_loss: 5.5439 - val_loss: 12.8565 - val_question_output_accuracy: 0.0087 - val_question_output_loss: 6.1941 - val_question_type_output_accuracy: 0.5000 - val_question_type_output_loss: 1.1185\n", "Epoch 4/10\n", - "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 300ms/step - answer_output_accuracy: 0.9853 - answer_output_loss: 5.4983 - loss: 12.7772 - question_output_accuracy: 0.0143 - question_output_loss: 6.2471 - question_type_output_accuracy: 0.5111 - question_type_output_loss: 1.0153 - val_answer_output_accuracy: 0.9844 - val_answer_output_loss: 3.9937 - val_loss: 11.4697 - val_question_output_accuracy: 0.0050 - val_question_output_loss: 6.2620 - val_question_type_output_accuracy: 0.4375 - val_question_type_output_loss: 1.2140\n", + "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 533ms/step - answer_output_accuracy: 0.9839 - answer_output_loss: 5.1228 - loss: 12.2985 - question_output_accuracy: 0.0137 - question_output_loss: 6.1532 - question_type_output_accuracy: 0.5164 - question_type_output_loss: 1.0060 - val_answer_output_accuracy: 0.9856 - val_answer_output_loss: 3.2875 - val_loss: 10.6708 - val_question_output_accuracy: 0.0050 - val_question_output_loss: 6.1772 - val_question_type_output_accuracy: 0.5000 - val_question_type_output_loss: 1.2060\n", "Epoch 5/10\n", - "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 308ms/step - answer_output_accuracy: 0.9855 - answer_output_loss: 3.4938 - loss: 10.7212 - question_output_accuracy: 0.0046 - question_output_loss: 6.1959 - question_type_output_accuracy: 0.4903 - question_type_output_loss: 1.0066 - val_answer_output_accuracy: 0.9844 - val_answer_output_loss: 1.4529 - val_loss: 9.4832 - val_question_output_accuracy: 0.0037 - val_question_output_loss: 6.2063 - val_question_type_output_accuracy: 0.4375 - val_question_type_output_loss: 1.8240\n", + "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 520ms/step - answer_output_accuracy: 0.9835 - answer_output_loss: 2.7939 - loss: 9.9397 - question_output_accuracy: 0.0056 - question_output_loss: 6.0862 - question_type_output_accuracy: 0.5263 - question_type_output_loss: 1.0473 - val_answer_output_accuracy: 0.9856 - val_answer_output_loss: 1.1028 - val_loss: 9.0601 - val_question_output_accuracy: 0.0012 - val_question_output_loss: 6.1277 - val_question_type_output_accuracy: 0.5000 - val_question_type_output_loss: 1.8296\n", "Epoch 6/10\n", - "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 296ms/step - answer_output_accuracy: 0.9853 - answer_output_loss: 1.4168 - loss: 8.7444 - question_output_accuracy: 0.0029 - question_output_loss: 6.0149 - question_type_output_accuracy: 0.5007 - question_type_output_loss: 1.3046 - val_answer_output_accuracy: 0.9844 - val_answer_output_loss: 0.7223 - val_loss: 8.8975 - val_question_output_accuracy: 0.0019 - val_question_output_loss: 6.1260 - val_question_type_output_accuracy: 0.2500 - val_question_type_output_loss: 2.0492\n", + "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 541ms/step - answer_output_accuracy: 0.9828 - answer_output_loss: 1.2315 - loss: 8.3718 - question_output_accuracy: 0.0016 - question_output_loss: 5.8773 - question_type_output_accuracy: 0.5055 - question_type_output_loss: 1.2478 - val_answer_output_accuracy: 0.9856 - val_answer_output_loss: 0.6227 - val_loss: 8.6339 - val_question_output_accuracy: 0.0012 - val_question_output_loss: 6.0831 - val_question_type_output_accuracy: 0.1250 - val_question_type_output_loss: 1.9281\n", "Epoch 7/10\n", - "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 316ms/step - answer_output_accuracy: 0.9855 - answer_output_loss: 0.7297 - loss: 7.7458 - question_output_accuracy: 0.0020 - question_output_loss: 5.7405 - question_type_output_accuracy: 0.5653 - question_type_output_loss: 1.2641 - val_answer_output_accuracy: 0.9844 - val_answer_output_loss: 0.6319 - val_loss: 8.0634 - val_question_output_accuracy: 0.0019 - val_question_output_loss: 6.0919 - val_question_type_output_accuracy: 0.3125 - val_question_type_output_loss: 1.3396\n", + "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 492ms/step - answer_output_accuracy: 0.9842 - answer_output_loss: 0.7375 - loss: 7.4714 - question_output_accuracy: 9.6824e-04 - question_output_loss: 5.5770 - question_type_output_accuracy: 0.4612 - question_type_output_loss: 1.1578 - val_answer_output_accuracy: 0.9856 - val_answer_output_loss: 0.5788 - val_loss: 7.9850 - val_question_output_accuracy: 0.0012 - val_question_output_loss: 6.1148 - val_question_type_output_accuracy: 0.1250 - val_question_type_output_loss: 1.2913\n", "Epoch 8/10\n", - "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 300ms/step - answer_output_accuracy: 0.9852 - answer_output_loss: 0.6516 - loss: 7.1078 - question_output_accuracy: 0.0025 - question_output_loss: 5.5006 - question_type_output_accuracy: 0.5424 - question_type_output_loss: 0.9515 - val_answer_output_accuracy: 0.9844 - val_answer_output_loss: 0.6445 - val_loss: 7.8441 - val_question_output_accuracy: 0.0031 - val_question_output_loss: 6.1414 - val_question_type_output_accuracy: 0.3125 - val_question_type_output_loss: 1.0582\n", + "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 455ms/step - answer_output_accuracy: 0.9847 - answer_output_loss: 0.6731 - loss: 6.9870 - question_output_accuracy: 0.0011 - question_output_loss: 5.3263 - question_type_output_accuracy: 0.5596 - question_type_output_loss: 0.9895 - val_answer_output_accuracy: 0.9856 - val_answer_output_loss: 0.6030 - val_loss: 7.8753 - val_question_output_accuracy: 0.0012 - val_question_output_loss: 6.2693 - val_question_type_output_accuracy: 0.5000 - val_question_type_output_loss: 1.0031\n", "Epoch 9/10\n", - "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 301ms/step - answer_output_accuracy: 0.9855 - answer_output_loss: 0.5892 - loss: 6.9181 - question_output_accuracy: 0.0027 - question_output_loss: 5.2758 - question_type_output_accuracy: 0.4993 - question_type_output_loss: 1.0541 - val_answer_output_accuracy: 0.9844 - val_answer_output_loss: 0.6490 - val_loss: 7.9863 - val_question_output_accuracy: 0.0031 - val_question_output_loss: 6.2535 - val_question_type_output_accuracy: 0.4375 - val_question_type_output_loss: 1.0839\n", + "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 458ms/step - answer_output_accuracy: 0.9836 - answer_output_loss: 0.7391 - loss: 6.9393 - question_output_accuracy: 0.0017 - question_output_loss: 5.0887 - question_type_output_accuracy: 0.4841 - question_type_output_loss: 1.1123 - val_answer_output_accuracy: 0.9856 - val_answer_output_loss: 0.6056 - val_loss: 8.1353 - val_question_output_accuracy: 0.0019 - val_question_output_loss: 6.4616 - val_question_type_output_accuracy: 0.5000 - val_question_type_output_loss: 1.0682\n", "Epoch 10/10\n", - "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 296ms/step - answer_output_accuracy: 0.9854 - answer_output_loss: 0.5727 - loss: 6.6346 - question_output_accuracy: 0.0027 - question_output_loss: 5.0879 - question_type_output_accuracy: 0.5319 - question_type_output_loss: 0.9754 - val_answer_output_accuracy: 0.9844 - val_answer_output_loss: 0.6354 - val_loss: 8.3545 - val_question_output_accuracy: 0.0037 - val_question_output_loss: 6.4062 - val_question_type_output_accuracy: 0.2500 - val_question_type_output_loss: 1.3129\n", - "✅ Model training complete and saved!\n" + "\u001b[1m2/2\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 454ms/step - answer_output_accuracy: 0.9847 - answer_output_loss: 0.6727 - loss: 6.6312 - question_output_accuracy: 0.0018 - question_output_loss: 4.9620 - question_type_output_accuracy: 0.5258 - question_type_output_loss: 1.0078 - val_answer_output_accuracy: 0.9856 - val_answer_output_loss: 0.5869 - val_loss: 8.5074 - val_question_output_accuracy: 0.0037 - val_question_output_loss: 6.6207 - val_question_type_output_accuracy: 0.3750 - val_question_type_output_loss: 1.2998\n" ] } ], "source": [ - "# === Model Hyperparameters === #\n", + "\n", "VOCAB_SIZE = len(tokenizer.word_index) + 1\n", "EMBEDDING_DIM = 300\n", "LSTM_UNITS = 256\n", "BATCH_SIZE = 32\n", "EPOCHS = 10\n", "\n", - "# === Build Model === #\n", - "# Encoder for Context\n", "context_input = Input(shape=(MAX_LENGTH,), name=\"context_input\")\n", "context_embedding = Embedding(input_dim=VOCAB_SIZE, output_dim=EMBEDDING_DIM, mask_zero=True, name=\"context_embedding\")(context_input)\n", "encoder_lstm = LSTM(LSTM_UNITS, return_state=True, name=\"encoder_lstm\")\n", "encoder_output, state_h, state_c = encoder_lstm(context_embedding)\n", "\n", - "# Decoder for Question (Teacher Forcing)\n", + "# Question Decoder\n", "question_decoder_input = Input(shape=(MAX_LENGTH,), name=\"question_decoder_input\")\n", "question_embedding = Embedding(input_dim=VOCAB_SIZE, output_dim=EMBEDDING_DIM, mask_zero=True, name=\"question_embedding\")(question_decoder_input)\n", "question_lstm = LSTM(LSTM_UNITS, return_sequences=True, return_state=True, name=\"question_lstm\")\n", "question_output, _, _ = question_lstm(question_embedding, initial_state=[state_h, state_c])\n", "question_dense = Dense(VOCAB_SIZE, activation=\"softmax\", name=\"question_output\")(question_output)\n", "\n", - "# Decoder for Answer\n", + "# Answer Decoder\n", "answer_lstm = LSTM(LSTM_UNITS, return_sequences=True, return_state=True, name=\"answer_lstm\")\n", "answer_output, _, _ = answer_lstm(context_embedding, initial_state=[state_h, state_c])\n", "answer_dense = Dense(VOCAB_SIZE, activation=\"softmax\", name=\"answer_output\")(answer_output)\n", "\n", - "# Classification Output for Question Type\n", "type_dense = Dense(128, activation=\"relu\")(encoder_output)\n", "question_type_output = Dense(3, activation=\"softmax\", name=\"question_type_output\")(type_dense)\n", "\n", - "# Construct the Model\n", "model = Model(\n", " inputs=[context_input, question_decoder_input],\n", - " outputs=[question_dense, answer_dense, question_type_output],\n", + " outputs=[question_dense, answer_dense, question_type_output]\n", ")\n", "\n", - "# === Compile the Model === #\n", "model.compile(\n", " optimizer=\"adam\",\n", - " loss={\n", - " \"question_output\": \"sparse_categorical_crossentropy\",\n", - " \"answer_output\": \"sparse_categorical_crossentropy\",\n", - " \"question_type_output\": \"sparse_categorical_crossentropy\",\n", - " },\n", - " metrics={\n", - " \"question_output\": [\"accuracy\"],\n", - " \"answer_output\": [\"accuracy\"],\n", - " \"question_type_output\": [\"accuracy\"],\n", - " },\n", + " loss={\"question_output\": \"sparse_categorical_crossentropy\",\n", + " \"answer_output\": \"sparse_categorical_crossentropy\",\n", + " \"question_type_output\": \"sparse_categorical_crossentropy\"},\n", + " metrics={\"question_output\": [\"accuracy\"],\n", + " \"answer_output\": [\"accuracy\"],\n", + " \"question_type_output\": [\"accuracy\"]}\n", ")\n", "\n", - "# === Train the Model === #\n", - "model.fit(\n", + "data_model = model.fit(\n", " [context_train, question_train],\n", - " {\n", - " \"question_output\": question_train,\n", - " \"answer_output\": answer_train,\n", - " \"question_type_output\": qtype_train,\n", - " },\n", + " {\"question_output\": question_train, \"answer_output\": answer_train, \"question_type_output\": qtype_train},\n", " batch_size=BATCH_SIZE,\n", " epochs=EPOCHS,\n", - " validation_split=0.2,\n", + " validation_split=0.2\n", ")\n", "\n", - "# Save the Model\n", "model.save(\"lstm_multi_output_model.keras\")\n", - "print(\"✅ Model training complete and saved!\")" + "with open(\"tokenizer.pkl\", \"wb\") as handle:\n", + " pickle.dump(tokenizer, handle, protocol=pickle.HIGHEST_PROTOCOL)\n" ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 121, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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Bn2THPdmVVZWiufOnRMrKyulLuW2LV26VLS3txcPHTokdSnUBnz77beim5tbg/82t2SW9PeemlZxcbFFXFNczRLPiVqnpIceFs916izmr/9W6lLq+DPxT7Hbum7ivdvvlboUukZr/394YmKi+Nhjj4leXl6iIAgiAPH+++8Xy8vLa22Xnp4u3nnnnaKdnZ0YGhoq/vHHH6KTk5O4du1a0zaZmZnio48+Krq7u4sqlUoMCQkRZ8+eLRYXF4tZWVnixIkTRR8fH1GpVIqBgYHi0qVLRb3e+DtYVVWV+MADD4jOzs4iANN+AdT6/f3UqVPiiBEjRGtra9HV1VWcPXu2WFpaanr9scceEydMmFCr9gULFogRERGN+iwAiP/884/puWuPX1Pr448/Ljo5OYnOzs7iM888Iy5evFjs2bNng3VERESICxYsqLWfCRMmiI899liD9bz++usigDqPmnziep/F9T5vtVotPvjgg2JAQICoVCpFX19fcd68ea3mv+Hr/Z1r7DWFIN6om1oTGjBgAMLDw/Hf//4XqB4J1a5dO8ybN6/eRucvv/wyfvjhByQkJJga+X788cdYuXIlMjIyGnXMkpISODk5obi4GI6ON15RrqXKXPo6in78EW7P/AueCxaYdd/xx3Ow48szcHS3xsP/GdSkDYpzkkuwf0scMuOLAQDlVkVI7XoCnzz9Hwgy6RsjV1VVITExEcHBwbC2tpa6nNu2du1aFBcXY/78+aa/Q0TmVFFRgczMTNx3332YOHEiVqxYIXVJN83S/t5T07GUa4qrWeI5UeuUv24dct5ZCdvwcAR+u17qcmop1ZRi2OZh0Bl0+N/E/7XYBXraIkv7f/jrr7+ODz74oEkWECIyh+v9nWvsNYWkv5UuXLgQX375JdavX4/z58/jmWeeQXl5uWk1vkcffRRLliwxbf/MM8+goKAACxYswKVLl/D777/jrbfewty5cyU8C2loEhIAAKomaHJuWnXPTFP3rscz0BGTnu+DsbO7QXDUwk7rjM4nR2LrymPIiCtq0mO3RU888QSeffZZBlLUZN5991107twZ3t7etf79JiIiuhkO1YshVRw7Bl1hodTl1OKgdEB/r/4AgD1pnMJHTWf58uX45JNPcPjw4SZtwk0kJUl/M502bRref/99LF26FL169UJsbCz++usv0xzUlJSUWg3cAgIC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BxERERHFPkmSIJlMkE0m4LARPUQiRWtYdjihY8P0ej1GjhyJRYsWhfcpioJFixbhlFNOafaaU045pcn5ALBw4cIWzzcYDLBYLE0eREREREREREQklvD+fDNnzsSMGTMwatQojBkzBs8++yzsdjuuu+46AMA111yDnJwczJkzBwDwl7/8BWeeeSb++c9/4txzz8UHH3yANWvW4FXBk3MREREREREREVHrCQ+lrrjiClRWVuL+++9HWVkZhg0bhnnz5oUnMy8uLoYsN3ToOvXUUzF37lzce++9uPvuu9G7d2988cUXGDRokMC7ICIiIiIiIiKi4yGpajPrcMcxq9WK5ORk1NXVcSgfERERnbB4bFPE4z0RERFR5LW2TSF0TikiIiIiIiIiIuqYGEoREREREREREVHEMZQiIiIiIiIiIqKIYyhFREREREREREQRx1CKiIiIiIiIiIgijqEUERERERERERFFHEMpIiIiIiIiIiKKOIZSREREREREREQUcQyliIiIiIiIiIgo4hhKERERERERERFRxDGUIiIiIiIiIiKiiGMoRUREREREREREEcdQioiIiIiIiIiIIo6hFBERERERERERRRxDKSIiIiIiIiIiijiGUkREREREREREFHFa0QVEmqqqAACr1Sq6FCIiIophobZEqG0RD9hOIiIiorbQ2nZShwulbDYbACA3N1d0KURERBQHbDYbkpOTRZfRJthOIiIiorZ0rHaSpMbTr/daQVEUHDx4EGazGZIktfnrW61W5ObmoqSkBBaLpc1fn9oWP6/Yws8rdvCzii38vE6Mqqqw2Wzo0qULZDk+ZkRgO4ka4+cVW/h5xQ5+VrGFn9eJaW07qcP1lJJlGV27dm3397FYLPwDG0P4ecUWfl6xg59VbOHndfzipYdUCNtJ1Bx+XrGFn1fs4GcVW/h5Hb/WtJPi49d6REREREREREQUUxhKERERERERERFRxDGUamMGgwEPPPAADAaD6FKoFfh5xRZ+XrGDn1Vs4edFkcI/a7GFn1ds4ecVO/hZxRZ+Xu2rw010TkRERERERERE4rGnFBERERERERERRRxDKSIiIiIiIiIiijiGUkREREREREREFHEMpdrYCy+8gLy8PBiNRowdOxarVq0SXRI1Y86cORg9ejTMZjMyMzNx0UUXYefOnaLLolZ44oknIEkS7rjjDtGl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mDFjhqrRaNTExMQmj8cee0xVVVUFoN50001Nrhk7dqx68803q6qqqq+++qqampqq1tfXh49/++23qizLallZmaqqqtqlSxf1nnvuabEGAOq9994b/rq+vl4FoH7//fdtfr9ERERErcV2EhFFI84pRURxZeLEiXjppZea7EtLSwtvn3LKKU2OnXLKKdiwYQMAYPv27Rg6dCgSExPDx8ePHw9FUbBz505IkoSDBw9i0qRJR61hyJAh4e3ExERYLBZUVFSc9L0RERERnQy2k4go2jCUIqK4kpiYeEQ38baSkJDQqvN0Ol2TryVJgqIo7VITERERUWuxnURE0YZzShFRh7JixYojvu7fvz8AoH///ti4cSPsdnv4+LJlyyDLMvr27Quz2Yy8vDwsWrQo4nUTERERtTe2k4go0thTiojiitvtRllZWZN9Wq0W6enpAICPP/4Yo0aNwmmnnYb33nsPq1atwmuvvQYAuOqqq/DAAw9gxowZePDBB1FZWYnbb78dV199NbKysgAADz74IG666SZkZmZi+vTpsNlsWLZsGW6//XYBd0tERETUemwnEVG0YShFRHFl3rx5yM7ObrKvb9++2LFjBxBc8eWDDz7ALbfcguzsbLz//vsYMGAAAMBkMmH+/Pn4y1/+gtGjR8NkMuHSSy/Fv/71r/BrzZgxAy6XC//+979x5513Ij09HZdddlmE75KIiIjo+LGdRETRRlIDqyAQEcU9SZLw+eef46KLLhJdChEREVFUYTuJiETgnFJERERERERERBRxDKWIiIiIiIiIiCjiOHyPiIiIiIiIiIgijj2liIiIiIiIiIgo4hhKERERERERERFRxDGUIiIiIiIiIiKiiGMoRUREREREREREEcdQioiIiIiIiIiIIo6hFBERERERERERRRxDKSIiIiIiIiIiijiGUkREREREREREFHEMpYiIiIiIiIiIKOL+H5V9RYujxzg1AAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "# data epoch\n", + "\n", + "plt.figure(figsize=(12, 6))\n", + "\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(data_model.history['question_output_accuracy'], label='Question Train Accuracy')\n", + "plt.plot(data_model.history['val_question_output_accuracy'], label='Question Val Accuracy')\n", + "plt.plot(data_model.history['answer_output_accuracy'], label='Answer Train Accuracy')\n", + "plt.plot(data_model.history['val_answer_output_accuracy'], label='Answer Val Accuracy')\n", + "plt.plot(data_model.history['question_type_output_accuracy'], label='Question Type Train Accuracy')\n", + "plt.plot(data_model.history['val_question_type_output_accuracy'], label='Question Type Val Accuracy')\n", + "plt.title('Model Accuracy')\n", + "plt.xlabel('Epoch')\n", + "plt.ylabel('Accuracy')\n", + "plt.legend()\n", + "\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(data_model.history['question_output_loss'], label='Question Train Loss')\n", + "plt.plot(data_model.history['val_question_output_loss'], label='Question Val Loss')\n", + "plt.plot(data_model.history['answer_output_loss'], label='Answer Train Loss')\n", + "plt.plot(data_model.history['val_answer_output_loss'], label='Answer Val Loss')\n", + "plt.plot(data_model.history['question_type_output_loss'], label='Question Type Train Loss')\n", + "plt.plot(data_model.history['val_question_type_output_loss'], label='Question Type Val Loss')\n", + "plt.title('Model Loss')\n", + "plt.xlabel('Epoch')\n", + "plt.ylabel('Loss')\n", + "plt.legend()\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 119, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 264ms/step\n", + "\n", "=== Evaluation on Test Data ===\n", - "Classification Report for Question Type:\n", + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 389ms/step\n", + "Classification Report for Question Type (Test Set):\n", " precision recall f1-score support\n", "\n", - " 0 0.00 0.00 0.00 8\n", - " 1 0.50 0.83 0.62 6\n", - " 2 0.44 0.80 0.57 5\n", + " 0 0.00 0.00 0.00 4\n", + " 1 0.40 0.67 0.50 3\n", + " 2 0.20 0.33 0.25 3\n", "\n", - " accuracy 0.47 19\n", - " macro avg 0.31 0.54 0.40 19\n", - "weighted avg 0.27 0.47 0.35 19\n", + " accuracy 0.30 10\n", + " macro avg 0.20 0.33 0.25 10\n", + "weighted avg 0.18 0.30 0.23 10\n", "\n", - "Accuracy: 0.47368421052631576\n", - "Precision: 0.27485380116959063\n", - "Recall: 0.47368421052631576\n", - "BLEU score for first test sample (question generation): 0\n" + "Test Accuracy: 0.3\n", + "Test Precision: 0.18000000000000002\n", + "Test Recall: 0.3\n", + "BLEU Score for first test sample (question generation): 0.02664466031983166\n", + "BLEU Score for first test sample (answer generation): 0\n", + "\n", + "=== Evaluation on Validation Data ===\n", + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 92ms/step\n", + "Classification Report for Question Type (Validation Set):\n", + " precision recall f1-score support\n", + "\n", + " 0 0.00 0.00 0.00 4\n", + " 1 0.50 1.00 0.67 3\n", + " 2 0.25 0.33 0.29 3\n", + "\n", + " accuracy 0.40 10\n", + " macro avg 0.25 0.44 0.32 10\n", + "weighted avg 0.23 0.40 0.29 10\n", + "\n", + "Validation Accuracy: 0.4\n", + "Validation Precision: 0.225\n", + "Validation Recall: 0.4\n", + "BLEU Score for first validation sample (question generation): 0.008991061769415444\n", + "BLEU Score for first validation sample (answer generation): 0\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ + "/mnt/disc1/code/thesis_quiz_project/lstm-quiz/myenv/lib64/python3.10/site-packages/sklearn/metrics/_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n", + " _warn_prf(average, modifier, f\"{metric.capitalize()} is\", len(result))\n", + "/mnt/disc1/code/thesis_quiz_project/lstm-quiz/myenv/lib64/python3.10/site-packages/sklearn/metrics/_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n", + " _warn_prf(average, modifier, f\"{metric.capitalize()} is\", len(result))\n", + "/mnt/disc1/code/thesis_quiz_project/lstm-quiz/myenv/lib64/python3.10/site-packages/sklearn/metrics/_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n", + " _warn_prf(average, modifier, f\"{metric.capitalize()} is\", len(result))\n", + "/mnt/disc1/code/thesis_quiz_project/lstm-quiz/myenv/lib64/python3.10/site-packages/sklearn/metrics/_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n", + " _warn_prf(average, modifier, f\"{metric.capitalize()} is\", len(result))\n", "/mnt/disc1/code/thesis_quiz_project/lstm-quiz/myenv/lib64/python3.10/site-packages/sklearn/metrics/_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n", " _warn_prf(average, modifier, f\"{metric.capitalize()} is\", len(result))\n", "/mnt/disc1/code/thesis_quiz_project/lstm-quiz/myenv/lib64/python3.10/site-packages/sklearn/metrics/_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n", @@ -474,25 +446,52 @@ } ], "source": [ - "# === Evaluate on Test Set === #\n", - "pred_question, pred_answer, pred_qtype = model.predict([context_test, question_test])\n", - "pred_qtype_labels = np.argmax(pred_qtype, axis=1)\n", "\n", - "print(\"=== Evaluation on Test Data ===\")\n", - "print(\"Classification Report for Question Type:\")\n", - "print(classification_report(qtype_test, pred_qtype_labels))\n", - "print(\"Accuracy:\", accuracy_score(qtype_test, pred_qtype_labels))\n", - "print(\"Precision:\", precision_score(qtype_test, pred_qtype_labels, average='weighted'))\n", - "print(\"Recall:\", recall_score(qtype_test, pred_qtype_labels, average='weighted'))\n", "\n", "\n", "def sequence_to_text(sequence, tokenizer):\n", - " return [tokenizer.index_word.get(idx, \"\") for idx in sequence if idx != 0]\n", + " \"\"\" Converts a tokenized sequence back into readable text. \"\"\"\n", + " return \" \".join([tokenizer.index_word.get(idx, \"\") for idx in sequence if idx != 0])\n", "\n", - "reference = [sequence_to_text(question_test[0], tokenizer)]\n", - "candidate = sequence_to_text(np.argmax(pred_question[0], axis=-1), tokenizer)\n", - "bleu_score = nltk.translate.bleu_score.sentence_bleu(reference, candidate)\n", - "print(\"BLEU score for first test sample (question generation):\", bleu_score)\n" + "print(\"\\n=== Evaluation on Test Data ===\")\n", + "pred_question_test, pred_answer_test, pred_qtype_test = model.predict([context_test, question_test])\n", + "pred_qtype_labels_test = np.argmax(pred_qtype_test, axis=1)\n", + "\n", + "print(\"Classification Report for Question Type (Test Set):\")\n", + "print(classification_report(qtype_test, pred_qtype_labels_test))\n", + "print(\"Test Accuracy:\", accuracy_score(qtype_test, pred_qtype_labels_test))\n", + "print(\"Test Precision:\", precision_score(qtype_test, pred_qtype_labels_test, average='weighted'))\n", + "print(\"Test Recall:\", recall_score(qtype_test, pred_qtype_labels_test, average='weighted'))\n", + "\n", + "reference_question_test = [sequence_to_text(question_test[0], tokenizer)]\n", + "candidate_question_test = sequence_to_text(np.argmax(pred_question_test[0], axis=-1), tokenizer)\n", + "bleu_score_question_test = nltk.translate.bleu_score.sentence_bleu(reference_question_test, candidate_question_test)\n", + "print(\"BLEU Score for first test sample (question generation):\", bleu_score_question_test)\n", + "\n", + "reference_answer_test = [sequence_to_text(answer_test[0], tokenizer)]\n", + "candidate_answer_test = sequence_to_text(np.argmax(pred_answer_test[0], axis=-1), tokenizer)\n", + "bleu_score_answer_test = nltk.translate.bleu_score.sentence_bleu(reference_answer_test, candidate_answer_test)\n", + "print(\"BLEU Score for first test sample (answer generation):\", bleu_score_answer_test)\n", + "\n", + "print(\"\\n=== Evaluation on Validation Data ===\")\n", + "pred_question_val, pred_answer_val, pred_qtype_val = model.predict([context_val, question_val])\n", + "pred_qtype_labels_val = np.argmax(pred_qtype_val, axis=1)\n", + "\n", + "print(\"Classification Report for Question Type (Validation Set):\")\n", + "print(classification_report(qtype_val, pred_qtype_labels_val))\n", + "print(\"Validation Accuracy:\", accuracy_score(qtype_val, pred_qtype_labels_val))\n", + "print(\"Validation Precision:\", precision_score(qtype_val, pred_qtype_labels_val, average='weighted'))\n", + "print(\"Validation Recall:\", recall_score(qtype_val, pred_qtype_labels_val, average='weighted'))\n", + "\n", + "reference_question_val = [sequence_to_text(question_val[0], tokenizer)]\n", + "candidate_question_val = sequence_to_text(np.argmax(pred_question_val[0], axis=-1), tokenizer)\n", + "bleu_score_question_val = nltk.translate.bleu_score.sentence_bleu(reference_question_val, candidate_question_val)\n", + "print(\"BLEU Score for first validation sample (question generation):\", bleu_score_question_val)\n", + "\n", + "reference_answer_val = [sequence_to_text(answer_val[0], tokenizer)]\n", + "candidate_answer_val = sequence_to_text(np.argmax(pred_answer_val[0], axis=-1), tokenizer)\n", + "bleu_score_answer_val = nltk.translate.bleu_score.sentence_bleu(reference_answer_val, candidate_answer_val)\n", + "print(\"BLEU Score for first validation sample (answer generation):\", bleu_score_answer_val)\n" ] } ], diff --git a/uji.py b/uji.py new file mode 100644 index 0000000..aabe8c7 --- /dev/null +++ b/uji.py @@ -0,0 +1,163 @@ +import numpy as np +import pickle +import tensorflow as tf +from tensorflow.keras.preprocessing.sequence import pad_sequences +import nltk +import random +import string +import re +from nltk.tokenize import word_tokenize +from nltk.corpus import stopwords + +# Ensure NLTK resources are available +nltk.download("punkt") +nltk.download("stopwords") + + +class QuestionGenerator: + def __init__( + self, model_path="lstm_multi_output_model.keras", tokenizer_path="tokenizer.pkl" + ): + """ + Initializes the QuestionGenerator by loading the trained model and tokenizer. + """ + # Load trained model + self.model = tf.keras.models.load_model(model_path) + + # Load tokenizer + with open(tokenizer_path, "rb") as handle: + self.tokenizer = pickle.load(handle) + + # Define question type mapping + self.question_type_dict = { + 0: "fill_in_the_blank", + 1: "true_false", + 2: "multiple_choice", + } + + # Load Indonesian stopwords + self.stop_words = set(stopwords.words("indonesian")) + + # Custom word normalization dictionary + self.normalization_dict = { + "yg": "yang", + "gokil": "kocak", + "kalo": "kalau", + "gue": "saya", + "elo": "kamu", + "nih": "ini", + "trs": "terus", + "tdk": "tidak", + "gmna": "bagaimana", + "tp": "tapi", + "jd": "jadi", + "aja": "saja", + "krn": "karena", + "blm": "belum", + "dgn": "dengan", + "skrg": "sekarang", + "msh": "masih", + "lg": "lagi", + "sy": "saya", + "sm": "sama", + "bgt": "banget", + "dr": "dari", + "kpn": "kapan", + "hrs": "harus", + "cm": "cuma", + "sbnrnya": "sebenarnya", + } + + def preprocess_text(self, text): + """ + Preprocesses the input text by: + - Converting to lowercase + - Removing punctuation + - Tokenizing + - Normalizing words + - Removing stopwords + """ + text = text.lower() + text = text.translate( + str.maketrans("", "", string.punctuation) + ) # Remove punctuation + text = re.sub(r"\s+", " ", text).strip() # Remove extra spaces + tokens = word_tokenize(text) # Tokenization + tokens = [ + self.normalization_dict.get(word, word) for word in tokens + ] # Normalize words + tokens = [ + word for word in tokens if word not in self.stop_words + ] # Remove stopwords + return " ".join(tokens) + + def sequence_to_text(self, sequence): + """ + Converts a tokenized sequence back into readable text. + """ + return " ".join( + [ + self.tokenizer.index_word.get(idx, "") + for idx in sequence + if idx != 0 + ] + ) + + def generate_qa_from_paragraph(self, paragraph): + """ + Generates a question, answer, and question type from the given paragraph. + If it's a multiple-choice question, it also returns answer options. + """ + # Preprocess the input paragraph + processed_paragraph = self.preprocess_text(paragraph) + + # Convert text to sequence + input_seq = self.tokenizer.texts_to_sequences([processed_paragraph]) + input_seq = pad_sequences(input_seq, maxlen=100, padding="post") + + # Predict question, answer, and type + pred_question, pred_answer, pred_qtype = self.model.predict( + [input_seq, input_seq] + ) + + # Decode predictions + generated_question = self.sequence_to_text(np.argmax(pred_question[0], axis=-1)) + generated_answer = self.sequence_to_text(np.argmax(pred_answer[0], axis=-1)) + question_type_index = np.argmax(pred_qtype[0]) + generated_qtype = self.question_type_dict[question_type_index] + + # Handle multiple-choice options + options = None + if generated_qtype == "multiple_choice": + words = processed_paragraph.split() + random.shuffle(words) + distractors = [ + word for word in words if word.lower() != generated_answer.lower() + ] + options = [generated_answer] + distractors[:3] + random.shuffle(options) # Shuffle options + + # Return the generated data + return { + "generated_question": generated_question, + "generated_answer": generated_answer, + "question_type": generated_qtype, + "options": options if generated_qtype == "multiple_choice" else None, + } + + +# Initialize the question generator +qg = QuestionGenerator() + +# Example input paragraph +sample_paragraph = "Samudra Pasifik adalah yang terbesar dan terdalam di antara divisi samudra di Bumi. Samudra ini membentang dari Samudra Arktik di utara hingga Samudra Selatan di selatan dan berbatasan dengan Asia dan Australia di barat serta Amerika di timur." + +# Generate question, answer, and type +generated_result = qg.generate_qa_from_paragraph(sample_paragraph) + +# Print output +print("Generated Question:", generated_result["generated_question"]) +print("Generated Answer:", generated_result["generated_answer"]) +print("Question Type:", generated_result["question_type"]) +if generated_result["options"]: + print("Options:", generated_result["options"])