459 lines
19 KiB
Plaintext
459 lines
19 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "a954725d",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# 1 extraction features TF-IDF\n",
|
||
"import pandas as pd\n",
|
||
"import joblib\n",
|
||
"import os\n",
|
||
"from sklearn.feature_extraction.text import TfidfVectorizer\n",
|
||
"from sklearn.model_selection import train_test_split\n",
|
||
"\n",
|
||
"print(\"🔄 [TAHAP 1] Memulai Preprocessing & TF-IDF...\")\n",
|
||
"\n",
|
||
"# --- CONFIG ---\n",
|
||
"# Gunakan Absolute Path dengan 'r' di depan agar aman di Windows\n",
|
||
"FILE_DATA = r'd:\\project skripsi machine learning intoleransi\\virtualEnvironment\\dataset\\dataYangDiPakai\\data_label_revisi_goblog.csv' \n",
|
||
"\n",
|
||
"# 0. CEK KEAMANAN FILE SEBELUM JALAN\n",
|
||
"if not os.path.exists(FILE_DATA):\n",
|
||
" raise FileNotFoundError(f\"❌ File tidak ditemukan di jalur:\\n{FILE_DATA}\\nCoba pastikan nama file dan foldernya sudah persis sama!\")\n",
|
||
"\n",
|
||
"# Bikin folder otomatis\n",
|
||
"os.makedirs('output', exist_ok=True) \n",
|
||
"os.makedirs('models', exist_ok=True) \n",
|
||
"\n",
|
||
"# 1. LOAD DATA\n",
|
||
"print(\" - Membaca dataset...\")\n",
|
||
"df = pd.read_csv(FILE_DATA, sep=';') \n",
|
||
"\n",
|
||
"# Cek keamanan kolom (Biar tidak error kalau nama kolom salah)\n",
|
||
"if 'terjemahan_indo' not in df.columns or 'label' not in df.columns:\n",
|
||
" print(f\"Daftar kolom yang ada di filemu: {df.columns.tolist()}\")\n",
|
||
" raise KeyError(\"❌ Kolom 'terjemahan_indo' atau 'label' tidak ada! Coba cek tulisan di atas, pastikan namanya cocok.\")\n",
|
||
"\n",
|
||
"# Bersihkan data kosong\n",
|
||
"df = df.dropna(subset=['terjemahan_indo', 'label']) \n",
|
||
"print(f\" - Total data bersih yang siap diproses: {len(df)} baris\")\n",
|
||
"\n",
|
||
"# 2. TF-IDF (Ubah Huruf jadi Angka)\n",
|
||
"print(\" - Melakukan ekstraksi fitur TF-IDF...\")\n",
|
||
"vectorizer = TfidfVectorizer(max_features=5000)\n",
|
||
"X = vectorizer.fit_transform(df['terjemahan_indo'].astype(str))\n",
|
||
"y = df['label'].astype(int) # Pastikan label berupa angka (0, 1, 2)\n",
|
||
"\n",
|
||
"# 3. SIMPAN KAMUS TF-IDF\n",
|
||
"joblib.dump(vectorizer, 'models/vectorizer_tfidf.pkl')\n",
|
||
"\n",
|
||
"# 4. SPLIT DATA (80% Latih, 20% Uji)\n",
|
||
"print(\" - Memecah data (80% Data Latih, 20% Data Uji)...\")\n",
|
||
"X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
|
||
"\n",
|
||
"# 5. SIMPAN DATA MATANG\n",
|
||
"print(\" - Menyimpan data matang ke folder 'output'...\")\n",
|
||
"joblib.dump(X_train, 'output/X_train.pkl')\n",
|
||
"joblib.dump(X_test, 'output/X_test.pkl')\n",
|
||
"joblib.dump(y_train, 'output/y_train.pkl')\n",
|
||
"joblib.dump(y_test, 'output/y_test.pkl')\n",
|
||
"\n",
|
||
"print(\"✅ SELESAI TAHAP 1. Data sudah siap!\")\n",
|
||
"print(\"👉 Silakan lanjut jalankan '2_training.py' atau '2_training.ipynb'\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "15e21017",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# 2 pelatihan model SVM, KNN dan ensemble\n",
|
||
"import joblib\n",
|
||
"import pandas as pd\n",
|
||
"import os\n",
|
||
"from sklearn.svm import SVC\n",
|
||
"from sklearn.neighbors import KNeighborsClassifier\n",
|
||
"from sklearn.ensemble import VotingClassifier\n",
|
||
"from sklearn.model_selection import GridSearchCV\n",
|
||
"\n",
|
||
"print(\"🏋️ [TAHAP 2] Training: DATA ASLI (Tanpa Penyeimbang Apapun)...\")\n",
|
||
"\n",
|
||
"# 0. CEK KEAMANAN: Pastikan folder dan file Tahap 1 sudah ada\n",
|
||
"if not os.path.exists('output/X_train.pkl'):\n",
|
||
" raise FileNotFoundError(\"❌ File 'output/X_train.pkl' tidak ditemukan! Pastikan kamu sudah menjalankan '1_preprocessing.py' terlebih dahulu.\")\n",
|
||
"os.makedirs('models', exist_ok=True) # Jaga-jaga kalau folder models terhapus\n",
|
||
"\n",
|
||
"# 1. AMBIL DATA DARI TAHAP 1\n",
|
||
"print(\" - Memuat data latih...\")\n",
|
||
"X_train = joblib.load('output/X_train.pkl')\n",
|
||
"y_train = joblib.load('output/y_train.pkl')\n",
|
||
"\n",
|
||
"print(f\" - Jumlah Data Latih Asli: {len(y_train)} baris\")\n",
|
||
"print(f\" - Komposisi Label: {y_train.value_counts().to_dict()}\")\n",
|
||
"\n",
|
||
"# ---------------------------------------------------------\n",
|
||
"# 2. LATIH SVM (MODEL UTAMA)\n",
|
||
"# ---------------------------------------------------------\n",
|
||
"print(\"\\n🚀 Melatih SVM (Mencari Settingan Terbaik)...\")\n",
|
||
"print(\" (Mohon tunggu, ini akan memakan waktu beberapa menit ☕)\")\n",
|
||
"\n",
|
||
"param_svm = {\n",
|
||
" 'C': [0.1, 1, 10],\n",
|
||
" 'kernel': ['linear', 'rbf'],\n",
|
||
" 'gamma': ['scale', 'auto']\n",
|
||
"}\n",
|
||
"\n",
|
||
"# n_jobs=-1 artinya kita memakai seluruh \"otak\" CPU laptop agar cepat selesai\n",
|
||
"svm_grid = GridSearchCV(SVC(probability=True, random_state=42), param_svm, cv=3, verbose=1, n_jobs=-1)\n",
|
||
"svm_grid.fit(X_train, y_train) \n",
|
||
"\n",
|
||
"best_svm = svm_grid.best_estimator_\n",
|
||
"joblib.dump(best_svm, 'models/model_svm.pkl')\n",
|
||
"print(f\" ✅ SVM Selesai (Akurasi Validasi: {svm_grid.best_score_*100:.2f}%)\")\n",
|
||
"\n",
|
||
"# ---------------------------------------------------------\n",
|
||
"# 3. LATIH KNN (METRIC COSINE)\n",
|
||
"# ---------------------------------------------------------\n",
|
||
"print(\"\\n🚀 Melatih KNN (Wajib Cosine)...\")\n",
|
||
"\n",
|
||
"param_knn = {\n",
|
||
" 'n_neighbors': [3, 5, 7, 9, 11, 15], \n",
|
||
" 'metric': ['cosine'] \n",
|
||
"}\n",
|
||
"\n",
|
||
"knn_grid = GridSearchCV(KNeighborsClassifier(), param_knn, cv=3, verbose=1, n_jobs=-1)\n",
|
||
"knn_grid.fit(X_train, y_train)\n",
|
||
"\n",
|
||
"best_knn = knn_grid.best_estimator_\n",
|
||
"joblib.dump(best_knn, 'models/model_knn.pkl')\n",
|
||
"print(f\" ✅ KNN Selesai (Best K: {knn_grid.best_params_['n_neighbors']})\")\n",
|
||
"\n",
|
||
"# ---------------------------------------------------------\n",
|
||
"# 4. LATIH ENSEMBLE (SVM + KNN)\n",
|
||
"# ---------------------------------------------------------\n",
|
||
"print(\"\\n🚀 Melatih ENSEMBLE (Voting SVM + KNN)...\")\n",
|
||
"\n",
|
||
"# Gabungkan dua model terbaik\n",
|
||
"ensemble_model = VotingClassifier(\n",
|
||
" estimators=[\n",
|
||
" ('svm', best_svm), \n",
|
||
" ('knn', best_knn)\n",
|
||
" ],\n",
|
||
" voting='soft',\n",
|
||
" weights=[2, 1] # SVM kita beri bobot suara lebih tinggi\n",
|
||
")\n",
|
||
"\n",
|
||
"ensemble_model.fit(X_train, y_train)\n",
|
||
"joblib.dump(ensemble_model, 'models/model_ensemble.pkl')\n",
|
||
"print(\" ✅ Ensemble Selesai.\")\n",
|
||
"\n",
|
||
"print(\"\\n==================================================\")\n",
|
||
"print(\"🎉 TRAINING DATA MURNI SELESAI!\")\n",
|
||
"print(\"👉 Silakan jalankan '3_evaluasi.py' untuk melihat hasil akhirnya.\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "38511828",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# 3 evaluasi hasil model\n",
|
||
"import joblib\n",
|
||
"import matplotlib.pyplot as plt\n",
|
||
"import seaborn as sns\n",
|
||
"from sklearn.metrics import accuracy_score, classification_report, confusion_matrix\n",
|
||
"import os\n",
|
||
"\n",
|
||
"print(\"📊 [TAHAP 3] Evaluasi Hasil Model...\")\n",
|
||
"\n",
|
||
"# 0. CEK KEAMANAN\n",
|
||
"if not os.path.exists('output/X_test.pkl'):\n",
|
||
" raise FileNotFoundError(\"❌ File 'output/X_test.pkl' tidak ditemukan! Pastikan Tahap 1 sudah dijalankan.\")\n",
|
||
"if not os.path.exists('models/model_svm.pkl'):\n",
|
||
" raise FileNotFoundError(\"❌ File 'models/model_svm.pkl' tidak ditemukan! Pastikan Tahap 2 sudah selesai 100%.\")\n",
|
||
"\n",
|
||
"# Bikin folder images otomatis\n",
|
||
"os.makedirs('images', exist_ok=True)\n",
|
||
"\n",
|
||
"# 1. Ambil Data Uji\n",
|
||
"print(\" - Memuat data uji...\")\n",
|
||
"X_test = joblib.load('output/X_test.pkl')\n",
|
||
"y_test = joblib.load('output/y_test.pkl')\n",
|
||
"\n",
|
||
"# 2. Daftar Model (CUMA 3 SEKARANG)\n",
|
||
"print(\" - Memuat model-model AI...\")\n",
|
||
"daftar_model = {\n",
|
||
" \"SVM\": joblib.load('models/model_svm.pkl'),\n",
|
||
" \"KNN\": joblib.load('models/model_knn.pkl'),\n",
|
||
" \"Ensemble\": joblib.load('models/model_ensemble.pkl')\n",
|
||
"}\n",
|
||
"\n",
|
||
"# 3. Loop Evaluasi\n",
|
||
"for nama, model in daftar_model.items():\n",
|
||
" print(f\"\\n==========================================\")\n",
|
||
" print(f\"--- Evaluasi Model: {nama} ---\")\n",
|
||
" print(f\"==========================================\")\n",
|
||
"\n",
|
||
" # Lakukan Prediksi\n",
|
||
" y_pred = model.predict(X_test)\n",
|
||
" \n",
|
||
" # Hitung Akurasi\n",
|
||
" acc = accuracy_score(y_test, y_pred)\n",
|
||
" print(f\"🎯 Akurasi {nama}: {acc*100:.2f}%\\n\")\n",
|
||
" \n",
|
||
" # Laporan Lengkap (Precision, Recall, F1-Score)\n",
|
||
" print(\"📋 Laporan Klasifikasi:\")\n",
|
||
" print(classification_report(y_test, y_pred))\n",
|
||
"\n",
|
||
" # Bikin Grafik Confusion Matrix\n",
|
||
" cm = confusion_matrix(y_test, y_pred)\n",
|
||
" plt.figure(figsize=(7, 5))\n",
|
||
" sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', \n",
|
||
" annot_kws={\"size\": 14}) # Angka di dalam kotak diperbesar\n",
|
||
" \n",
|
||
" # Hiasan Grafik (Lebih rapi untuk masuk ke buku Skripsi)\n",
|
||
" plt.title(f'Confusion Matrix - {nama}\\n(Akurasi: {acc*100:.2f}%)', fontsize=14, fontweight='bold', pad=15)\n",
|
||
" plt.xlabel('Prediksi Mesin', fontsize=12, fontweight='bold')\n",
|
||
" plt"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "ff1f299c",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# 3.2 Menampilkan Distribusi Data\n",
|
||
"# Menampilkan perbandingan jumlah data dan tampilan grafik perbandingan data\n",
|
||
"import pandas as pd\n",
|
||
"import matplotlib.pyplot as plt\n",
|
||
"import seaborn as sns\n",
|
||
"import os\n",
|
||
"\n",
|
||
"# Pastikan folder images ada untuk menyimpan hasil\n",
|
||
"os.makedirs('images', exist_ok=True)\n",
|
||
"\n",
|
||
"# ==========================================\n",
|
||
"# 1. LOAD DATA\n",
|
||
"# ==========================================\n",
|
||
"nama_file = r'd:\\project skripsi machine learning intoleransi\\virtualEnvironment\\dataset\\dataYangDiPakai\\data_label_revisi_goblog.csv'\n",
|
||
"\n",
|
||
"print(f\"📂 Membaca file: {nama_file}...\")\n",
|
||
"df = pd.read_csv(nama_file, sep=';') \n",
|
||
"\n",
|
||
"# ==========================================\n",
|
||
"# 2. HITUNG JUMLAH LABEL\n",
|
||
"# ==========================================\n",
|
||
"# Kita pastikan kolom 'label' ada\n",
|
||
"if 'label' not in df.columns:\n",
|
||
" raise ValueError(\"❌ Kolom 'label' tidak ditemukan di dataset! Coba cek separatornya (sep=';' atau sep=',')\")\n",
|
||
"\n",
|
||
"jumlah_label = df['label'].value_counts().sort_index()\n",
|
||
"\n",
|
||
"print(\"\\n📊 STATISTIK JUMLAH DATA:\")\n",
|
||
"print(\"-\" * 30)\n",
|
||
"label_names = {0: \"Netral (0)\", 1: \"Kritik (1)\", 2: \"Hujatan (2)\"}\n",
|
||
"for lbl, count in jumlah_label.items():\n",
|
||
" print(f\" {label_names.get(lbl, lbl)}: {count} data\")\n",
|
||
"print(\"-\" * 30)\n",
|
||
"print(f\" TOTAL: {len(df)} data\")\n",
|
||
"\n",
|
||
"# ==========================================\n",
|
||
"# 3. BUAT GRAFIK (VISUALISASI)\n",
|
||
"# ==========================================\n",
|
||
"plt.figure(figsize=(8, 6)) # Ukuran gambar (Lebar, Tinggi)\n",
|
||
"\n",
|
||
"# Bikin Bar Chart warna-warni (tambah hue=... agar tidak muncul warning di versi Seaborn terbaru)\n",
|
||
"ax = sns.barplot(x=jumlah_label.index, y=jumlah_label.values, hue=jumlah_label.index, palette='viridis', legend=False)\n",
|
||
"\n",
|
||
"# Hiasan Grafik\n",
|
||
"plt.title('Perbandingan Jumlah Data per Label', fontsize=16, fontweight='bold', pad=15)\n",
|
||
"plt.xlabel('Kategori Label', fontsize=12, fontweight='bold')\n",
|
||
"plt.ylabel('Jumlah Data', fontsize=12, fontweight='bold')\n",
|
||
"\n",
|
||
"# Pastikan urutan label sesuai dengan 0, 1, 2\n",
|
||
"urutan_label = sorted(jumlah_label.index.tolist())\n",
|
||
"plt.xticks(ticks=range(len(urutan_label)), labels=['0\\n(Netral)', '1\\n(Kritik)', '2\\n(Hujatan)'])\n",
|
||
"plt.grid(axis='y', linestyle='--', alpha=0.5)\n",
|
||
"\n",
|
||
"# Tampilkan Angka di Atas Batang\n",
|
||
"for p in ax.patches:\n",
|
||
" ax.annotate(f'{int(p.get_height())}', \n",
|
||
" (p.get_x() + p.get_width() / 2., p.get_height()), \n",
|
||
" ha='center', va='center', \n",
|
||
" xytext=(0, 10), \n",
|
||
" textcoords='offset points',\n",
|
||
" fontsize=14, fontweight='bold', color='black')\n",
|
||
"\n",
|
||
"# Simpan Gambar di dalam folder 'images'\n",
|
||
"nama_gambar = 'images/grafik_distribusi_data.png'\n",
|
||
"plt.savefig(nama_gambar, dpi=300, bbox_inches='tight')\n",
|
||
"print(f\"\\n🖼️ Grafik berhasil disimpan: {nama_gambar}\")\n",
|
||
"\n",
|
||
"# Tampilkan gambar di layar\n",
|
||
"plt.show()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "c2325607",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import joblib\n",
|
||
"import pandas as pd\n",
|
||
"import numpy as np\n",
|
||
"import math\n",
|
||
"import matplotlib.pyplot as plt\n",
|
||
"import os\n",
|
||
"from sklearn.neighbors import KNeighborsClassifier\n",
|
||
"from sklearn.model_selection import cross_val_score, GridSearchCV\n",
|
||
"\n",
|
||
"print(\"🔬 [EKSPERIMEN] Membandingkan 3 Metode Mencari Nilai K Terbaik...\")\n",
|
||
"\n",
|
||
"# 0. CEK KEAMANAN\n",
|
||
"if not os.path.exists('output/X_train.pkl'):\n",
|
||
" raise FileNotFoundError(\"❌ File 'output/X_train.pkl' tidak ditemukan! Pastikan Tahap 1 sudah dijalankan.\")\n",
|
||
"\n",
|
||
"# Pastikan folder images ada\n",
|
||
"os.makedirs('images', exist_ok=True)\n",
|
||
"\n",
|
||
"# 1. LOAD DATA\n",
|
||
"X_train = joblib.load('output/X_train.pkl')\n",
|
||
"y_train = joblib.load('output/y_train.pkl')\n",
|
||
"jumlah_data = X_train.shape[0]\n",
|
||
"\n",
|
||
"print(f\" - Jumlah Data Latih: {jumlah_data} baris\")\n",
|
||
"print(\"-\" * 50)\n",
|
||
"\n",
|
||
"results = [] # Untuk menyimpan hasil perbandingan\n",
|
||
"\n",
|
||
"# =========================================================\n",
|
||
"# METODE 1: AKAR KUADRAT (Square Root Rule)\n",
|
||
"# Rumus: K = Akar(Total Data)\n",
|
||
"# =========================================================\n",
|
||
"print(\"1️⃣ Menguji Metode Akar Kuadrat...\")\n",
|
||
"k_sqrt = int(math.sqrt(jumlah_data))\n",
|
||
"\n",
|
||
"# Aturan: K harus ganjil biar gak seri (draw)\n",
|
||
"if k_sqrt % 2 == 0:\n",
|
||
" k_sqrt += 1\n",
|
||
"\n",
|
||
"# Uji Akurasinya (Pakai n_jobs=-1 biar ngebut)\n",
|
||
"knn_sq = KNeighborsClassifier(n_neighbors=k_sqrt, metric='cosine')\n",
|
||
"scores_sq = cross_val_score(knn_sq, X_train, y_train, cv=5, scoring='accuracy', n_jobs=-1)\n",
|
||
"acc_sq = scores_sq.mean() * 100\n",
|
||
"\n",
|
||
"print(f\" -> Hasil: K={k_sqrt}, Akurasi={acc_sq:.2f}%\")\n",
|
||
"results.append({'Metode': 'Akar Kuadrat', 'K': k_sqrt, 'Akurasi': acc_sq})\n",
|
||
"\n",
|
||
"# =========================================================\n",
|
||
"# METODE 2: ELBOW METHOD (Metode Siku)\n",
|
||
"# Coba manual dari 1 sampai 40, lalu cari error terkecil\n",
|
||
"# =========================================================\n",
|
||
"print(\"\\n2️⃣ Menguji Metode Elbow (Looping 1-40)...\")\n",
|
||
"print(\" (Tunggu sebentar, sedang menghitung manual...)\")\n",
|
||
"error_rates = []\n",
|
||
"acc_rates = []\n",
|
||
"k_range = range(1, 41, 2) # Coba angka ganjil: 1, 3, 5, ... 39\n",
|
||
"\n",
|
||
"best_k_elbow = 0\n",
|
||
"best_acc_elbow = 0\n",
|
||
"\n",
|
||
"for k in k_range:\n",
|
||
" knn = KNeighborsClassifier(n_neighbors=k, metric='cosine')\n",
|
||
" # Pakai n_jobs=-1 di sini juga biar loopingnya gak kelamaan\n",
|
||
" scores = cross_val_score(knn, X_train, y_train, cv=5, scoring='accuracy', n_jobs=-1)\n",
|
||
" acc = scores.mean()\n",
|
||
"\n",
|
||
" # Simpan data buat grafik\n",
|
||
" acc_rates.append(acc)\n",
|
||
" error_rates.append(1 - acc) # Error = 100% - Akurasi\n",
|
||
"\n",
|
||
" # Cek apakah ini rekor terbaik?\n",
|
||
" if acc > best_acc_elbow:\n",
|
||
" best_acc_elbow = acc\n",
|
||
" best_k_elbow = k\n",
|
||
"\n",
|
||
"print(f\" -> Hasil Terbaik di Range Ini: K={best_k_elbow}, Akurasi={best_acc_elbow*100:.2f}%\")\n",
|
||
"results.append({'Metode': 'Elbow (Manual)', 'K': best_k_elbow, 'Akurasi': best_acc_elbow*100})\n",
|
||
"\n",
|
||
"# Bikin Grafik Elbow\n",
|
||
"plt.figure(figsize=(10, 6))\n",
|
||
"plt.plot(k_range, error_rates, color='red', linestyle='dashed', marker='o',\n",
|
||
" markerfacecolor='blue', markersize=8)\n",
|
||
"plt.title('Grafik Elbow (Mencari Error Terkecil)', fontsize=14, fontweight='bold', pad=15)\n",
|
||
"plt.xlabel('Nilai K', fontsize=12, fontweight='bold')\n",
|
||
"plt.ylabel('Tingkat Error', fontsize=12, fontweight='bold')\n",
|
||
"plt.grid(True, linestyle='--', alpha=0.6)\n",
|
||
"\n",
|
||
"# Simpan ke folder images\n",
|
||
"nama_gambar_elbow = 'images/grafik_elbow_knn.png'\n",
|
||
"plt.savefig(nama_gambar_elbow, dpi=300, bbox_inches='tight')\n",
|
||
"print(f\" 🖼️ Grafik Elbow tersimpan: {nama_gambar_elbow}\")\n",
|
||
"plt.close() # Tutup grafik biar memori lega\n",
|
||
"\n",
|
||
"# =========================================================\n",
|
||
"# METODE 3: GRID SEARCH CV (Validasi Silang)\n",
|
||
"# Ini metode paling 'Sultan' dan Valid\n",
|
||
"# =========================================================\n",
|
||
"print(\"\\n3️⃣ Menguji Metode Grid Search CV (Otomatis)...\")\n",
|
||
"param_grid = {'n_neighbors': [3, 5, 7, 9, 11, 15, 19, 21, 25, 29]}\n",
|
||
"grid = GridSearchCV(KNeighborsClassifier(metric='cosine'), param_grid, cv=5, scoring='accuracy', n_jobs=-1)\n",
|
||
"grid.fit(X_train, y_train)\n",
|
||
"\n",
|
||
"k_grid = grid.best_params_['n_neighbors']\n",
|
||
"acc_grid = grid.best_score_ * 100\n",
|
||
"\n",
|
||
"print(f\" -> Hasil: K={k_grid}, Akurasi={acc_grid:.2f}%\")\n",
|
||
"results.append({'Metode': 'Grid Search CV', 'K': k_grid, 'Akurasi': acc_grid})\n",
|
||
"\n",
|
||
"# =========================================================\n",
|
||
"# KESIMPULAN AKHIR\n",
|
||
"# =========================================================\n",
|
||
"print(\"\\n\" + \"=\"*50)\n",
|
||
"print(\"🏆 TABEL PERBANDINGAN METODE PENENTUAN K\")\n",
|
||
"print(\"=\"*50)\n",
|
||
"df_res = pd.DataFrame(results)\n",
|
||
"print(df_res.to_string(index=False))\n",
|
||
"print(\"-\" * 50)\n",
|
||
"\n",
|
||
"# Cari pemenang\n",
|
||
"best_method = df_res.loc[df_res['Akurasi'].idxmax()]\n",
|
||
"print(f\"✅ REKOMENDASI: Gunakan K = {best_method['K']}\")\n",
|
||
"print(f\" (Berdasarkan metode {best_method['Metode']} dengan akurasi tertinggi)\")"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "virtualEnvironment",
|
||
"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.11.9"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 5
|
||
}
|