| |
|
| |
|
| | import neat
|
| | import numpy as np
|
| | import os
|
| | import logging
|
| | import pickle
|
| | import datetime
|
| | import traceback
|
| |
|
| |
|
| | from sklearn.datasets import make_classification
|
| | from sklearn.model_selection import train_test_split
|
| | from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
|
| |
|
| |
|
| | log_filename = f"quanta_log_v6_classifier_{datetime.datetime.now():%Y%m%d_%H%M%S}.log"
|
| | logging.basicConfig(
|
| | level=logging.INFO,
|
| | format='%(asctime)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s',
|
| | handlers=[
|
| | logging.FileHandler(log_filename),
|
| | logging.StreamHandler()
|
| | ]
|
| | )
|
| | logger = logging.getLogger(__name__)
|
| |
|
| | logger.info("="*70)
|
| | logger.info("Quanta Classifier Başlatılıyor (Sürüm 6 - Veri Seti ile Sınıflandırma)")
|
| | logger.info(f"Başlangıç Zamanı: {datetime.datetime.now()}")
|
| | logger.info("="*70)
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | X_train, X_test, y_train, y_test = None, None, None, None
|
| |
|
| |
|
| | def prepare_data(n_samples=500, n_features=2, n_informative=2, n_redundant=0, random_state=42):
|
| | """
|
| | Scikit-learn kullanarak sentetik bir sınıflandırma veri seti oluşturur ve böler.
|
| | """
|
| | global X_train, X_test, y_train, y_test
|
| | logger.info(f"{n_samples} örnekli, {n_features} özellikli sentetik veri seti oluşturuluyor...")
|
| |
|
| | X, y = make_classification(
|
| | n_samples=n_samples,
|
| | n_features=n_features,
|
| | n_informative=n_informative,
|
| | n_redundant=n_redundant,
|
| | n_clusters_per_class=1,
|
| | flip_y=0.05,
|
| | random_state=random_state
|
| | )
|
| |
|
| | X_train, X_test, y_train, y_test = train_test_split(
|
| | X, y, test_size=0.3, random_state=random_state, stratify=y
|
| | )
|
| | logger.info(f"Veri seti bölündü: {len(X_train)} eğitim, {len(X_test)} test örneği.")
|
| | logger.info(f"Girdi Boyutu (Özellik Sayısı): {X_train.shape[1]}")
|
| | logger.info(f"Sınıf Dağılımı (Eğitim): {np.bincount(y_train)}")
|
| |
|
| |
|
| |
|
| | def eval_genomes_classification(genomes, config):
|
| | """
|
| | Genomları eğitim verisi üzerindeki sınıflandırma doğruluğuna göre değerlendirir.
|
| | """
|
| | global X_train, y_train
|
| |
|
| | if X_train is None or y_train is None:
|
| | logger.error("Eğitim verisi yüklenmemiş! Fitness hesaplanamıyor.")
|
| |
|
| | for genome_id, genome in genomes:
|
| | genome.fitness = -1.0
|
| | return
|
| |
|
| | for genome_id, genome in genomes:
|
| | genome.fitness = 0.0
|
| | try:
|
| | net = neat.nn.FeedForwardNetwork.create(genome, config)
|
| | except Exception as e:
|
| | logger.error(f"Genome {genome_id} ağ oluşturma hatası: {e}")
|
| | genome.fitness = -1.0
|
| | continue
|
| |
|
| | correct_predictions = 0
|
| |
|
| | for xi, yi in zip(X_train, y_train):
|
| | try:
|
| | output = net.activate(xi)
|
| |
|
| | prediction = 1 if output[0] >= 0.5 else 0
|
| | if prediction == yi:
|
| | correct_predictions += 1
|
| | except Exception as e:
|
| |
|
| | pass
|
| |
|
| |
|
| | accuracy = correct_predictions / len(y_train)
|
| | genome.fitness = accuracy
|
| |
|
| |
|
| |
|
| |
|
| | def run_neat(config_file, generations=100):
|
| | """
|
| | NEAT evrimini başlatır, yönetir ve sonucu değerlendirir.
|
| | """
|
| | logger.info(f"NEAT yapılandırması yükleniyor: {config_file}")
|
| | config = None
|
| | try:
|
| | config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
|
| | neat.DefaultSpeciesSet, neat.DefaultStagnation,
|
| | config_file)
|
| | logger.info(f"Yapılandırma: Giriş={config.genome_config.num_inputs}, Çıkış={config.genome_config.num_outputs}, Pop={config.pop_size}, Eşik={config.fitness_threshold}")
|
| |
|
| | if config.genome_config.num_inputs != X_train.shape[1]:
|
| | logger.error(f"Yapılandırma hatası: Config'deki girdi sayısı ({config.genome_config.num_inputs}) veri özelliği sayısı ({X_train.shape[1]}) ile eşleşmiyor!")
|
| | return None
|
| |
|
| | if config.genome_config.num_outputs != 1:
|
| | logger.warning(f"Yapılandırma uyarısı: Binary sınıflandırma için çıktı sayısı ({config.genome_config.num_outputs}) genellikle 1 olmalıdır.")
|
| |
|
| | except Exception as e:
|
| | logger.critical(f"Yapılandırma dosyası yüklenemedi: {config_file} - Hata: {e}")
|
| | return None
|
| |
|
| | logger.info("Yeni popülasyon oluşturuluyor...")
|
| | p = neat.Population(config)
|
| |
|
| |
|
| | p.add_reporter(neat.StdOutReporter(True))
|
| | stats = neat.StatisticsReporter()
|
| | p.add_reporter(stats)
|
| | checkpoint_prefix = 'neat-checkpoint-v6-'
|
| | p.add_reporter(neat.Checkpointer(generation_interval=20, filename_prefix=checkpoint_prefix))
|
| | logger.info(f"Checkpoint dosyaları '{checkpoint_prefix}*' olarak kaydedilecek.")
|
| |
|
| | logger.info(f"Evrim başlıyor (Maksimum {generations} nesil)...")
|
| | winner = None
|
| | try:
|
| |
|
| | winner = p.run(eval_genomes_classification, generations)
|
| | logger.info(' ' + "="*30 + " Evrim Tamamlandı " + "="*30)
|
| | except Exception as e:
|
| | logger.critical(f"Evrim sırasında kritik bir hata oluştu: {e}")
|
| | logger.error(traceback.format_exc())
|
| | if not winner and p and p.best_genome:
|
| | logger.warning("Evrim hata ile durdu, bulunan son en iyi genom kullanılıyor.")
|
| | winner = p.best_genome
|
| |
|
| |
|
| | if winner:
|
| | logger.info(f'En iyi genom bulundu/kullanıldı (Fitness - Eğitim Doğruluğu: {winner.fitness:.6f}):')
|
| | num_nodes = len(winner.nodes)
|
| | num_connections = len(winner.connections)
|
| | logger.info(f'Kazanan Karmaşıklığı: {num_nodes} Düğüm, {num_connections} Bağlantı')
|
| |
|
| |
|
| | winner_filename = "winner_classifier_v6.pkl"
|
| | try:
|
| | with open(winner_filename, 'wb') as f:
|
| | pickle.dump(winner, f)
|
| | logger.info(f"En iyi genom '{winner_filename}' dosyasına başarıyla kaydedildi.")
|
| | except Exception as e:
|
| | logger.error(f"En iyi genom kaydedilemedi: {e}")
|
| |
|
| |
|
| | logger.info(" " + "="*20 + " En İyi Genomun Test Seti Performansı " + "="*20)
|
| | try:
|
| | if config is None:
|
| | logger.error("Yapılandırma yüklenemediği için final test atlanıyor.")
|
| | raise RuntimeError("Config object is None.")
|
| |
|
| | winner_net = neat.nn.FeedForwardNetwork.create(winner, config)
|
| |
|
| |
|
| | y_pred = []
|
| | logger.info(f"Test seti ({len(X_test)} örnek) üzerinde tahminler yapılıyor...")
|
| | for xi in X_test:
|
| | output = winner_net.activate(xi)
|
| | prediction = 1 if output[0] >= 0.5 else 0
|
| | y_pred.append(prediction)
|
| |
|
| |
|
| | accuracy_test = accuracy_score(y_test, y_pred)
|
| | conf_matrix = confusion_matrix(y_test, y_pred)
|
| | class_report = classification_report(y_test, y_pred)
|
| |
|
| | logger.info(f"\n--- Test Seti Sonuçları ---")
|
| | logger.info(f"Doğruluk (Accuracy): {accuracy_test:.4f}")
|
| | logger.info(f"\nKarışıklık Matrisi (Confusion Matrix):\n{conf_matrix}")
|
| | logger.info(f"\nSınıflandırma Raporu:\n{class_report}")
|
| | logger.info("---------------------------\n")
|
| |
|
| | except Exception as e:
|
| | logger.error(f"En iyi genom test edilirken hata oluştu: {e}")
|
| | logger.error(traceback.format_exc())
|
| | else:
|
| | logger.warning("Evrim sonunda test edilecek bir kazanan genom bulunamadı.")
|
| |
|
| | logger.info("="*70)
|
| | logger.info("Quanta Classifier Adım 6 (Veri Seti ile Sınıflandırma) tamamlandı.")
|
| | logger.info(f"Bitiş Zamanı: {datetime.datetime.now()}")
|
| | logger.info("="*70)
|
| |
|
| |
|
| |
|
| | if __name__ == '__main__':
|
| |
|
| | local_dir = os.path.dirname(os.path.abspath(__file__))
|
| |
|
| | config_path = os.path.join(local_dir, 'config-classification-v6.txt')
|
| |
|
| | if not os.path.exists(config_path):
|
| | logger.critical(f"Yapılandırma dosyası bulunamadı: {config_path}")
|
| | else:
|
| | try:
|
| |
|
| | prepare_data(n_samples=1000, n_features=2, n_informative=2, random_state=123)
|
| |
|
| |
|
| |
|
| | MAX_GENERATIONS_RUN = 150
|
| | run_neat(config_path, generations=MAX_GENERATIONS_RUN)
|
| |
|
| | except ImportError as ie:
|
| | logger.critical(f"Gerekli kütüphane bulunamadı: {ie}")
|
| | logger.critical("Lütfen 'pip install scikit-learn numpy neat-python' komutu ile kurun.")
|
| | except Exception as main_e:
|
| | logger.critical(f"Ana program akışında beklenmedik bir hata oluştu: {main_e}")
|
| | logger.error(traceback.format_exc()) |