Update explanation_builder.py
Browse files- explanation_builder.py +18 -11
explanation_builder.py
CHANGED
|
@@ -9,7 +9,7 @@ from typing import List, Dict, Any
|
|
| 9 |
from .recommendation_builder import generate_recommendation_paragraph
|
| 10 |
|
| 11 |
# ======================================================================
|
| 12 |
-
# 1. BANK TEMPLATE (Faktor / Poin-Poin) - Dibuat lebih
|
| 13 |
# ======================================================================
|
| 14 |
EXPLANATION_TEMPLATES = {
|
| 15 |
"pembuka": {
|
|
@@ -58,7 +58,7 @@ EXPLANATION_TEMPLATES = {
|
|
| 58 |
"tinggi_kuat": "🚀 Tren Menanjak: Grafik nilai Anda menunjukkan tren kenaikan yang kuat."
|
| 59 |
},
|
| 60 |
"Rentang_IPS": {
|
| 61 |
-
"rendah": "⚖️ Performa Stabil: Fluktuasi nilai Anda kecil, menunjukkan konsistensi.",
|
| 62 |
"tinggi": "🎢 Nilai Fluktuatif: Terdeteksi rentang nilai yang lebar ({value:.2f}) (tidak stabil)."
|
| 63 |
},
|
| 64 |
"Total_SKS_Gagal": {
|
|
@@ -95,14 +95,15 @@ def _get_explanation_text(rule: Dict[str, Any]) -> str:
|
|
| 95 |
# 1. Fitur OHE
|
| 96 |
if feature in ["Tren_Menaik", "Tren_Menurun", "Tren_Stabil"]:
|
| 97 |
key = "ya" if condition == "tinggi" else "tidak"
|
| 98 |
-
|
|
|
|
| 99 |
|
| 100 |
# 2. Fitur Numerik (Sanity Check)
|
| 101 |
chosen_template_key = ""
|
| 102 |
if feature == "IPS_Terakhir":
|
| 103 |
if condition == "tinggi":
|
| 104 |
if value < 2.75: chosen_template_key = "cukup" # Untuk 2.62
|
| 105 |
-
elif value < 3.25: chosen_template_key = "baik"
|
| 106 |
else: chosen_template_key = "tinggi"
|
| 107 |
else:
|
| 108 |
if value < 2.0: chosen_template_key = "rendah_parah"
|
|
@@ -111,15 +112,15 @@ def _get_explanation_text(rule: Dict[str, Any]) -> str:
|
|
| 111 |
elif feature == "IPK_Terakhir":
|
| 112 |
if condition == "tinggi":
|
| 113 |
if value < 2.75: chosen_template_key = "cukup" # Untuk 2.15
|
| 114 |
-
elif value < 3.25: chosen_template_key = "baik"
|
| 115 |
else: chosen_template_key = "tinggi"
|
| 116 |
else:
|
| 117 |
if value < 2.0: chosen_template_key = "rendah_parah"
|
| 118 |
else: chosen_template_key = "rendah"
|
| 119 |
|
| 120 |
elif feature == "Jumlah_MK_Gagal":
|
| 121 |
-
if condition == "rendah":
|
| 122 |
-
chosen_template_key = "rendah"
|
| 123 |
else: # tinggi
|
| 124 |
if value <= 3: chosen_template_key = "tinggi_sedikit"
|
| 125 |
else: chosen_template_key = "tinggi_banyak" # Untuk 4
|
|
@@ -127,7 +128,7 @@ def _get_explanation_text(rule: Dict[str, Any]) -> str:
|
|
| 127 |
elif feature == "Tren_IPS_Slope":
|
| 128 |
if condition == "tinggi":
|
| 129 |
if value < 0.1: chosen_template_key = "tinggi_sedikit" # Untuk 0.066
|
| 130 |
-
else: chosen_template_key = "tinggi_kuat"
|
| 131 |
else:
|
| 132 |
chosen_template_key = "rendah"
|
| 133 |
|
|
@@ -161,6 +162,10 @@ def _get_explanation_text(rule: Dict[str, Any]) -> str:
|
|
| 161 |
if isinstance(template_str, list):
|
| 162 |
template_str = random.choice(template_str)
|
| 163 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
return template_str.format(
|
| 165 |
feature_name=feature,
|
| 166 |
value=value,
|
|
@@ -174,14 +179,16 @@ def _get_explanation_text(rule: Dict[str, Any]) -> str:
|
|
| 174 |
|
| 175 |
def build_full_response(structured_rules: List[Dict[str, Any]], prediction_val: str) -> Dict[str, Any]:
|
| 176 |
"""
|
| 177 |
-
Merakit respons lengkap: Poin Faktor + Paragraf Rekomendasi
|
| 178 |
"""
|
| 179 |
try:
|
| 180 |
# --- BAGIAN 1: BUAT POIN FAKTOR (Logika DIPERBARUI) ---
|
| 181 |
opening_templates = EXPLANATION_TEMPLATES["pembuka"].get(prediction_val)
|
| 182 |
|
| 183 |
if not opening_templates:
|
| 184 |
-
|
|
|
|
|
|
|
| 185 |
elif isinstance(opening_templates, list):
|
| 186 |
opening_line = random.choice(opening_templates)
|
| 187 |
else:
|
|
@@ -198,7 +205,7 @@ def build_full_response(structured_rules: List[Dict[str, Any]], prediction_val:
|
|
| 198 |
# [DIUBAH] Panggil helper baru
|
| 199 |
chosen_template = _get_explanation_text(rule)
|
| 200 |
|
| 201 |
-
if chosen_template:
|
| 202 |
factors_list.append(chosen_template)
|
| 203 |
|
| 204 |
# --- BAGIAN 2: BUAT PARAGRAF REKOMENDASI (Logika Impor) ---
|
|
|
|
| 9 |
from .recommendation_builder import generate_recommendation_paragraph
|
| 10 |
|
| 11 |
# ======================================================================
|
| 12 |
+
# 1. BANK TEMPLATE (Faktor / Poin-Poin) - Dibuat lebih spesifik
|
| 13 |
# ======================================================================
|
| 14 |
EXPLANATION_TEMPLATES = {
|
| 15 |
"pembuka": {
|
|
|
|
| 58 |
"tinggi_kuat": "🚀 Tren Menanjak: Grafik nilai Anda menunjukkan tren kenaikan yang kuat."
|
| 59 |
},
|
| 60 |
"Rentang_IPS": {
|
| 61 |
+
"rendah": "⚖️ Performa Stabil: Fluktuasi nilai Anda kecil ({value:.2f}), menunjukkan konsistensi.",
|
| 62 |
"tinggi": "🎢 Nilai Fluktuatif: Terdeteksi rentang nilai yang lebar ({value:.2f}) (tidak stabil)."
|
| 63 |
},
|
| 64 |
"Total_SKS_Gagal": {
|
|
|
|
| 95 |
# 1. Fitur OHE
|
| 96 |
if feature in ["Tren_Menaik", "Tren_Menurun", "Tren_Stabil"]:
|
| 97 |
key = "ya" if condition == "tinggi" else "tidak"
|
| 98 |
+
# Kita hanya definisikan 'ya', jadi jika 'tidak' akan di-skip (return None)
|
| 99 |
+
return templates.get(feature, {}).get(key)
|
| 100 |
|
| 101 |
# 2. Fitur Numerik (Sanity Check)
|
| 102 |
chosen_template_key = ""
|
| 103 |
if feature == "IPS_Terakhir":
|
| 104 |
if condition == "tinggi":
|
| 105 |
if value < 2.75: chosen_template_key = "cukup" # Untuk 2.62
|
| 106 |
+
elif value < 3.25: chosen_template_key = "baik" # Untuk 2.92
|
| 107 |
else: chosen_template_key = "tinggi"
|
| 108 |
else:
|
| 109 |
if value < 2.0: chosen_template_key = "rendah_parah"
|
|
|
|
| 112 |
elif feature == "IPK_Terakhir":
|
| 113 |
if condition == "tinggi":
|
| 114 |
if value < 2.75: chosen_template_key = "cukup" # Untuk 2.15
|
| 115 |
+
elif value < 3.25: chosen_template_key = "baik" # Untuk 2.78
|
| 116 |
else: chosen_template_key = "tinggi"
|
| 117 |
else:
|
| 118 |
if value < 2.0: chosen_template_key = "rendah_parah"
|
| 119 |
else: chosen_template_key = "rendah"
|
| 120 |
|
| 121 |
elif feature == "Jumlah_MK_Gagal":
|
| 122 |
+
if condition == "rendah": # (value 0)
|
| 123 |
+
chosen_template_key = "rendah"
|
| 124 |
else: # tinggi
|
| 125 |
if value <= 3: chosen_template_key = "tinggi_sedikit"
|
| 126 |
else: chosen_template_key = "tinggi_banyak" # Untuk 4
|
|
|
|
| 128 |
elif feature == "Tren_IPS_Slope":
|
| 129 |
if condition == "tinggi":
|
| 130 |
if value < 0.1: chosen_template_key = "tinggi_sedikit" # Untuk 0.066
|
| 131 |
+
else: chosen_template_key = "tinggi_kuat" # Untuk 0.125
|
| 132 |
else:
|
| 133 |
chosen_template_key = "rendah"
|
| 134 |
|
|
|
|
| 162 |
if isinstance(template_str, list):
|
| 163 |
template_str = random.choice(template_str)
|
| 164 |
|
| 165 |
+
# Pastikan string tidak None sebelum di-format
|
| 166 |
+
if not template_str:
|
| 167 |
+
return None # Skip jika template tidak ditemukan
|
| 168 |
+
|
| 169 |
return template_str.format(
|
| 170 |
feature_name=feature,
|
| 171 |
value=value,
|
|
|
|
| 179 |
|
| 180 |
def build_full_response(structured_rules: List[Dict[str, Any]], prediction_val: str) -> Dict[str, Any]:
|
| 181 |
"""
|
| 182 |
+
[DIUBAH] Merakit respons lengkap: Poin Faktor + Paragraf Rekomendasi
|
| 183 |
"""
|
| 184 |
try:
|
| 185 |
# --- BAGIAN 1: BUAT POIN FAKTOR (Logika DIPERBARUI) ---
|
| 186 |
opening_templates = EXPLANATION_TEMPLATES["pembuka"].get(prediction_val)
|
| 187 |
|
| 188 |
if not opening_templates:
|
| 189 |
+
# Fallback jika key prediksi (misal 'Resiko Sedang') tidak ada
|
| 190 |
+
default_template = EXPLANATION_TEMPLATES["pembuka"].get("default", "Analisis Faktor:")
|
| 191 |
+
opening_line = default_template.format(prediction_val=prediction_val)
|
| 192 |
elif isinstance(opening_templates, list):
|
| 193 |
opening_line = random.choice(opening_templates)
|
| 194 |
else:
|
|
|
|
| 205 |
# [DIUBAH] Panggil helper baru
|
| 206 |
chosen_template = _get_explanation_text(rule)
|
| 207 |
|
| 208 |
+
if chosen_template: # Hanya tambahkan jika string tidak None/Kosong
|
| 209 |
factors_list.append(chosen_template)
|
| 210 |
|
| 211 |
# --- BAGIAN 2: BUAT PARAGRAF REKOMENDASI (Logika Impor) ---
|