TIF_E41211115_lstm-quiz-gen.../question_generation/question_generation_model.i...

1293 lines
168 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": 75,
"id": "02cbdb19",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import json\n",
"import random\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 Model, load_model\n",
"from tensorflow.keras.layers import (\n",
" Input,\n",
" LSTM,\n",
" Dense,\n",
" Embedding,\n",
" Bidirectional,\n",
" Concatenate,\n",
" Dropout,\n",
")\n",
"from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\n",
"from sklearn.model_selection import train_test_split\n",
"import matplotlib.pyplot as plt\n",
"import re\n",
"from rouge_score import rouge_scorer\n",
"from nltk.translate.bleu_score import sentence_bleu"
]
},
{
"cell_type": "code",
"execution_count": 76,
"id": "f9c0af74",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"total question 931\n"
]
}
],
"source": [
"# Load data\n",
"with open(\"data_converted.json\", \"r\") as f:\n",
" data = json.load(f)\n",
"\n",
"\n",
"# Preprocessing function\n",
"def preprocess_text(text):\n",
" \"\"\"Melakukan preprocessing teks dasar\"\"\"\n",
" text = text.lower()\n",
" text = re.sub(r\"\\s+\", \" \", text).strip()\n",
" return text\n",
"\n",
"\n",
"# Persiapkan data untuk model prediksi pertanyaan\n",
"def prepare_question_prediction_data(data):\n",
" \"\"\"Siapkan data untuk model prediksi pertanyaan\"\"\"\n",
" contexts = []\n",
" tokens_list = []\n",
" ner_list = []\n",
" srl_list = []\n",
" questions = []\n",
" q_types = []\n",
"\n",
" for item in data:\n",
" \n",
" for qa in item[\"qas\"]:\n",
" if qa[\"question\"] == \"\":\n",
" continue\n",
" context = preprocess_text(item[\"context\"])\n",
" contexts.append(context)\n",
" token = [preprocess_text(token) for token in item[\"tokens\"]]\n",
" tokens_list.append(token)\n",
" ner_list.append(item[\"ner\"])\n",
" srl_list.append(item[\"srl\"])\n",
" questions.append(preprocess_text(qa[\"question\"]))\n",
" q_types.append(qa[\"type\"])\n",
" # Tidak mengambil jawaban (answer) sebagai input\n",
" print(\"total question \", len(questions))\n",
" return contexts, tokens_list, ner_list, srl_list, questions, q_types\n",
"\n",
"\n",
"contexts, tokens_list, ner_list, srl_list, questions, q_types = (\n",
" prepare_question_prediction_data(data)\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 77,
"id": "952f71da",
"metadata": {},
"outputs": [],
"source": [
"# Tokenizer untuk teks (context, question)\n",
"max_vocab_size = 10000\n",
"tokenizer = Tokenizer(num_words=max_vocab_size, oov_token=\"<OOV>\")\n",
"all_texts = contexts + questions + [\" \".join(item) for item in tokens_list]\n",
"tokenizer.fit_on_texts(all_texts)\n",
"vocab_size = len(tokenizer.word_index) + 1\n",
"\n",
"# Encoding untuk NER\n",
"ner_tokenizer = Tokenizer(oov_token=\"<OOV>\")\n",
"ner_tokenizer.fit_on_texts([\" \".join(ner) for ner in ner_list])\n",
"ner_vocab_size = len(ner_tokenizer.word_index) + 1\n",
"\n",
"# Encoding untuk SRL\n",
"srl_tokenizer = Tokenizer(oov_token=\"<OOV>\")\n",
"srl_tokenizer.fit_on_texts([\" \".join(srl) for srl in srl_list])\n",
"srl_vocab_size = len(srl_tokenizer.word_index) + 1\n",
"\n",
"# Encoding untuk tipe pertanyaan\n",
"q_type_tokenizer = Tokenizer()\n",
"q_type_tokenizer.fit_on_texts(q_types)\n",
"q_type_vocab_size = len(q_type_tokenizer.word_index) + 1\n",
"\n",
"\n",
"# Konversi token, ner, srl ke sequences\n",
"def tokens_to_sequences(tokens, ner, srl):\n",
" \"\"\"Konversi token, ner, dan srl ke sequences\"\"\"\n",
" token_seqs = [tokenizer.texts_to_sequences([\" \".join(t)])[0] for t in tokens]\n",
" ner_seqs = [ner_tokenizer.texts_to_sequences([\" \".join(n)])[0] for n in ner]\n",
" srl_seqs = [srl_tokenizer.texts_to_sequences([\" \".join(s)])[0] for s in srl]\n",
" return token_seqs, ner_seqs, srl_seqs\n",
"\n",
"\n",
"# Sequences\n",
"context_seqs = tokenizer.texts_to_sequences(contexts)\n",
"question_seqs = tokenizer.texts_to_sequences(questions)\n",
"token_seqs, ner_seqs, srl_seqs = tokens_to_sequences(tokens_list, ner_list, srl_list)\n",
"\n",
"# Menentukan panjang maksimum untuk padding\n",
"max_context_len = max([len(seq) for seq in context_seqs])\n",
"max_question_len = max([len(seq) for seq in question_seqs])\n",
"max_token_len = max([len(seq) for seq in token_seqs])\n",
"\n",
"\n",
"# Pad sequences untuk memastikan semua input sama panjang\n",
"def pad_all_sequences(context_seqs, token_seqs, ner_seqs, srl_seqs, question_seqs):\n",
" \"\"\"Padding semua sequences\"\"\"\n",
" context_padded = pad_sequences(context_seqs, maxlen=max_context_len, padding=\"post\")\n",
" token_padded = pad_sequences(token_seqs, maxlen=max_token_len, padding=\"post\")\n",
" ner_padded = pad_sequences(ner_seqs, maxlen=max_token_len, padding=\"post\")\n",
" srl_padded = pad_sequences(srl_seqs, maxlen=max_token_len, padding=\"post\")\n",
" question_padded = pad_sequences(\n",
" question_seqs, maxlen=max_question_len, padding=\"post\"\n",
" )\n",
" return (\n",
" context_padded,\n",
" token_padded,\n",
" ner_padded,\n",
" srl_padded,\n",
" question_padded,\n",
" )\n",
"\n",
"\n",
"# Encode tipe pertanyaan\n",
"q_type_indices = []\n",
"for q_type in q_types:\n",
" q_type_idx = q_type_tokenizer.word_index.get(q_type, 0)\n",
" q_type_indices.append(q_type_idx)\n",
"\n",
"# Konversi ke numpy array\n",
"q_type_indices = np.array(q_type_indices)\n",
"\n",
"# One-hot encode tipe pertanyaan\n",
"q_type_categorical = tf.keras.utils.to_categorical(\n",
" q_type_indices, num_classes=q_type_vocab_size\n",
")\n",
"\n",
"# Pad sequences\n",
"context_padded, token_padded, ner_padded, srl_padded, question_padded = (\n",
" pad_all_sequences(context_seqs, token_seqs, ner_seqs, srl_seqs, question_seqs)\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 78,
"id": "37ffc0e5",
"metadata": {},
"outputs": [],
"source": [
"# Split data menjadi train dan test sets\n",
"indices = list(range(len(context_padded)))\n",
"train_indices, test_indices = train_test_split(indices, test_size=0.2, random_state=42)\n",
"\n",
"\n",
"def get_subset(data, indices):\n",
" return np.array([data[i] for i in indices])\n",
"\n",
"\n",
"# Train data\n",
"train_context = get_subset(context_padded, train_indices)\n",
"train_token = get_subset(token_padded, train_indices)\n",
"train_ner = get_subset(ner_padded, train_indices)\n",
"train_srl = get_subset(srl_padded, train_indices)\n",
"train_q_type = get_subset(q_type_categorical, train_indices)\n",
"train_question = get_subset(question_padded, train_indices)\n",
"\n",
"# Test data\n",
"test_context = get_subset(context_padded, test_indices)\n",
"test_token = get_subset(token_padded, test_indices)\n",
"test_ner = get_subset(ner_padded, test_indices)\n",
"test_srl = get_subset(srl_padded, test_indices)\n",
"test_q_type = get_subset(q_type_categorical, test_indices)\n",
"test_question = get_subset(question_padded, test_indices)"
]
},
{
"cell_type": "code",
"execution_count": 79,
"id": "df580682",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"functional_8\"</span>\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1mModel: \"functional_8\"\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n",
"┃<span style=\"font-weight: bold\"> Layer (type) </span>┃<span style=\"font-weight: bold\"> Output Shape </span>┃<span style=\"font-weight: bold\"> Param # </span>┃<span style=\"font-weight: bold\"> Connected to </span>┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n",
"│ context_input │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">49</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ - │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ token_input │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">49</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ - │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ ner_input │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">49</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ - │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ srl_input │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">49</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ - │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ text_embedding │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">49</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">100</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">151,800</span> │ context_input[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]… │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Embedding</span>) │ │ │ token_input[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ ner_embedding │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">49</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">50</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,700</span> │ ner_input[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Embedding</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ srl_embedding │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">49</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">50</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">1,350</span> │ srl_input[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Embedding</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ bidirectional_16 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">49</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">234,496</span> │ text_embedding[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>… │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Bidirectional</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ token_features │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">49</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">200</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ text_embedding[<span style=\"color: #00af00; text-decoration-color: #00af00\">1</span>… │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Concatenate</span>) │ │ │ ner_embedding[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]… │\n",
"│ │ │ │ srl_embedding[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]… │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ context_attention │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">49</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ bidirectional_16… │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Attention</span>) │ │ │ bidirectional_16… │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ bidirectional_17 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">49</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">336,896</span> │ token_features[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>… │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Bidirectional</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ context_att_pool │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ context_attentio… │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">GlobalMaxPooling1…</span> │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ token_pool │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ bidirectional_17… │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">GlobalMaxPooling1…</span> │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ q_type_input │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ - │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ all_features │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">517</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ context_att_pool… │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Concatenate</span>) │ │ │ token_pool[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>], │\n",
"│ │ │ │ q_type_input[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ dense_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">265,216</span> │ all_features[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ dropout_16 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ dense_1[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ dense_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">131,328</span> │ dropout_16[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ dropout_17 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ dense_2[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ decoder_input │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">65,792</span> │ dropout_17[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ repeat_vector_8 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">14</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ decoder_input[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]… │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">RepeatVector</span>) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ decoder_lstm (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">LSTM</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">14</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">525,312</span> │ repeat_vector_8[<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ time_distributed_8 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">14</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1518</span>) │ <span style=\"color: #00af00; text-decoration-color: #00af00\">390,126</span> │ decoder_lstm[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
"│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">TimeDistributed</span>) │ │ │ │\n",
"└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n",
"</pre>\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",
"│ context_input │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m49\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ - │\n",
"│ (\u001b[38;5;33mInputLayer\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ token_input │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m49\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ - │\n",
"│ (\u001b[38;5;33mInputLayer\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ ner_input │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m49\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ - │\n",
"│ (\u001b[38;5;33mInputLayer\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ srl_input │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m49\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ - │\n",
"│ (\u001b[38;5;33mInputLayer\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ text_embedding │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m49\u001b[0m, \u001b[38;5;34m100\u001b[0m) │ \u001b[38;5;34m151,800\u001b[0m │ context_input[\u001b[38;5;34m0\u001b[0m]… │\n",
"│ (\u001b[38;5;33mEmbedding\u001b[0m) │ │ │ token_input[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ ner_embedding │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m49\u001b[0m, \u001b[38;5;34m50\u001b[0m) │ \u001b[38;5;34m1,700\u001b[0m │ ner_input[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
"│ (\u001b[38;5;33mEmbedding\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ srl_embedding │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m49\u001b[0m, \u001b[38;5;34m50\u001b[0m) │ \u001b[38;5;34m1,350\u001b[0m │ srl_input[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
"│ (\u001b[38;5;33mEmbedding\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ bidirectional_16 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m49\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m234,496\u001b[0m │ text_embedding[\u001b[38;5;34m0\u001b[0m… │\n",
"│ (\u001b[38;5;33mBidirectional\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ token_features │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m49\u001b[0m, \u001b[38;5;34m200\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ text_embedding[\u001b[38;5;34m1\u001b[0m… │\n",
"│ (\u001b[38;5;33mConcatenate\u001b[0m) │ │ │ ner_embedding[\u001b[38;5;34m0\u001b[0m]… │\n",
"│ │ │ │ srl_embedding[\u001b[38;5;34m0\u001b[0m]… │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ context_attention │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m49\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ bidirectional_16… │\n",
"│ (\u001b[38;5;33mAttention\u001b[0m) │ │ │ bidirectional_16… │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ bidirectional_17 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m49\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m336,896\u001b[0m │ token_features[\u001b[38;5;34m0\u001b[0m… │\n",
"│ (\u001b[38;5;33mBidirectional\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ context_att_pool │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ context_attentio… │\n",
"│ (\u001b[38;5;33mGlobalMaxPooling1…\u001b[0m │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ token_pool │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ bidirectional_17… │\n",
"│ (\u001b[38;5;33mGlobalMaxPooling1…\u001b[0m │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ q_type_input │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ - │\n",
"│ (\u001b[38;5;33mInputLayer\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ all_features │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m517\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ context_att_pool… │\n",
"│ (\u001b[38;5;33mConcatenate\u001b[0m) │ │ │ token_pool[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m], │\n",
"│ │ │ │ q_type_input[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ dense_1 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m265,216\u001b[0m │ all_features[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ dropout_16 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m512\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ dense_1[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
"│ (\u001b[38;5;33mDropout\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ dense_2 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m131,328\u001b[0m │ dropout_16[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ dropout_17 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ dense_2[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
"│ (\u001b[38;5;33mDropout\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ decoder_input │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m65,792\u001b[0m │ dropout_17[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
"│ (\u001b[38;5;33mDense\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ repeat_vector_8 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m14\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │ decoder_input[\u001b[38;5;34m0\u001b[0m]… │\n",
"│ (\u001b[38;5;33mRepeatVector\u001b[0m) │ │ │ │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ decoder_lstm (\u001b[38;5;33mLSTM\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m14\u001b[0m, \u001b[38;5;34m256\u001b[0m) │ \u001b[38;5;34m525,312\u001b[0m │ repeat_vector_8[\u001b[38;5;34m…\u001b[0m │\n",
"├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
"│ time_distributed_8 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m14\u001b[0m, \u001b[38;5;34m1518\u001b[0m) │ \u001b[38;5;34m390,126\u001b[0m │ decoder_lstm[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n",
"│ (\u001b[38;5;33mTimeDistributed\u001b[0m) │ │ │ │\n",
"└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">2,104,016</span> (8.03 MB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m2,104,016\u001b[0m (8.03 MB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">2,104,016</span> (8.03 MB)\n",
"</pre>\n"
],
"text/plain": [
"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m2,104,016\u001b[0m (8.03 MB)\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
"</pre>\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"
}
],
"source": [
"embedding_dim = 100\n",
"lstm_units = 128\n",
"ner_embedding_dim = 50\n",
"srl_embedding_dim = 50\n",
"dropout_rate = 0.3\n",
"\n",
"\n",
"# Function untuk membuat model prediksi pertanyaan\n",
"def create_question_prediction_model():\n",
" # Input layers\n",
" context_input = Input(shape=(max_context_len,), name=\"context_input\")\n",
" token_input = Input(shape=(max_token_len,), name=\"token_input\")\n",
" ner_input = Input(shape=(max_token_len,), name=\"ner_input\")\n",
" srl_input = Input(shape=(max_token_len,), name=\"srl_input\")\n",
" q_type_input = Input(shape=(q_type_vocab_size,), name=\"q_type_input\")\n",
"\n",
" # Shared embedding layer for text\n",
" text_embedding = Embedding(vocab_size, embedding_dim, name=\"text_embedding\")\n",
"\n",
" # Embedding untuk NER dan SRL\n",
" ner_embedding = Embedding(ner_vocab_size, ner_embedding_dim, name=\"ner_embedding\")(\n",
" ner_input\n",
" )\n",
" srl_embedding = Embedding(srl_vocab_size, srl_embedding_dim, name=\"srl_embedding\")(\n",
" srl_input\n",
" )\n",
"\n",
" # Apply embeddings\n",
" context_embed = text_embedding(context_input)\n",
" token_embed = text_embedding(token_input)\n",
"\n",
" # Bi-directional LSTM untuk context dan token-level features\n",
" context_lstm = Bidirectional(\n",
" LSTM(lstm_units, return_sequences=True, name=\"context_lstm\")\n",
" )(context_embed)\n",
"\n",
" # Concat token features (tokens, NER, SRL)\n",
" token_features = Concatenate(name=\"token_features\")(\n",
" [token_embed, ner_embedding, srl_embedding]\n",
" )\n",
" token_lstm = Bidirectional(\n",
" LSTM(lstm_units, return_sequences=True, name=\"token_lstm\")\n",
" )(token_features)\n",
"\n",
" # Apply attention to context LSTM\n",
" context_attention = tf.keras.layers.Attention(name=\"context_attention\")(\n",
" [context_lstm, context_lstm]\n",
" )\n",
"\n",
" # Pool attention outputs\n",
" context_att_pool = tf.keras.layers.GlobalMaxPooling1D(name=\"context_att_pool\")(\n",
" context_attention\n",
" )\n",
" token_pool = tf.keras.layers.GlobalMaxPooling1D(name=\"token_pool\")(token_lstm)\n",
"\n",
" # Concat all features (tidak ada answer feature)\n",
" all_features = Concatenate(name=\"all_features\")(\n",
" [context_att_pool, token_pool, q_type_input]\n",
" )\n",
"\n",
" # Dense layers with expanded capacity for sequence generation\n",
" x = Dense(512, activation=\"relu\", name=\"dense_1\")(all_features)\n",
" x = Dropout(dropout_rate)(x)\n",
" x = Dense(256, activation=\"relu\", name=\"dense_2\")(x)\n",
" x = Dropout(dropout_rate)(x)\n",
"\n",
" # Reshape untuk sequence decoder\n",
" decoder_dense = Dense(vocab_size, activation=\"softmax\", name=\"decoder_dense\")\n",
"\n",
" # Many-to-many architecture for sequence generation\n",
" # Decoder LSTM\n",
" decoder_lstm = LSTM(lstm_units * 2, return_sequences=True, name=\"decoder_lstm\")\n",
"\n",
" # Reshape untuk input ke decoder\n",
" decoder_input = Dense(lstm_units * 2, activation=\"relu\", name=\"decoder_input\")(x)\n",
"\n",
" # Decoder sequence with teacher forcing\n",
" # Expand dimensionality to match expected sequence length\n",
" repeated_vector = tf.keras.layers.RepeatVector(max_question_len)(decoder_input)\n",
"\n",
" # Process through decoder LSTM\n",
" decoder_outputs = decoder_lstm(repeated_vector)\n",
"\n",
" # Apply dense layer to each timestep\n",
" question_output_seq = tf.keras.layers.TimeDistributed(decoder_dense)(\n",
" decoder_outputs\n",
" )\n",
"\n",
" # Create model\n",
" model = Model(\n",
" inputs=[\n",
" context_input,\n",
" token_input,\n",
" ner_input,\n",
" srl_input,\n",
" q_type_input,\n",
" ],\n",
" outputs=question_output_seq,\n",
" )\n",
"\n",
" # Compile model with categorical crossentropy for sequence prediction\n",
" model.compile(\n",
" optimizer=\"adam\", loss=\"sparse_categorical_crossentropy\", metrics=[\"accuracy\"]\n",
" )\n",
"\n",
" return model\n",
"\n",
"\n",
"# Buat model\n",
"model = create_question_prediction_model()\n",
"model.summary()"
]
},
{
"cell_type": "code",
"execution_count": 80,
"id": "6ba404db",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 36ms/step - accuracy: 0.5309 - loss: 4.2503 - val_accuracy: 0.5642 - val_loss: 3.1908\n",
"Epoch 2/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 29ms/step - accuracy: 0.5667 - loss: 2.9923 - val_accuracy: 0.5699 - val_loss: 2.9613\n",
"Epoch 3/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 30ms/step - accuracy: 0.5789 - loss: 2.7875 - val_accuracy: 0.5733 - val_loss: 2.9850\n",
"Epoch 4/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 30ms/step - accuracy: 0.5751 - loss: 2.7333 - val_accuracy: 0.5810 - val_loss: 2.8962\n",
"Epoch 5/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 30ms/step - accuracy: 0.5919 - loss: 2.5382 - val_accuracy: 0.5791 - val_loss: 2.8806\n",
"Epoch 6/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 29ms/step - accuracy: 0.5976 - loss: 2.4694 - val_accuracy: 0.5837 - val_loss: 2.8012\n",
"Epoch 7/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 30ms/step - accuracy: 0.5988 - loss: 2.3733 - val_accuracy: 0.5924 - val_loss: 2.7668\n",
"Epoch 8/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 33ms/step - accuracy: 0.5963 - loss: 2.3688 - val_accuracy: 0.5913 - val_loss: 2.7328\n",
"Epoch 9/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 32ms/step - accuracy: 0.5942 - loss: 2.2982 - val_accuracy: 0.5921 - val_loss: 2.6984\n",
"Epoch 10/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 33ms/step - accuracy: 0.6094 - loss: 2.1666 - val_accuracy: 0.6005 - val_loss: 2.6723\n",
"Epoch 11/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 30ms/step - accuracy: 0.6103 - loss: 2.1201 - val_accuracy: 0.6028 - val_loss: 2.6278\n",
"Epoch 12/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 30ms/step - accuracy: 0.6120 - loss: 2.1040 - val_accuracy: 0.6085 - val_loss: 2.6569\n",
"Epoch 13/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 30ms/step - accuracy: 0.6244 - loss: 1.9767 - val_accuracy: 0.6089 - val_loss: 2.6050\n",
"Epoch 14/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 30ms/step - accuracy: 0.6330 - loss: 1.8633 - val_accuracy: 0.6154 - val_loss: 2.5609\n",
"Epoch 15/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 31ms/step - accuracy: 0.6275 - loss: 1.8729 - val_accuracy: 0.6161 - val_loss: 2.5589\n",
"Epoch 16/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 31ms/step - accuracy: 0.6261 - loss: 1.8763 - val_accuracy: 0.6131 - val_loss: 2.5505\n",
"Epoch 17/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 41ms/step - accuracy: 0.6298 - loss: 1.8188 - val_accuracy: 0.6092 - val_loss: 2.5473\n",
"Epoch 18/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 43ms/step - accuracy: 0.6330 - loss: 1.7953 - val_accuracy: 0.6161 - val_loss: 2.5135\n",
"Epoch 19/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 43ms/step - accuracy: 0.6389 - loss: 1.7240 - val_accuracy: 0.6165 - val_loss: 2.5359\n",
"Epoch 20/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 42ms/step - accuracy: 0.6245 - loss: 1.7859 - val_accuracy: 0.6154 - val_loss: 2.5241\n",
"Epoch 21/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 43ms/step - accuracy: 0.6350 - loss: 1.7127 - val_accuracy: 0.6134 - val_loss: 2.5240\n",
"Epoch 22/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 42ms/step - accuracy: 0.6457 - loss: 1.6129 - val_accuracy: 0.6257 - val_loss: 2.5314\n",
"Epoch 23/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 42ms/step - accuracy: 0.6354 - loss: 1.6795 - val_accuracy: 0.6222 - val_loss: 2.4927\n",
"Epoch 24/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 42ms/step - accuracy: 0.6323 - loss: 1.6659 - val_accuracy: 0.6196 - val_loss: 2.5081\n",
"Epoch 25/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 42ms/step - accuracy: 0.6436 - loss: 1.5886 - val_accuracy: 0.6230 - val_loss: 2.5029\n",
"Epoch 26/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 32ms/step - accuracy: 0.6432 - loss: 1.5517 - val_accuracy: 0.6241 - val_loss: 2.4935\n",
"Epoch 27/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 32ms/step - accuracy: 0.6501 - loss: 1.5298 - val_accuracy: 0.6192 - val_loss: 2.5179\n",
"Epoch 28/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 33ms/step - accuracy: 0.6434 - loss: 1.5379 - val_accuracy: 0.6215 - val_loss: 2.5084\n",
"Epoch 29/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 33ms/step - accuracy: 0.6515 - loss: 1.4863 - val_accuracy: 0.6241 - val_loss: 2.5016\n",
"Epoch 30/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 35ms/step - accuracy: 0.6707 - loss: 1.3811 - val_accuracy: 0.6283 - val_loss: 2.4840\n",
"Epoch 31/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 39ms/step - accuracy: 0.6602 - loss: 1.4188 - val_accuracy: 0.6234 - val_loss: 2.4991\n",
"Epoch 32/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 42ms/step - accuracy: 0.6582 - loss: 1.3886 - val_accuracy: 0.6280 - val_loss: 2.4856\n",
"Epoch 33/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 42ms/step - accuracy: 0.6656 - loss: 1.3863 - val_accuracy: 0.6245 - val_loss: 2.4951\n",
"Epoch 34/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 41ms/step - accuracy: 0.6665 - loss: 1.3715 - val_accuracy: 0.6287 - val_loss: 2.4736\n",
"Epoch 35/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 43ms/step - accuracy: 0.6527 - loss: 1.4147 - val_accuracy: 0.6218 - val_loss: 2.4797\n",
"Epoch 36/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 42ms/step - accuracy: 0.6775 - loss: 1.2971 - val_accuracy: 0.6230 - val_loss: 2.4879\n",
"Epoch 37/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 33ms/step - accuracy: 0.6693 - loss: 1.2954 - val_accuracy: 0.6341 - val_loss: 2.4773\n",
"Epoch 38/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 32ms/step - accuracy: 0.6560 - loss: 1.3712 - val_accuracy: 0.6268 - val_loss: 2.5058\n",
"Epoch 39/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 33ms/step - accuracy: 0.6826 - loss: 1.2517 - val_accuracy: 0.6287 - val_loss: 2.4729\n",
"Epoch 40/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 33ms/step - accuracy: 0.6666 - loss: 1.2982 - val_accuracy: 0.6249 - val_loss: 2.4828\n",
"Epoch 41/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 36ms/step - accuracy: 0.6816 - loss: 1.2239 - val_accuracy: 0.6306 - val_loss: 2.4720\n",
"Epoch 42/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 40ms/step - accuracy: 0.6769 - loss: 1.2318 - val_accuracy: 0.6261 - val_loss: 2.5146\n",
"Epoch 43/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 42ms/step - accuracy: 0.6771 - loss: 1.2312 - val_accuracy: 0.6253 - val_loss: 2.4932\n",
"Epoch 44/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 42ms/step - accuracy: 0.6798 - loss: 1.2397 - val_accuracy: 0.6257 - val_loss: 2.4925\n",
"Epoch 45/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 43ms/step - accuracy: 0.6823 - loss: 1.2102 - val_accuracy: 0.6238 - val_loss: 2.5187\n",
"Epoch 46/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 43ms/step - accuracy: 0.6820 - loss: 1.2039 - val_accuracy: 0.6295 - val_loss: 2.4984\n",
"Epoch 47/50\n",
"\u001b[1m93/93\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 43ms/step - accuracy: 0.6874 - loss: 1.1845 - val_accuracy: 0.6318 - val_loss: 2.4856\n",
"Epoch 47: early stopping\n"
]
}
],
"source": [
"checkpoint = ModelCheckpoint(\n",
" \"question_prediction_model.h5\",\n",
" monitor=\"val_accuracy\",\n",
" save_best_only=True,\n",
" verbose=1,\n",
")\n",
"\n",
"early_stop = EarlyStopping(monitor=\"val_accuracy\", patience=10, verbose=1)\n",
"\n",
"# Reshaping question data for sequence-to-sequence training\n",
"# We need to reshape to (samples, max_question_len, 1) for sparse categorical crossentropy\n",
"train_question_target = np.expand_dims(train_question, -1)\n",
"test_question_target = np.expand_dims(test_question, -1)\n",
"\n",
"# Training parameters\n",
"batch_size = 8\n",
"epochs = 50\n",
"\n",
"# Train model\n",
"history = model.fit(\n",
" [train_context, train_token, train_ner, train_srl, train_q_type],\n",
" train_question_target,\n",
" batch_size=batch_size,\n",
" epochs=epochs,\n",
" validation_data=(\n",
" [test_context, test_token, test_ner, test_srl, test_q_type],\n",
" test_question_target,\n",
" ),\n",
" callbacks=[\n",
" # checkpoint,\n",
" early_stop,\n",
" ],\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 81,
"id": "184209bc",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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NZMnTwbg2Wef5eKLL6Z9+/YUFhby4osvcvjwYe6+++7acz766KOMGjWKAQMGcOmll7Jw4UI+/fRTli9fbtp9ioiIiIiIiIjId0wvSo0aNYq8vDyefPJJsrOz6dGjBwsXLqwd/DwzMxOr9bsOXSdPnuSee+4hOzubwMBAkpOTWb16dZ3H9a6//nqmTp3K5MmTeeihh+jYsSMffvgh/fv3N+UeRURERERERESkLothGIbZQbia4uJiAgICKCoq0qN8IiIiUofyhBr6HEREROSH1DdPMHVMKRERERERERERaZlMf3zPFX3beay4uNjsUERERMTFfJsftPTO5sqXRERE5IfUN19SUeocSkpKAIiJiTE7FBEREXFRJSUlBAQEmB2GaZQviYiIyE/5qXxJY0qdg9Pp5Pjx4/j5+WGxWBr8/MXFxcTExHDkyBGNweBi1DauS23jutQ2rktt0zgMw6CkpISoqKg6k7G0NMqXWi61jetS27gutY3rUts0jvrmS+opdQ5Wq5Xo6OhGv46/v79+6V2U2sZ1qW1cl9rGdaltGl5L7iH1LeVLorZxXWob16W2cV1qm4ZXn3yp5X69JyIiIiIiIiIiplFRSkREREREREREmpyKUiaw2+089dRT2O12s0OR/6G2cV1qG9eltnFdahtpzvT767rUNq5LbeO61DauS21jLg10LiIiIiIiIiIiTU49pUREREREREREpMmpKCUiIiIiIiIiIk1ORSkREREREREREWlyKko1sddee402bdrg6elJnz59WL9+vdkhtUgrVqzgmmuuISoqCovFwvz58+tsNwyDJ598ksjISLy8vBgyZAh79+41Ld6WYvLkyfTq1Qs/Pz/CwsIYMWIEGRkZdfYpLy9n/PjxBAcH4+vry8iRI8nJyTEt5pZkypQpdO/eHX9/f/z9/UlNTeWLL76o3a62cQ0vvPACFouFhx9+uHad2kaaG+VLrkH5kmtSvuTalC81D8qXXIeKUk1o9uzZTJw4kaeeeorNmzeTlJTEsGHDyM3NNTu0FqesrIykpCRee+21c27/61//yr/+9S+mTp3KunXr8PHxYdiwYZSXlzd5rC1JWloa48ePZ+3atSxevJiqqiouv/xyysrKavd55JFH+PTTT5kzZw5paWkcP36cG264wdS4W4ro6GheeOEFNm3axMaNG7nsssu47rrr2LlzJ6htXMKGDRuYNm0a3bt3r7NebSPNifIl16F8yTUpX3Jtypdcn/IlF2NIk+ndu7cxfvz42vcOh8OIiooyJk+ebGpcLR1gzJs3r/a90+k0IiIijBdffLF2XWFhoWG3242ZM2eaFGXLlJubawBGWlqaYZxpB3d3d2POnDm1+6SnpxuAsWbNGhMjbbkCAwONt956S23jAkpKSoyEhARj8eLFxsCBA40JEyYYhv67kWZI+ZJrUr7kupQvuT7lS65D+ZLrUU+pJlJZWcmmTZsYMmRI7Tqr1cqQIUNYs2aNqbFJXQcPHiQ7O7tOWwUEBNCnTx+1VRMrKioCICgoCIBNmzZRVVVVp206depEbGys2qaJORwOZs2aRVlZGampqWobFzB+/HiuuuqqOm2A/ruRZkb5UvOhfMl1KF9yXcqXXI/yJddjMzuAliI/Px+Hw0F4eHid9eHh4ezevdu0uORs2dnZcKZtvi88PLx2mzQ+p9PJww8/TL9+/ejatSucaRsPDw9atWpVZ1+1TdPZvn07qamplJeX4+vry7x580hMTGTLli1qGxPNmjWLzZs3s2HDhrO26b8baU6ULzUfypdcg/Il16R8yTUpX3JNKkqJiEsaP348O3bs4OuvvzY7FPmejh07smXLFoqKipg7dy5jxowhLS3N7LBatCNHjjBhwgQWL16Mp6en2eGIiEgTUr7kmpQvuR7lS65Lj+81kZCQENzc3M4avT8nJ4eIiAjT4pKzfdseaivzPPDAA3z22WcsW7aM6Ojo2vURERFUVlZSWFhYZ3+1TdPx8PCgffv2JCcnM3nyZJKSkvjnP/+ptjHRpk2byM3NpWfPnthsNmw2G2lpafzrX//CZrMRHh6utpFmQ/lS86F8yXzKl1yX8iXXo3zJdako1UQ8PDxITk5myZIlteucTidLliwhNTXV1Nikrvj4eCIiIuq0VXFxMevWrVNbNTLDMHjggQeYN28eS5cuJT4+vs725ORk3N3d67RNRkYGmZmZahuTOJ1OKioq1DYmGjx4MNu3b2fLli21S0pKCqNHj659rbaR5kL5UvOhfMk8ypeaH+VL5lO+5Lr0+F4TmjhxImPGjCElJYXevXvz8ssvU1ZWxh133GF2aC1OaWkp+/btq31/8OBBtmzZQlBQELGxsTz88MP86U9/IiEhgfj4eJ544gmioqIYMWKEqXFf6MaPH8+MGTP4+OOP8fPzq31+OyAgAC8vLwICArjrrruYOHEiQUFB+Pv78+CDD5KamsrFF19sdvgXvEmTJjF8+HBiY2MpKSlhxowZLF++nC+//FJtYyI/P7/acUS+5ePjQ3BwcO16tY00J8qXXIfyJdekfMm1KV9yTcqXXJjZ0/+1NK+88ooRGxtreHh4GL179zbWrl1rdkgt0rJlywzgrGXMmDGGcWaa4yeeeMIIDw837Ha7MXjwYCMjI8PssC9452oTwHj77bdr9zl9+rQxbtw4IzAw0PD29jauv/56Iysry9S4W4o777zTiIuLMzw8PIzQ0FBj8ODBxqJFi2q3q21cx/enODbUNtIMKV9yDcqXXJPyJdemfKn5UL7kGixGzT9sIiIiIiIiIiIiTUZjSomIiIiIiIiISJNTUUpERERERERERJqcilIiIiIiIiIiItLkVJQSEREREREREZEmp6KUiIiIiIiIiIg0ORWlRERERERERESkyakoJSIiIiIiIiIiTU5FKRERERERERERaXIqSomINBKLxcL8+fPNDkNERETEZSlfEmnZVJQSkQvS7bffjsViOWu54oorzA5NRERExCUoXxIRs9nMDkBEpLFcccUVvP3223XW2e120+IRERERcTXKl0TETOopJSIXLLvdTkRERJ0lMDAQznQVnzJlCsOHD8fLy4u2bdsyd+7cOsdv376dyy67DC8vL4KDg7n33nspLS2ts8/06dPp0qULdrudyMhIHnjggTrb8/Pzuf766/H29iYhIYFPPvmkCe5cREREpH6UL4mImVSUEpEW64knnmDkyJFs3bqV0aNHc/PNN5Oeng5AWVkZw4YNIzAwkA0bNjBnzhy++uqrOknUlClTGD9+PPfeey/bt2/nk08+oX379nWu8cwzz3DTTTexbds2rrzySkaPHk1BQUGT36uIiIjIz6F8SUQalSEicgEaM2aM4ebmZvj4+NRZ/vznPxuGYRiAMXbs2DrH9OnTx7j//vsNwzCMN954wwgMDDRKS0trty9YsMCwWq1Gdna2YRiGERUVZTz++OM/GANg/PGPf6x9X1paagDGF1980eD3KyIiInK+lC+JiNk0ppSIXLAuvfRSpkyZUmddUFBQ7evU1NQ621JTU9myZQsA6enpJCUl4ePjU7u9X79+OJ1OMjIysFgsHD9+nMGDB/9oDN27d6997ePjg7+/P7m5ub/43kREREQagvIlETGTilIicsHy8fE5q3t4Q/Hy8qrXfu7u7nXeWywWnE5no8QkIiIicr6UL4mImTSmlIi0WGvXrj3rfefOnQHo3LkzW7dupaysrHb7qlWrsFqtdOzYET8/P9q0acOSJUuaPG4RERGRpqJ8SUQak3pKicgFq6Kiguzs7DrrbDYbISEhAMyZM4eUlBT69+/Pf/7zH9avX8+///1vAEaPHs1TTz3FmDFjePrpp8nLy+PBBx/k1ltvJTw8HICnn36asWPHEhYWxvDhwykpKWHVqlU8+OCDJtytiIiIyPlTviQiZlJRSkQuWAsXLiQyMrLOuo4dO7J79244M9PLrFmzGDduHJGRkcycOZPExEQAvL29+fLLL5kwYQK9evXC29ubkSNH8tJLL9Wea8yYMZSXl/OPf/yD3/3ud4SEhPCrX/2qie9SRERE5OdTviQiZrIYNTMeiIi0KBaLhXnz5jFixAizQxERERFxScqXRKSxaUwpERERERERERFpcipKiYiIiIiIiIhIk9PjeyIiIiIiIiIi0uTUU0pERERERERERJqcilIiIiIiIiIiItLkVJQSEREREREREZEmp6KUiIiIiIiIiIg0ORWlRERERERERESkyakoJSIiIiIiIiIiTU5FKRERERERERERaXIqSomIiIiIiIiISJNTUUpERERERERERJrc/wOVnt/28zF8VgAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 1200x400 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n"
]
}
],
"source": [
"# Plot training history\n",
"plt.figure(figsize=(12, 4))\n",
"plt.subplot(1, 2, 1)\n",
"plt.plot(history.history[\"accuracy\"])\n",
"plt.plot(history.history[\"val_accuracy\"])\n",
"plt.title(\"Model Accuracy\")\n",
"plt.ylabel(\"Accuracy\")\n",
"plt.xlabel(\"Epoch\")\n",
"plt.legend([\"Train\", \"Validation\"], loc=\"upper left\")\n",
"\n",
"plt.subplot(1, 2, 2)\n",
"plt.plot(history.history[\"loss\"])\n",
"plt.plot(history.history[\"val_loss\"])\n",
"plt.title(\"Model Loss\")\n",
"plt.ylabel(\"Loss\")\n",
"plt.xlabel(\"Epoch\")\n",
"plt.legend([\"Train\", \"Validation\"], loc=\"upper left\")\n",
"plt.tight_layout()\n",
"plt.savefig(\"question_prediction_training_history.png\")\n",
"plt.show()\n",
"\n",
"# Simpan model dan tokenizer\n",
"model.save(\"question_prediction_model_final.h5\")\n",
"\n",
"# Simpan tokenizer\n",
"tokenizer_data = {\n",
" \"word_tokenizer\": tokenizer.to_json(),\n",
" \"ner_tokenizer\": ner_tokenizer.to_json(),\n",
" \"srl_tokenizer\": srl_tokenizer.to_json(),\n",
" \"q_type_tokenizer\": q_type_tokenizer.to_json(),\n",
" \"max_context_len\": max_context_len,\n",
" \"max_question_len\": max_question_len,\n",
" \"max_token_len\": max_token_len,\n",
"}\n",
"\n",
"with open(\"question_prediction_tokenizers.json\", \"w\") as f:\n",
" json.dump(tokenizer_data, f)"
]
},
{
"cell_type": "code",
"execution_count": 82,
"id": "71ec455a",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING:absl:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"kaliamt aktual ['para', 'brahmana', 'mendirikan', 'sebuah', 'candi', 'sebagai', 'peringatan', 'upacara', 'kurban.']\n",
"kaliamt prediksi ['kali', 'ini', 'sebagai', 'untuk', 'di', 'desa', 'bolak', 'hilir']\n",
"kaliamt aktual ['di', 'negara', 'mana', 'terletak', 'patung', 'yesus', 'penebus?']\n",
"kaliamt prediksi ['keajaiban', 'dunia', 'apa', 'yang', 'berada', 'di']\n",
"kaliamt aktual ['kerajaan', 'banten', 'berdiri', 'pada', 'tahun', '___?']\n",
"kaliamt prediksi ['kerajaan', 'berdiri', 'berdiri', 'pada', 'tahun']\n",
"kaliamt aktual ['siapa', 'pendiri', 'putri', 'mardika', '___']\n",
"kaliamt prediksi ['kapan', 'pendiri', 'utomo', 'didirikan']\n",
"kaliamt aktual ['pada', 'pelayarannya,', 'para', 'pedagang', 'singgah', 'terlebih', 'dahulu', 'di', 'kutai.']\n",
"kaliamt prediksi ['perubahan', 'tarumanegara', 'sebagai', 'yang', 'di', 'di', 'di', 'di', 'di']\n",
"kaliamt aktual ['air', 'mendidih', 'pada', 'suhu', '90', 'derajat', 'celsius', '___']\n",
"kaliamt prediksi ['vincent', 'einstein', 'secara', 'memotong', 'pada', 'ke', '5']\n",
"kaliamt aktual ['abdul', 'muis', 'lahir', 'di', '___']\n",
"kaliamt prediksi ['mohammad', 'muis', 'lahir', 'tanggal']\n",
"kaliamt aktual ['gunung', 'everest', 'memiliki', 'ketinggian', '9000', 'meter', '___']\n",
"kaliamt prediksi ['raja', 'yang', 'memiliki', 'ketinggian', 'isaac']\n",
"kaliamt aktual ['kapan', 'kerajaan', 'kutai', 'mengalami', 'masa', 'keemasan', '___']\n",
"kaliamt prediksi ['siapa', 'apa', 'komunis']\n",
"kaliamt aktual ['benda', 'apa', 'saja', 'yang', 'dapat', 'ditarik', 'oleh', 'magnet', '___']\n",
"kaliamt prediksi ['siapa', 'yang', 'yang', 'ditemukan', 'dan']\n",
"kaliamt aktual ['kerajaan', 'tarumanagara', 'berdiri', 'pada', 'tahun', '___?']\n",
"kaliamt prediksi ['kerajaan', 'berdiri', 'berdiri', 'pada', 'tahun']\n",
"kaliamt aktual ['sultan', 'mahmud', 'badaruddin', 'ii', 'lahir', 'di', '___']\n",
"kaliamt prediksi ['i', 'mahmud', 'badaruddin', 'ii', 'lahir', 'tanggal']\n",
"kaliamt aktual ['___', 'menghadiri', 'pameran', 'teknologi', 'di', 'makassar']\n",
"kaliamt prediksi ['menghadiri', 'konser', 'amal', 'di', 'yogyakarta']\n",
"kaliamt aktual ['pangeran', 'diponegoro', 'lahir', 'pada', '___']\n",
"kaliamt prediksi ['mohammad', 'hatta', 'lahir', 'di']\n",
"kaliamt aktual ['lina', 'menghadiri', 'turnamen', 'catur', 'pada', 'tanggal', '15', 'juli', '2023', '___']\n",
"kaliamt prediksi ['nina', 'menghadiri', 'konser', 'teknologi', 'pada', 'tanggal', '5', 'mei', '2023']\n",
"kaliamt aktual ['___', 'menghadiri', 'bazar', 'amal', 'di', 'padang']\n",
"kaliamt prediksi ['menghadiri', 'kompetisi', 'fotografi', 'di', 'yogyakarta']\n",
"kaliamt aktual ['di', 'manakah', 'benua', 'australia', 'terletak', '___']\n",
"kaliamt prediksi ['berapa', 'dikenal', 'terletak', 'di']\n",
"kaliamt aktual ['ernest', 'douwes', 'dekker', 'lahir', 'di', '___']\n",
"kaliamt prediksi ['ernest', 'douwes', 'dekker', 'lahir', 'di']\n",
"kaliamt aktual ['i', 'gusti', 'ngurah', 'rai', 'lahir', 'di', '___']\n",
"kaliamt prediksi ['i', 'gusti', 'ngurah', 'rai', 'lahir', 'di']\n",
"kaliamt aktual ['apa', 'kepanjangan', 'bu?']\n",
"kaliamt prediksi ['kapan', 'budi', 'utomo']\n",
"kaliamt aktual ['raja', 'balitung', 'memerintah', 'mataram', 'kuno', 'dari', 'tahun', '___', 'hingga', 'tahun', '___?']\n",
"kaliamt prediksi ['siapa', 'tahun', 'berapa', 'yang', 'mataram', 'pada', 'ke']\n",
"kaliamt aktual ['___', 'adalah', 'kota', 'kembang', 'yang', 'terkenal', 'dengan', 'fashion']\n",
"kaliamt prediksi ['adalah', 'kota', 'yang', 'yang', 'kaya', 'akan']\n",
"kaliamt aktual ['sebutkan', 'proses', 'dalam', 'pernapasan', '___']\n",
"kaliamt prediksi ['apa', 'saja', 'organ', 'dari']\n",
"kaliamt aktual ['sebutkan', 'tanggal', 'tiara', 'melakukan', 'melanjutkan', 'ke', 'bali', '___']\n",
"kaliamt prediksi ['pada', 'tanggal', 'berapa', 'melakukan', 'pergi', 'ke', 'bandung']\n",
"kaliamt aktual ['kh', 'ahmad', 'dahlan', 'lahir', 'di', '___']\n",
"kaliamt prediksi ['ernest', 'douwes', 'dekker', 'lahir', 'di']\n",
"kaliamt aktual ['___', 'adalah', 'kota', 'kembang', 'yang', 'terkenal', 'dengan', 'fashion']\n",
"kaliamt prediksi ['adalah', 'kota', 'yang', 'yang', 'kaya', 'akan']\n",
"kaliamt aktual ['inskripsi', 'ini', 'ditemukan', 'di', 'kampung', 'batu', 'tumbuh,', 'desa', 'tugu,', 'dekat', 'tanjung', 'priok,', 'jakarta.']\n",
"kaliamt prediksi ['raja', 'mulawarman', 'memiliki', 'memeluk', 'tinggi']\n",
"kaliamt aktual ['siapa', 'raja', 'pertama', 'kerajaan', 'demak?']\n",
"kaliamt prediksi ['siapa', 'yang', 'memerintah', 'kerajaan', 'palapa']\n",
"kaliamt aktual ['penduduk', 'tarumanegara', 'menjadi', 'makmur', 'tanpa', 'bantuan', 'sungai.']\n",
"kaliamt prediksi ['prasasti', 'mulawarman', 'memiliki', 'di', 'di']\n",
"kaliamt aktual ['rian', 'menghadiri', 'seminar', 'pendidikan', 'pada', 'tanggal', '5', 'mei', '2023', '___']\n",
"kaliamt prediksi ['nina', 'menghadiri', 'kompetisi', 'teknologi', 'pada', 'tanggal', '5', 'mei', '2023']\n",
"kaliamt aktual ['apa', 'fungsi', 'pembuluh', 'xilem', 'pada', 'tumbuhan', '___']\n",
"kaliamt prediksi ['apa', 'terdiri', 'atas', 'kurang']\n",
"kaliamt aktual ['apa', 'nama', 'keajaiban', 'dunia', 'di', 'meksiko?']\n",
"kaliamt prediksi ['apa', 'apa', 'organ', 'dari']\n",
"kaliamt aktual ['pada', 'tanggal', 'berapa', 'roni', 'liburan', 'ke', 'surabaya', '___']\n",
"kaliamt prediksi ['pada', 'tanggal', 'berapa', 'melakukan', 'pergi', 'ke', 'bandung']\n",
"kaliamt aktual ['kudungga', 'berubah', 'menjadi', '___?']\n",
"kaliamt prediksi ['siapa', 'terdiri', 'atas', 'kurang']\n",
"kaliamt aktual ['siapa', 'pendiri', 'kerajaan', 'singhasari?']\n",
"kaliamt prediksi ['siapa', 'yang', 'berapa', 'sumpah']\n",
"kaliamt aktual ['prasasti', 'kedukan', 'bukit', 'ditemukan', 'di', 'tepi', 'sungai', '___?']\n",
"kaliamt prediksi ['adalah', 'kota', 'pelajar', 'yang', 'kaya', 'akan']\n",
"kaliamt aktual ['kapan', 'masa', 'reformasi', 'di', 'indonesia', 'dimulai', '___']\n",
"kaliamt prediksi ['siapa', 'yang', 'pertama', 'kerajaan', 'palapa']\n",
"kaliamt aktual ['pattimura', 'lahir', 'pada', '___']\n",
"kaliamt prediksi ['dimana', 'hatta', 'lahir']\n",
"kaliamt aktual ['sang', 'mulawarman', 'memberi', 'sedekah', '20.000', 'ekor', 'sapi', 'kepada', 'para', 'brahmana.']\n",
"kaliamt prediksi ['kepada', 'yang', 'sedekah', 'di', 'diberikan']\n",
"kaliamt aktual ['bahan', 'apa', 'saja', 'yang', 'dibutuhkan', 'dalam', 'fotosintesis', '___']\n",
"kaliamt prediksi ['berapa', 'luas', 'terletak', 'di']\n",
"kaliamt aktual ['sebutkan', 'keajaiban', 'dunia', 'yang', 'ada', 'di', 'yordania?']\n",
"kaliamt prediksi ['keajaiban', 'dunia', 'apa', 'yang', 'berada', 'di']\n",
"kaliamt aktual ['bandung', 'dikenal', 'sebagai', '___']\n",
"kaliamt prediksi ['benua', 'dikenal', 'sebagai']\n",
"kaliamt aktual ['___', 'adalah', 'kota', 'sejuk', 'dengan', 'banyak', 'destinasi', 'wisata', 'alam']\n",
"kaliamt prediksi ['adalah', 'kota', 'pahlawan', 'yang', 'di', 'di', 'jawa']\n",
"kaliamt aktual ['planet', 'selain', 'saturnus', 'yang', 'memiliki', 'cincin', 'adalah', '___']\n",
"kaliamt prediksi ['keajaiban', 'dunia', 'apa', 'yang', 'berada']\n",
"kaliamt aktual ['di', 'mana', 'kerajaan', 'kutai', 'berdiri', '___']\n",
"kaliamt prediksi ['siapa', 'perdagangan', 'yang', 'yang', 'dari', 'dari']\n",
"kaliamt aktual ['pekerjaan', 'penggalian', 'selesai', 'dalam', '21', 'hari.']\n",
"kaliamt prediksi ['berapa', 'yang', 'sedekah', 'sedekah', 'diberikan']\n",
"kaliamt aktual ['galian', 'itu', 'panjangnya', 'kurang', 'dari', '10', 'km.']\n",
"kaliamt prediksi ['berapa', 'yang', 'sedekah', 'sedekah', 'diberikan']\n",
"kaliamt aktual ['organisasi', 'perempuan', 'pertama', 'pada', '1912', 'adalah', '___?']\n",
"kaliamt prediksi ['kerajaan', 'berdiri', 'berdiri', 'pada', 'tahun']\n",
"kaliamt aktual ['respirasi', 'adalah', '___', 'pertukaran', 'gas?']\n",
"kaliamt prediksi ['respirasi', 'adalah', 'pertukaran', 'pertukaran', 'gas', 'hindia']\n",
"kaliamt aktual ['___', 'adalah', 'ibukota', 'indonesia', 'dan', 'pusat', 'pemerintahan']\n",
"kaliamt prediksi ['siapa', 'yang', 'yang', 'yang', 'dan']\n",
"kaliamt aktual ['organ', 'apa', 'yang', 'berperan', 'penting', 'dalam', 'sistem', 'peredaran', 'darah', '___']\n",
"kaliamt prediksi ['siapa', 'yang', 'lembu', 'dipersembahkan']\n",
"kaliamt aktual ['yogyakarta', 'dikenal', 'sebagai', 'kota', 'pelajar', 'yang', 'kaya', 'akan', 'budaya', '___']\n",
"kaliamt prediksi ['prasasti', 'dikenal', 'sebagai', 'terletak', 'di', 'di', 'sungai']\n",
"kaliamt aktual ['apa', 'fungsi', 'insulin', 'dalam', 'tubuh', '___']\n",
"kaliamt prediksi ['balaputradewa', 'mempunyai', 'putra', 'dari']\n",
"kaliamt aktual ['kerajaan', '___', 'berdiri', 'pada', 'tahun', '1482?']\n",
"kaliamt prediksi ['kerajaan', 'berdiri', 'berdiri', 'pada', 'tahun']\n",
"kaliamt aktual ['pada', 'tanggal', 'berapa', 'budi', 'pindah', 'ke', 'bali', '___']\n",
"kaliamt prediksi ['kapan', 'aktivitas', 'pindah', 'ke', 'melanjutkan', 'ke', 'oleh']\n",
"kaliamt aktual ['ali', 'menghadiri', '___', 'robotik']\n",
"kaliamt prediksi ['lina', 'menghadiri', 'fotografi']\n",
"kaliamt aktual ['putri', 'menghadiri', 'festival', 'kuliner', 'pada', 'tanggal', '25', 'desember', '2023', '___']\n",
"kaliamt prediksi ['nina', 'menghadiri', 'kompetisi', 'amal', 'pada', 'tanggal', '5', 'juli', '2023']\n",
"kaliamt aktual ['sutan', 'sjahrir', 'lahir', 'tanggal', 'berapa', '___']\n",
"kaliamt prediksi ['mohammad', 'muis', 'lahir', 'tanggal']\n",
"kaliamt aktual ['siapa', 'yang', 'mengeluarkan', 'inskripsi', 'ini?']\n",
"kaliamt prediksi ['apa', 'mana', 'mana', 'kurang']\n",
"kaliamt aktual ['kerajaan', 'galuh', 'berdiri', 'pada', 'tahun', '___?']\n",
"kaliamt prediksi ['kerajaan', 'berdiri', 'berdiri', 'pada', 'tahun']\n",
"kaliamt aktual ['pluto', 'sekarang', 'dikategorikan', 'sebagai', '___']\n",
"kaliamt prediksi ['apa', 'saja', 'memberi', 'di', 'diberikan']\n",
"kaliamt aktual ['___', 'adalah', 'kota', 'kembang', 'yang', 'terkenal', 'dengan', 'fashion']\n",
"kaliamt prediksi ['adalah', 'kota', 'yang', 'yang', 'kaya', 'akan']\n",
"kaliamt aktual ['kerajaan', '___', 'berdiri', 'pada', 'tahun', '1514?']\n",
"kaliamt prediksi ['kerajaan', 'berdiri', 'berdiri', 'pada', 'tahun']\n",
"kaliamt aktual ['partai', 'nasional', 'indonesia', 'didirikan', 'pada', 'tanggal', '___', 'juli', '1927?']\n",
"kaliamt prediksi ['pada', 'wuruk', 'memerintah', 'majapahit', 'dari', 'tahun']\n",
"kaliamt aktual ['siapa', 'yang', 'mengemukakan', 'teori', 'evolusi', '___']\n",
"kaliamt prediksi ['siapa', 'penemu', 'pertama', 'kemerdekaan']\n",
"kaliamt aktual ['fajar', 'menghadiri', '___', 'fotografi']\n",
"kaliamt prediksi ['lina', 'menghadiri', 'fotografi']\n",
"kaliamt aktual ['siapa', 'nama', 'kakek', 'dari', 'raja', 'mulawarman', '___']\n",
"kaliamt prediksi ['di', 'negara', 'mana', 'dunia', 'dunia']\n",
"kaliamt aktual ['para', 'ahli', 'berpendapat', 'bahwa', 'yupa', 'dibuat', 'sekitar', 'abad', 'ke-5', 'm', 'karena', 'melihat', 'bentuk', '___']\n",
"kaliamt prediksi ['siapa', 'yang', 'berapa', 'kerajaan', 'palapa']\n",
"kaliamt aktual ['pusat', 'kerajaan', 'tarumanegara', 'diperkirakan', 'berada', 'di', 'antara', 'sungai', '____', 'dan', 'cisadane']\n",
"kaliamt prediksi ['adalah', 'kota', 'pahlawan', 'yang', 'di', 'di', 'destinasi']\n",
"kaliamt aktual ['siapa', 'pendiri', 'partai', 'nasional', 'indonesia', '___']\n",
"kaliamt prediksi ['kapan', 'budi', 'utomo']\n",
"kaliamt aktual ['siapa', 'yang', 'melakukan', 'selamatan', 'bagi', 'purnawarman?']\n",
"kaliamt prediksi ['siapa', 'yang', 'lembu', 'dipersembahkan', 'dipersembahkan']\n",
"kaliamt aktual ['___', 'menghadiri', 'turnamen', 'catur', 'di', 'malang']\n",
"kaliamt prediksi ['menghadiri', 'kompetisi', 'fotografi', 'di', 'yogyakarta']\n",
"kaliamt aktual ['cut', 'nyak', 'dien', 'wafat', 'tanggal', 'berapa', '___']\n",
"kaliamt prediksi ['i', 'nyak', 'dien', 'wafat', 'di']\n",
"kaliamt aktual ['ernest', 'douwes', 'dekker', 'lahir', 'pada', '___']\n",
"kaliamt prediksi ['ernest', 'douwes', 'dekker', 'lahir', 'di']\n",
"kaliamt aktual ['huruf', 'dan', 'bahasa', 'apa', 'yang', 'digunakan', 'pada', 'prasasti', 'yupa', '___']\n",
"kaliamt prediksi ['respirasi', 'adalah', 'yang', 'yang', 'gas', 'yang']\n",
"kaliamt aktual ['apa', 'nama', 'keajaiban', 'dunia', 'di', 'brasil?']\n",
"kaliamt prediksi ['planet', 'dunia', 'yang', 'yang', 'berada', 'di']\n",
"kaliamt aktual ['di', 'mana', 'proses', 'penyerapan', 'zat', 'makanan', 'terjadi', '___']\n",
"kaliamt prediksi ['apa', 'saja', 'organ', 'dari']\n",
"kaliamt aktual ['pada', 'tanggal', 'berapa', 'lina', 'liburan', 'ke', 'bali', '___']\n",
"kaliamt prediksi ['pada', 'tanggal', 'berapa', 'melakukan', 'melanjutkan', 'ke', 'bandung']\n",
"kaliamt aktual ['pegunungan', 'terbesar', 'di', 'benua', 'eropa', 'adalah', '___']\n",
"kaliamt prediksi ['apa', 'yang', 'sedekah', 'sedekah', 'diberikan']\n",
"kaliamt aktual ['tanggal', 'berapa', 'farhan', 'lahir', '___']\n",
"kaliamt prediksi ['dimana', 'berapa', 'lahir']\n",
"kaliamt aktual ['bukit', 'adalah', 'bagian', 'permukaan', 'bumi', 'yang', 'lebih', '___', 'dibandingkan', 'daerah', 'di', 'sekitarnya?']\n",
"kaliamt prediksi ['siapa', 'yang', 'menggali', 'dipersembahkan']\n",
"kaliamt aktual ['sutan', 'sjahrir', 'lahir', 'di', '___']\n",
"kaliamt prediksi ['mohammad', 'muis', 'lahir', 'tanggal']\n",
"kaliamt aktual ['nina', 'menghadiri', '___', 'teknologi']\n",
"kaliamt prediksi ['lina', 'menghadiri', 'fotografi']\n",
"kaliamt aktual ['telah', 'ditemukan', '___', 'buah', 'prasasti', 'terkait', 'perkembangan', 'kerajaan', 'tarumanegara']\n",
"kaliamt prediksi ['adalah', 'merupakan', 'yang', 'yang', 'bagi', 'karena', 'di']\n",
"kaliamt aktual ['dewi', 'menghadiri', '___', 'robotik']\n",
"kaliamt prediksi ['lina', 'menghadiri', 'fotografi']\n",
"kaliamt aktual ['apa', 'kepanjangan', 'pgri?']\n",
"kaliamt prediksi ['siapa', 'apa', 'yang', 'dibentuk', 'selanjutnya']\n",
"kaliamt aktual ['gunung', 'adalah', 'bagian', 'permukaan', 'bumi', 'yang', 'berbentuk', '___', 'atau', '___?']\n",
"kaliamt prediksi ['siapa', 'penemu', 'atas']\n",
"kaliamt aktual ['kompleks', 'trowulan', 'diperkirakan', 'menjadi', 'pusat', 'pemerintahan', 'kerajaan', '___?']\n",
"kaliamt prediksi ['siapa', 'yang', 'yang', 'yang', 'mataram', 'pada', 'pemerintahan']\n",
"kaliamt aktual ['prasasti', 'talang', 'tuo', 'ditemukan', 'di', 'daerah', '___?']\n",
"kaliamt prediksi ['adalah', 'kota', 'tuo', 'yang', 'di', 'akan', 'budaya']\n",
"kaliamt aktual ['jakarta', 'dikenal', 'sebagai', '___']\n",
"kaliamt prediksi ['berapa', 'luas', 'terletak']\n",
"kaliamt aktual ['singkatan', 'apa', 'untuk', 'himpunan', 'pengusaha', 'muda', 'indonesia?']\n",
"kaliamt prediksi ['siapa', 'apa', 'yang', 'dibentuk', 'selanjutnya']\n",
"kaliamt aktual ['fajar', 'menghadiri', 'workshop', 'fotografi', 'pada', 'tanggal', '10', 'agustus', '2023', '___']\n",
"kaliamt prediksi ['nina', 'menghadiri', 'konser', 'teknologi', 'pada', 'tanggal', '5', 'mei', '2023']\n",
"kaliamt aktual ['sumber', 'sejarah', 'tarumanegara', 'yang', 'utama', 'adalah', 'prasasti-prasasti', 'yang', 'telah', 'ditemukan.']\n",
"kaliamt prediksi ['respirasi', 'adalah', 'yang', 'yang', 'yang', 'yang']\n",
"kaliamt aktual ['___', 'menghadiri', 'rapat', 'organisasi', 'di', 'surabaya']\n",
"kaliamt prediksi ['menghadiri', 'kompetisi', 'fotografi', 'di', 'yogyakarta']\n",
"kaliamt aktual ['kerajaan', 'kahuripan', 'dibagi', 'menjadi', 'kerajaan', 'janggala', 'dan', 'kerajaan', '___?']\n",
"kaliamt prediksi ['siapa', 'yang', 'kerajaan', 'kerajaan', 'dari']\n",
"kaliamt aktual ['apa', 'nama', 'keajaiban', 'dunia', 'di', 'india?']\n",
"kaliamt prediksi ['keajaiban', 'dunia', 'apa', 'yang', 'berada', 'di']\n",
"kaliamt aktual ['sultan', 'hasanuddin', 'lahir', 'pada', '___']\n",
"kaliamt prediksi ['mohammad', 'hatta', 'lahir', 'di']\n",
"kaliamt aktual ['gurun', 'terbesar', 'ketiga', 'di', 'dunia', 'adalah', 'gurun', '___']\n",
"kaliamt prediksi ['planet', 'sahara', 'proses', 'yang', 'amerika', 'amerika']\n",
"kaliamt aktual ['apa', 'singkatan', 'dari', 'panitia', 'persiapan', 'kemerdekaan', 'indonesia?']\n",
"kaliamt prediksi ['apa', 'apa', 'yang', 'dibentuk', 'selanjutnya']\n",
"kaliamt aktual ['siapa', 'yang', 'memerintah', 'majapahit', 'dari', 'tahun', '1350', 'hingga', '1389', 'm?']\n",
"kaliamt prediksi ['hayam', 'wuruk', 'memerintah', 'majapahit', 'tahun', 'tahun']\n",
"kaliamt aktual ['nina', 'menghadiri', 'workshop', 'fotografi', 'pada', 'tanggal', '5', 'mei', '2023', '___']\n",
"kaliamt prediksi ['nina', 'menghadiri', 'kompetisi', 'teknologi', 'pada', 'tanggal', '5', 'mei', '2023']\n",
"kaliamt aktual ['mohammad', 'hatta', 'lahir', 'di', '___']\n",
"kaliamt prediksi ['mohammad', 'hatta', 'lahir', 'tanggal']\n",
"kaliamt aktual ['apa', 'nama', 'keajaiban', 'dunia', 'di', 'china?']\n",
"kaliamt prediksi ['planet', 'yang', 'yang', 'memperkuat', 'kedudukan', 'matahari', 'matahari']\n",
"kaliamt aktual ['kapan', 'indonesia', 'memproklamasikan', 'kemerdekaannya', '___']\n",
"kaliamt prediksi ['siapa', 'yang', 'pertama', 'sumpah', 'palapa']\n",
"kaliamt aktual ['apa', 'fungsi', 'pembuluh', 'floem', 'pada', 'tumbuhan', '___']\n",
"kaliamt prediksi ['apa', 'terdiri', 'atas', 'kurang']\n",
"kaliamt aktual ['kapan', 'nasa', 'didirikan', '___']\n",
"kaliamt prediksi ['siapa', 'pendiri', 'yang', 'didirikan']\n",
"kaliamt aktual ['mars', 'merupakan', 'planet', 'ke', 'berapa', 'dalam', 'tata', 'surya', '___']\n",
"kaliamt prediksi ['adalah', 'apa', 'yang', 'yang', 'dengan']\n",
"kaliamt aktual ['organisasi', 'keagamaan', 'yang', 'bersifat', 'modern', 'dan', 'didirikan', 'pada', '18', 'november', '1912', 'adalah', '___?']\n",
"kaliamt prediksi ['kapan', 'ketua', 'ppki']\n",
"kaliamt aktual ['di', 'mana', 'prasasti', 'ini', 'ditemukan?']\n",
"kaliamt prediksi ['siapa', 'yang', 'yang', 'yang', 'dari', 'dari', 'bolak']\n",
"kaliamt aktual ['dr.', 'cipto', 'mangunkusumo', 'lahir', 'di', '___']\n",
"kaliamt prediksi ['ernest', 'douwes', 'dekker', 'lahir', 'di']\n",
"kaliamt aktual ['___', 'menghadiri', 'festival', 'kuliner', 'di', 'medan']\n",
"kaliamt prediksi ['menghadiri', 'kompetisi', 'robotik', 'di', 'yogyakarta']\n",
"kaliamt aktual ['gunung', 'tertinggi', 'di', 'benua', 'afrika', 'adalah', '___']\n",
"kaliamt prediksi ['siapa', 'terdiri', 'atas', 'kurang']\n",
"kaliamt aktual ['berdasarkan', 'prasasti', 'tugu,', 'purbacaraka', 'memperkirakan', 'pusat', 'tarumanegara', 'ada', 'di', 'daerah', '____']\n",
"kaliamt prediksi ['siapa', 'yang', 'menggali', 'kerajaan']\n",
"kaliamt aktual ['tempat', 'suci', 'raja', 'mulawarman', 'dinamakan', '___']\n",
"kaliamt prediksi ['apa', 'terdiri', 'atas', 'kurang']\n",
"kaliamt aktual ['hana', 'menghadiri', 'turnamen', 'catur', 'pada', 'tanggal', '15', 'juli', '2023', '___']\n",
"kaliamt prediksi ['nina', 'menghadiri', 'kompetisi', 'amal', 'pada', 'tanggal', '5', 'mei', '2023']\n",
"kaliamt aktual ['retina', 'adalah', 'bagian', 'terluar', 'dari', 'mata', 'manusia', '___']\n",
"kaliamt prediksi ['prasasti', 'itu', 'disertai', 'persembahan', '1', '000', 'ekor']\n",
"kaliamt aktual ['kerajaan', 'samudra', 'pasai', 'didirikan', 'oleh', '___?']\n",
"kaliamt prediksi ['siapa', 'yang', 'yang', 'di', 'dari', 'dan']\n",
"kaliamt aktual ['rian', 'menghadiri', '___', 'pendidikan']\n",
"kaliamt prediksi ['nina', 'menghadiri', 'fotografi']\n",
"kaliamt aktual ['sentot', 'alibasya', 'prawirodirjo', 'lahir', 'tanggal', 'berapa', '___']\n",
"kaliamt prediksi ['ernest', 'douwes', 'dekker', 'lahir', 'di']\n",
"kaliamt aktual ['teuku', 'umar', 'lahir', 'pada', '___']\n",
"kaliamt prediksi ['mohammad', 'hatta', 'lahir', 'di']\n",
"kaliamt aktual ['prasasti', 'jambu', 'terletak', 'di', 'kota', 'jakarta.']\n",
"kaliamt prediksi ['prasasti', 'dikenal', 'memiliki', 'di', 'di', 'sungai']\n",
"kaliamt aktual ['apa', 'nama', 'keajaiban', 'dunia', 'di', 'inggris?']\n",
"kaliamt prediksi ['berapa', 'yang', 'mana', 'dipersembahkan']\n",
"kaliamt aktual ['apa', 'peristiwa', 'politik', 'penting', 'pada', 'masa', 'reformasi', '___']\n",
"kaliamt prediksi ['siapa', 'yang', 'pertama', 'kerajaan', 'palapa']\n",
"kaliamt aktual ['di', 'mana', 'sedekah', 'itu', 'dilakukan', '___']\n",
"kaliamt prediksi ['siapa', 'yang', 'sedekah', 'sedekah', 'diberikan']\n",
"kaliamt aktual ['di', 'mana', 'dan', 'bagaimana', 'proses', 'pembentukan', 'urine', 'terjadi', '___']\n",
"kaliamt prediksi ['singkatan', 'partai', 'komunis', 'indonesia']\n",
"kaliamt aktual ['kata', 'tarum', 'dipakai', 'sebagai', 'nama', 'sungai', 'musi.']\n",
"kaliamt prediksi ['adalah', 'kota', 'pelajar', 'yang', 'kaya', 'akan']\n",
"kaliamt aktual ['kapan', 'sumpah', 'pemuda', 'diikrarkan', '___']\n",
"kaliamt prediksi ['siapa', 'partai', 'pertama', 'indonesia']\n",
"kaliamt aktual ['h', 'kern', 'membaca', 'inskripsi', 'b', 'sebagai', 'cri', 'tji', 'aroe', 'eun', 'waca.']\n",
"kaliamt prediksi ['adalah', 'adalah', 'komponen', 'yang', 'penting', 'keberlangsungan', 'kehidupan', 'di']\n",
"kaliamt aktual ['raja', 'berganti', 'nama', 'menjadi', '___?']\n",
"kaliamt prediksi ['apa', 'adalah', 'putra', 'dari']\n",
"kaliamt aktual ['tanggal', 'berapa', 'zain', 'lahir', '___']\n",
"kaliamt prediksi ['dimana', 'berapa', 'lahir']\n",
"kaliamt aktual ['galian', 'itu', 'panjangnya', 'kurang', 'dari', '10', 'km.']\n",
"kaliamt prediksi ['berapa', 'panjang', 'sedekah', 'sedekah', 'diberikan']\n",
"kaliamt aktual ['yogyakarta', 'dikenal', 'sebagai', '___']\n",
"kaliamt prediksi ['yogyakarta', 'dikenal', 'sebagai']\n",
"kaliamt aktual ['prasasti', 'kedukan', 'bukit', 'ditemukan', 'dekat', '___?']\n",
"kaliamt prediksi ['adalah', 'kota', 'pelajar', 'yang', 'kaya', 'akan']\n",
"kaliamt aktual ['apa', 'kepanjangan', 'bpupki?']\n",
"kaliamt prediksi ['kapan', 'ketua', 'ppki']\n",
"kaliamt aktual ['apa', 'peranan', 'sungai', 'mahakam', 'bagi', 'perekonomian', '___']\n",
"kaliamt prediksi ['adalah', 'kota', 'yang', 'yang', 'kaya', 'akan']\n",
"kaliamt aktual ['bandung', 'dikenal', 'sebagai', 'kota', 'kembang', 'yang', 'terkenal', 'dengan', 'fashion', '___']\n",
"kaliamt prediksi ['prasasti', 'kota', 'sebagai', 'terletak', 'di', 'di', 'sungai']\n",
"kaliamt aktual ['siapa', 'yang', 'membangun', 'taj', 'mahal', '___']\n",
"kaliamt prediksi ['apa', 'adalah', 'keturunan', 'dari']\n",
"kaliamt aktual ['pegunungan', 'adalah', 'dataran', '___?']\n",
"kaliamt prediksi ['apa', 'terdiri', 'atas', 'kurang']\n",
"kaliamt aktual ['raka', 'menghadiri', '___', 'organisasi']\n",
"kaliamt prediksi ['lina', 'menghadiri', 'fotografi']\n",
"kaliamt aktual ['dimana', 'letaknya', 'stonehenge?']\n",
"kaliamt prediksi ['planet', 'dunia', 'apa', 'yang', 'berada', 'di']\n",
"kaliamt aktual ['___', 'menghadiri', 'konser', 'musik', 'di', 'padang']\n",
"kaliamt prediksi ['menghadiri', 'konser', 'amal', 'di', 'yogyakarta']\n",
"kaliamt aktual ['rian', 'menghadiri', '___', 'renang']\n",
"kaliamt prediksi ['lina', 'menghadiri', 'fotografi']\n",
"kaliamt aktual ['___', 'menghadiri', 'workshop', 'fotografi', 'di', 'surabaya']\n",
"kaliamt prediksi ['menghadiri', 'konser', 'fotografi', 'di', 'yogyakarta']\n",
"kaliamt aktual ['apa', 'kepanjangan', 'sdi?']\n",
"kaliamt prediksi ['siapa', 'partai', 'komunis', 'indonesia']\n",
"kaliamt aktual ['di', 'mana', 'letak', 'kerajaan', 'kutai', '___']\n",
"kaliamt prediksi ['siapa', 'yang', 'menggali', 'kerajaan', 'dari']\n",
"kaliamt aktual ['raja', 'aswawarman', 'dikatakan', 'seperti', '___', 'ansuman']\n",
"kaliamt prediksi ['di', 'negara', 'mana', 'di', 'dunia']\n",
"kaliamt aktual ['sejarah', 'tertua', 'berkaitan', 'pengendalian', 'banjir', 'ada', 'pada', 'masa', 'kerajaan', 'tarumanegara.']\n",
"kaliamt prediksi ['perubahan', 'adalah', 'manusia', 'tersusun', 'atas', 'faring', 'laring', 'laring']\n",
"kaliamt aktual ['sebutkan', 'keajaiban', 'dunia', 'yang', 'ada', 'di', 'china?']\n",
"kaliamt prediksi ['planet', 'apa', 'yang', 'memperkuat', 'kedudukan', 'matahari', 'matahari']\n",
"kaliamt aktual ['benua', 'terbesar', 'di', 'dunia', 'adalah', '___']\n",
"kaliamt prediksi ['siapa', 'yang', 'lembu', 'yang', 'dan']\n",
"kaliamt aktual ['apa', 'yang', 'ditonjolkan', 'dalam', 'prasasti', 'cidanghiang', '___']\n",
"kaliamt prediksi ['adalah', 'kota', 'yang', 'ditemukan', 'di']\n",
"kaliamt aktual ['nina', 'menghadiri', '___', 'kuliner']\n",
"kaliamt prediksi ['nina', 'menghadiri', 'fotografi']\n",
"kaliamt aktual ['kerajaan', 'majapahit', 'berdiri', 'pada', 'tahun', '___?']\n",
"kaliamt prediksi ['kerajaan', 'berdiri', 'berdiri', 'pada', 'tahun']\n",
"kaliamt aktual ['kerajaan', 'demak', 'berdiri', 'tahun', '___?']\n",
"kaliamt prediksi ['siapa', 'yang', 'memerintah', 'kerajaan', 'palapa']\n",
"kaliamt aktual ['dimana', 'proses', 'fotosintesis', 'berlangsung', '___']\n",
"kaliamt prediksi ['siapa', 'saja', 'sedekah', 'sedekah', 'diberikan']\n",
"kaliamt aktual ['balaputradewa', 'adalah', 'putra', 'dari', 'raja', '___?']\n",
"kaliamt prediksi ['apa', 'adalah', 'keturunan', 'dari']\n",
"kaliamt aktual ['budi', 'menghadiri', 'konser', 'musik', 'pada', 'tanggal', '5', 'mei', '2023', '___']\n",
"kaliamt prediksi ['nina', 'menghadiri', 'konser', 'teknologi', 'pada', 'tanggal', '5', 'mei', '2023']\n",
"kaliamt aktual ['pertempuran', 'sengit', 'terjadi', 'antara', 'para', 'pejuang', 'dari', 'buleleng', 'yang', 'dibantu', 'oleh', '___.']\n",
"kaliamt prediksi ['kapan', 'ketua', 'ppki']\n",
"kaliamt aktual ['kapan', 'roni', 'dan', 'firmansyah', 'melakukan', 'liburan', 'ke', 'jakarta', '___']\n",
"kaliamt prediksi ['pada', 'tanggal', 'berapa', 'melakukan', 'melanjutkan', 'ke', 'bandung']\n",
"kaliamt aktual ['di', 'wilayah', 'mana', 'prasasti', 'kerajaan', 'tarumanegara', 'ditemukan?']\n",
"kaliamt prediksi ['siapa', 'perdagangan', 'yang', 'kerajaan', 'dari', 'dari']\n",
"kaliamt aktual ['dimana', 'mohammad', 'hatta', 'lahir?']\n",
"kaliamt prediksi ['mohammad', 'hatta', 'lahir', 'tanggal']\n",
"kaliamt aktual ['kapan', 'prasasti', 'yupa', 'diperkirakan', 'dibuat', '___']\n",
"kaliamt prediksi ['siapa', 'kota', 'yang', 'yang', 'dan', 'dan']\n",
"kaliamt aktual ['hubungan', 'dagang', 'sudah', 'terjadi', 'dengan', 'luar.']\n",
"kaliamt prediksi ['raja', 'yang', 'memiliki', 'ketinggian', 'tinggi']\n",
"kaliamt aktual ['apa', 'nama', 'kali', 'yang', 'kedua', 'digali', 'raja', 'purnawarman?']\n",
"kaliamt prediksi ['siapa', 'gomati', 'digali', 'digali', 'mengalir', 'memerintahkan', 'tengah', 'tengah']\n",
"kaliamt aktual ['kerajaan', 'sriwijaya', 'berkuasa', 'dari', 'abad', 'ke-___', 'hingga', 'abad', 'ke-___?']\n",
"kaliamt prediksi ['siapa', 'yang', 'pertama', 'kerajaan']\n",
"kaliamt aktual ['di', 'mana', 'prasasti', 'jambu', '(pasir', 'koleangkak)', 'terletak?']\n",
"kaliamt prediksi ['siapa', 'yang', 'yang', 'yang', 'di']\n",
"kaliamt aktual ['organisasi', 'trikoro', 'darmo', 'berdiri', 'di', '___?']\n",
"kaliamt prediksi ['siapa', 'partai', 'komunis', 'indonesia']\n",
"kaliamt aktual ['rian', 'menghadiri', 'festival', 'kuliner', 'pada', 'tanggal', '10', 'agustus', '2023', '___']\n",
"kaliamt prediksi ['nina', 'menghadiri', 'kompetisi', 'amal', 'pada', 'tanggal', '5', 'juli', '2023']\n",
"kaliamt aktual ['kapan', 'budi', 'dan', 'santoso', 'melakukan', 'pindah', 'ke', 'yogyakarta', '___']\n",
"kaliamt prediksi ['kapan', 'aktivitas', 'pindah', 'ke', 'pindah', 'dilakukan', 'oleh']\n",
"kaliamt aktual ['kapan', 'andi', 'dan', 'setiawan', 'melakukan', 'pergi', 'ke', 'medan', '___']\n",
"kaliamt prediksi ['pada', 'tanggal', 'berapa', 'melakukan', 'pergi', 'ke', 'bandung']\n",
"kaliamt aktual ['prasasti', 'kedukan', 'bukit', 'ditemukan', 'di', 'tepi', 'sungai', '___?']\n",
"kaliamt prediksi ['adalah', 'kota', 'pelajar', 'yang', 'kaya', 'akan']\n",
"kaliamt aktual ['dalam', 'bahasa', 'apa', 'inskripsi', 'tersebut', 'ditulis?']\n",
"kaliamt prediksi ['planet', 'yang', 'yang', 'terbesar', 'planet', 'matahari', 'matahari']\n",
"kaliamt aktual ['apa', 'sumber', 'utama', 'sejarah', 'kutai', '___']\n",
"kaliamt prediksi ['respirasi', 'adalah', 'yang', 'yang', 'gas', 'yang']\n",
"kaliamt aktual ['budi', 'menghadiri', '___', 'musik']\n",
"kaliamt prediksi ['lina', 'menghadiri', 'fotografi']\n",
"kaliamt aktual ['apa', 'nama', 'bagian', 'terluar', 'dari', 'mata', 'manusia', '___']\n",
"kaliamt prediksi ['siapa', 'yang', 'lembu', 'yang', 'dan']\n",
"kaliamt aktual ['sebutkan', 'keajaiban', 'dunia', 'yang', 'ada', 'di', 'inggris?']\n",
"kaliamt prediksi ['apa', 'mana', 'mana', 'di']\n",
"kaliamt aktual ['mereka', 'banyak', 'yang', 'melakukan', 'perdagangan.']\n",
"kaliamt prediksi ['raja', 'memiliki', 'memiliki']\n",
"kaliamt aktual ['jakarta', 'dikenal', 'sebagai', 'ibukota', 'indonesia', 'dan', 'pusat', 'pemerintahan', '___']\n",
"kaliamt prediksi ['prasasti', 'dikenal', 'disertai', 'persembahan', '1', '000', 'ekor']\n",
"kaliamt aktual ['di', 'negara', 'mana', 'terletak', 'angkot', 'wat?']\n",
"kaliamt prediksi ['siapa', 'yang', 'menggali', 'kerajaan']\n",
"kaliamt aktual ['siapa', 'yang', 'melakukan', 'selamatan', 'bagi', 'purnawarman?']\n",
"kaliamt prediksi ['siapa', 'yang', 'lembu', 'dipersembahkan', 'dipersembahkan']\n",
"kaliamt aktual ['dunia', 'terdiri', 'atas', '___', 'lautan?']\n",
"kaliamt prediksi ['apa', 'terdiri', 'atas', 'kurang']\n",
"kaliamt aktual ['kapan', 'bpupki', 'didirikan', '___']\n",
"kaliamt prediksi ['kapan', 'pendiri', 'utomo']\n",
"kaliamt aktual ['pattimura', 'lahir', 'di', '___']\n",
"kaliamt prediksi ['dimana', 'hatta', 'lahir']\n",
"kaliamt aktual ['dimana', 'kerajaan', 'majapahit', 'berdiri', '___']\n",
"kaliamt prediksi ['kapan', 'partai', 'komunis', 'indonesia']\n",
"kaliamt aktual ['masyarakat', 'kutai', 'melakukan', 'pertanian.']\n",
"kaliamt prediksi ['benua', 'mulawarman', 'memiliki', 'di']\n",
"kaliamt aktual ['dataran', '___', 'adalah', 'daerah', 'datar', 'yang', 'memiliki', 'ketinggian', 'lebih', 'dari', '400', 'mdpal?']\n",
"kaliamt prediksi ['siapa', 'yang', 'internasional', 'kerajaan', 'dari', 'dari']\n",
"kaliamt aktual ['siapa', 'raja', 'yang', 'terkenal', 'pada', 'masa', 'tarumanegara', '___']\n",
"kaliamt prediksi ['siapa', 'yang', 'yang', 'kerajaan', 'dari']\n",
"kaliamt aktual ['siapa', 'yang', 'memproklamasikan', 'kemerdekaan', 'indonesia', '___']\n",
"kaliamt prediksi ['tahun', 'berapa', 'sebelum', 'waterloo']\n",
"\n",
"Model Performance Metrics:\n",
"Average BLEU Score: 2.13%\n",
"Average ROUGE-1 Score: 25.43%\n",
"Average ROUGE-2 Score: 10.45%\n",
"Average ROUGE-L Score: 24.96%\n"
]
}
],
"source": [
"# Fungsi untuk memprediksi pertanyaan\n",
"def predict_question(context, tokens, ner, srl, q_type):\n",
" context = preprocess_text(context)\n",
"\n",
" context_seq = tokenizer.texts_to_sequences([context])[0]\n",
" token_seq = tokenizer.texts_to_sequences([\" \".join(tokens)])[0]\n",
" ner_seq = ner_tokenizer.texts_to_sequences([\" \".join(ner)])[0]\n",
" srl_seq = srl_tokenizer.texts_to_sequences([\" \".join(srl)])[0]\n",
"\n",
" context_padded = pad_sequences(\n",
" [context_seq], maxlen=max_context_len, padding=\"post\"\n",
" )\n",
" token_padded = pad_sequences([token_seq], maxlen=max_token_len, padding=\"post\")\n",
" ner_padded = pad_sequences([ner_seq], maxlen=max_token_len, padding=\"post\")\n",
" srl_padded = pad_sequences([srl_seq], maxlen=max_token_len, padding=\"post\")\n",
"\n",
" # Q-type one-hot encoding\n",
" q_type_idx = q_type_tokenizer.word_index.get(q_type, 0)\n",
" q_type_one_hot = tf.keras.utils.to_categorical(\n",
" [q_type_idx], num_classes=q_type_vocab_size\n",
" )\n",
"\n",
" # Predict\n",
" pred = model.predict(\n",
" [context_padded, token_padded, ner_padded, srl_padded, q_type_one_hot],\n",
" verbose=0,\n",
" )\n",
"\n",
" # Convert prediction to words\n",
" pred_seq = np.argmax(pred[0], axis=1)\n",
"\n",
" # Convert indices to words\n",
" reverse_word_map = {v: k for k, v in tokenizer.word_index.items()}\n",
" pred_words = [reverse_word_map.get(i, \"\") for i in pred_seq if i != 0]\n",
"\n",
" return \" \".join(pred_words)\n",
"\n",
"\n",
"def evaluate_model_performance(test_data):\n",
"\n",
" # Initialize ROUGE scorer\n",
" scorer = rouge_scorer.RougeScorer([\"rouge1\", \"rouge2\", \"rougeL\"], use_stemmer=True)\n",
"\n",
" # Lists to store scores\n",
" bleu_scores = []\n",
" rouge1_scores = []\n",
" rouge2_scores = []\n",
" rougel_scores = []\n",
"\n",
" # Iterate through test data\n",
" for i in range(len(test_data)):\n",
" # Get test sample\n",
" sample_context = contexts[test_data[i]]\n",
" sample_tokens = tokens_list[test_data[i]]\n",
" sample_ner = ner_list[test_data[i]]\n",
" sample_srl = srl_list[test_data[i]]\n",
" sample_q_type = q_types[test_data[i]]\n",
" actual_question = questions[test_data[i]]\n",
"\n",
" # Predict question\n",
" pred_question = predict_question(\n",
" sample_context, sample_tokens, sample_ner, sample_srl, sample_q_type\n",
" )\n",
"\n",
" # Tokenize for BLEU score\n",
" actual_tokens = actual_question.split()\n",
" pred_tokens = pred_question.split()\n",
"\n",
" # Calculate BLEU score\n",
" # Using unigram, bigram, trigram, and 4-gram\n",
" print(\"kaliamt aktual\", actual_tokens)\n",
" print(\"kaliamt prediksi\", pred_tokens)\n",
" bleu_score = sentence_bleu([actual_tokens], pred_tokens)\n",
" bleu_scores.append(bleu_score)\n",
"\n",
" try:\n",
" rouge_scores = scorer.score(actual_question, pred_question)\n",
"\n",
" # Extract F1 scores\n",
" rouge1_scores.append(rouge_scores[\"rouge1\"].fmeasure)\n",
" rouge2_scores.append(rouge_scores[\"rouge2\"].fmeasure)\n",
" rougel_scores.append(rouge_scores[\"rougeL\"].fmeasure)\n",
" except Exception as e:\n",
" print(f\"Error calculating ROUGE score: {e}\")\n",
"\n",
" # Calculate average scores\n",
" results = {\n",
" \"avg_bleu_score\": np.mean(bleu_scores),\n",
" \"avg_rouge1\": np.mean(rouge1_scores),\n",
" \"avg_rouge2\": np.mean(rouge2_scores),\n",
" \"avg_rougel\": np.mean(rougel_scores),\n",
" }\n",
"\n",
" return results\n",
"\n",
"\n",
"loaded_model = load_model(\"question_prediction_model_final.h5\")\n",
"\n",
"with open(\"question_prediction_tokenizers.json\", \"r\") as f:\n",
" tokenizer_data = json.load(f)\n",
"\n",
"# Ambil beberapa sampel dari data test\n",
"sample_idx = random.randint(0, len(test_indices) - 1)\n",
"sample_context = contexts[test_indices[sample_idx]]\n",
"sample_tokens = tokens_list[test_indices[sample_idx]]\n",
"sample_ner = ner_list[test_indices[sample_idx]]\n",
"sample_srl = srl_list[test_indices[sample_idx]]\n",
"sample_q_type = q_types[test_indices[sample_idx]]\n",
"\n",
"performance_metrics = evaluate_model_performance(test_indices)\n",
"\n",
"print(\"\\nModel Performance Metrics:\")\n",
"print(f\"Average BLEU Score: {performance_metrics['avg_bleu_score'] * 100:.2f}%\")\n",
"print(f\"Average ROUGE-1 Score: {performance_metrics['avg_rouge1'] * 100:.2f}%\")\n",
"print(f\"Average ROUGE-2 Score: {performance_metrics['avg_rouge2'] * 100:.2f}%\")\n",
"print(f\"Average ROUGE-L Score: {performance_metrics['avg_rougel'] * 100:.2f}%\")"
]
}
],
"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
}