# %% [1] IMPORT LIBRARIES & LOAD DATA import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report, accuracy_score import joblib print("--- [STEP 3] Pelatihan Model Random Forest 30 Jurusan ---") print("Memuat dataset yang sudah diproses...") df = pd.read_csv('dataset_siswa_siap_model.csv') # %% [2] MEMISAHKAN FITUR DAN TARGET (DATA SPLIT) print("Membagi fitur dan target...") X = df.drop('rekomendasi_jurusan', axis=1) y = df['rekomendasi_jurusan'] print("Membagi data menjadi data latih (80%) dan data uji (20%)...") # Karena ada 30 kelas, stratify sangat wajib agar distribusi per kelas merata X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y) print(f"Jumlah Data Latih: {X_train.shape[0]} | Jumlah Data Uji: {X_test.shape[0]}") # %% [3] TRAINING MODEL RANDOM FOREST (HYPERPARAMETER ANTI-OVERFIT) print("\nMelatih model Random Forest...") # Dengan data dimensi RIASEC, kita bisa membebaskan pohon sedikit lebih dalam rf_model = RandomForestClassifier( n_estimators=200, # 200 pohon sudah sangat cukup untuk 30 jurusan max_depth=12, # Cegah menghafal terlalu dalam (Anti Overfitting) min_samples_split=4, # Split akan terjadi jika minimal ada 4 sampel min_samples_leaf=2, # Daun terakhir minimal berisi 2 sampel max_features='sqrt', class_weight='balanced', random_state=42, n_jobs=-1 ) rf_model.fit(X_train, y_train) print("Proses pelatihan selesai!") # %% [4] EVALUASI MODEL print("\nMengevaluasi performa model pada data uji...") y_pred = rf_model.predict(X_test) akurasi = accuracy_score(y_test, y_pred) print(f"\n======================================") print(f"AKURASI MODEL 30 JURUSAN: {akurasi * 100:.2f}%") print(f"======================================") print("\nLaporan Detail Prediksi Keseluruhan:") print(classification_report(y_test, y_pred)) # Cek Feature Importances (Membuktikan bahwa RIASEC akan memiliki bobot besar) importances = rf_model.feature_importances_ feature_names = X.columns feature_imp_df = pd.DataFrame({'Fitur': feature_names, 'Bobot': importances}).sort_values('Bobot', ascending=False) plt.figure(figsize=(10, 8)) sns.barplot(x='Bobot', y='Fitur', data=feature_imp_df, palette='magma') plt.title('Tingkat Kepentingan Fitur (Feature Importances)', fontsize=14) plt.tight_layout() plt.show() # %% [5] SIMPAN MODEL print("\nMenyimpan struktur model yang sudah berhasil dilatih...") joblib.dump(rf_model, 'model_rekomendasi_15mapel.pkl') print("Model berhasil diamankan ke dalam format 'model_rekomendasi_15mapel.pkl'!") # %%