TIFNGK_E41222722/train_model.py

190 lines
6.1 KiB
Python

import os
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import joblib
from utils.helpers import prepare_dataset, save_model, analyze_features
from utils.feature_extraction import FeatureExtractor
def train_knn_model(data_dir='dataset', test_size=0.2, random_state=42):
"""
Train KNN model for PMK detection
"""
print("=" * 50)
print("TRAINING MODEL DETEKSI PMK PADA SAPI")
print("=" * 50)
# 1. Prepare dataset
print("\n1. MENYIAPKAN DATASET...")
features, labels, image_paths = prepare_dataset(data_dir)
print(f"\nJumlah total sampel: {len(features)}")
print("Distribusi kelas:")
unique, counts = np.unique(labels, return_counts=True)
for cls, count in zip(unique, counts):
print(f" {cls}: {count} gambar")
# 2. Encode labels
print("\n2. ENCODING LABELS...")
label_encoder = LabelEncoder()
labels_encoded = label_encoder.fit_transform(labels)
# 3. Split dataset
print("\n3. MEMBAGI DATASET...")
X_train, X_test, y_train, y_test = train_test_split(
features, labels_encoded,
test_size=test_size,
random_state=random_state,
stratify=labels_encoded
)
print(f"Training samples: {X_train.shape[0]}")
print(f"Testing samples: {X_test.shape[0]}")
# 4. Feature scaling
print("\n4. SCALING FEATURES...")
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 5. Train KNN model
print("\n5. TRAINING KNN MODEL...")
knn = KNeighborsClassifier(
n_neighbors=5,
weights='distance',
metric='euclidean',
n_jobs=-1
)
knn.fit(X_train_scaled, y_train)
# 6. Evaluate model
print("\n6. EVALUASI MODEL...")
y_pred = knn.predict(X_test_scaled)
accuracy = accuracy_score(y_test, y_pred)
print("\n" + "=" * 50)
print("HASIL EVALUASI")
print("=" * 50)
print(f"\nAkurasi Model: {accuracy:.2%}")
print("\nClassification Report:")
print(classification_report(y_test, y_pred,
target_names=label_encoder.classes_))
print("Confusion Matrix:")
cm = confusion_matrix(y_test, y_pred)
print(cm)
# Calculate precision, recall, F1-score
tn, fp, fn, tp = cm.ravel()
precision = tp / (tp + fp) if (tp + fp) > 0 else 0
recall = tp / (tp + fn) if (tp + fn) > 0 else 0
f1 = 2 * precision * recall / (precision + recall) if (precision + recall) > 0 else 0
print(f"\nPrecision: {precision:.2%}")
print(f"Recall: {recall:.2%}")
print(f"F1-Score: {f1:.2%}")
# 7. Save model
print("\n7. MENYIMPAN MODEL...")
save_model(knn, scaler, label_encoder)
# 8. Save features to separate CSV files
print("\n8. MENYIMPAN FITUR KE CSV...")
extractor = FeatureExtractor()
os.makedirs('features', exist_ok=True)
# Separate features by class
healthy_features = []
sick_features = []
for feat, label in zip(features, labels):
if label == 'sehat':
healthy_features.append(feat)
else:
sick_features.append(feat)
# Save to CSV
if healthy_features:
df_healthy = extractor.save_features_to_csv(
healthy_features,
['sehat'] * len(healthy_features),
'features/features_healthy.csv'
)
print(f" Fitur sehat: {len(df_healthy)} sampel")
if sick_features:
df_sick = extractor.save_features_to_csv(
sick_features,
['sakit'] * len(sick_features),
'features/features_sick.csv'
)
print(f" Fitur sakit: {len(df_sick)} sampel")
# Save all features
all_features_df = pd.DataFrame(features, columns=extractor.feature_names)
all_features_df['label'] = labels
all_features_df.to_csv('features/all_features.csv', index=False)
# 9. Analyze features
print("\n9. ANALISIS FITUR...")
analyze_features()
# Calculate feature statistics
print("\nRATA-RATA FITUR PER KELAS:")
stats = all_features_df.groupby('label').mean()
print(stats)
# Save model performance
performance = {
'accuracy': accuracy,
'precision': precision,
'recall': recall,
'f1_score': f1,
'training_samples': X_train.shape[0],
'testing_samples': X_test.shape[0]
}
perf_df = pd.DataFrame([performance])
perf_df.to_csv('results/model_performance.csv', index=False)
print("\n" + "=" * 50)
print("TRAINING SELESAI!")
print("=" * 50)
print(f"\nAkurasi model: {accuracy:.2%}")
print("Model disimpan di: models/knn_model.pkl")
print("Fitur disimpan di: features/")
print("Hasil analisis di: results/")
return knn, scaler, label_encoder, accuracy
if __name__ == "__main__":
# Check dataset structure
if not os.path.exists('dataset'):
print("ERROR: Folder 'dataset' tidak ditemukan!")
print("\nBuat struktur folder berikut:")
print("pmk_detection_desktop/")
print("├── dataset/")
print("│ ├── healthy/ (isi dengan gambar sapi sehat)")
print("│ └── sick/ (isi dengan gambar sapi sakit)")
print("└── ...")
# Create directories
os.makedirs('dataset/healthy', exist_ok=True)
os.makedirs('dataset/sick', exist_ok=True)
os.makedirs('features', exist_ok=True)
os.makedirs('models', exist_ok=True)
os.makedirs('results', exist_ok=True)
print("\nFolder telah dibuat. Silakan tambahkan gambar ke:")
print(" - dataset/healthy/ untuk gambar sapi sehat")
print(" - dataset/sick/ untuk gambar sapi sakit")
print("\nKemudian jalankan script ini kembali.")
else:
# Train model
model, scaler, label_encoder, accuracy = train_knn_model()