Add Deep Learning (LSTM) + Quick Wins automation features
Major improvements: - Deep Learning integration with PyTorch LSTM (dual models: main 1-50 + euro 1-12) - Hybrid predictor: 40% RandomForest + 60% Deep Learning - LaunchAgent for automatic weekly tip generation (Mon/Thu 21:00) - Health-Check system with auto-recovery and Telegram alerts - Fixed health checks for Eurojackpot-specific paths and file names - Model caching and intelligent retraining logic - Updated CSV data and generated tips - Performance reports for recent draws Technical details: - PyTorch used instead of TensorFlow (Python 3.14 compatibility) - Separate LSTM models for main numbers (1-50) and euro numbers (1-12) - Apple Silicon MPS acceleration support - Sequence learning with 20-draw history - Health-check adapted for eurojackpot_ml_models/ and learning_log.json 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -57,15 +57,35 @@ try:
|
||||
except ImportError:
|
||||
ML_AVAILABLE = False
|
||||
|
||||
# Deep Learning (optional)
|
||||
# Deep Learning (optional) - PyTorch or TensorFlow
|
||||
DEEP_LEARNING_AVAILABLE = False
|
||||
try:
|
||||
import tensorflow as tf
|
||||
from tensorflow.keras.models import Sequential
|
||||
from tensorflow.keras.layers import LSTM, Dense, Dropout
|
||||
from tensorflow.keras.optimizers import Adam
|
||||
import torch
|
||||
DEEP_LEARNING_AVAILABLE = True
|
||||
except ImportError:
|
||||
DEEP_LEARNING_AVAILABLE = False
|
||||
try:
|
||||
import tensorflow as tf
|
||||
from tensorflow.keras.models import Sequential
|
||||
from tensorflow.keras.layers import LSTM, Dense, Dropout
|
||||
from tensorflow.keras.optimizers import Adam
|
||||
DEEP_LEARNING_AVAILABLE = True
|
||||
except ImportError:
|
||||
DEEP_LEARNING_AVAILABLE = False
|
||||
|
||||
# Import Deep Learning Engine (PyTorch-based for Python 3.14+ compatibility)
|
||||
import sys
|
||||
try:
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'utils'))
|
||||
from deep_learning_engine_pytorch import DeepLearningEngine, HybridDeepLearningPredictor
|
||||
DL_ENGINE_AVAILABLE = True
|
||||
except ImportError:
|
||||
try:
|
||||
from deep_learning_engine import DeepLearningEngine, HybridDeepLearningPredictor
|
||||
DL_ENGINE_AVAILABLE = True
|
||||
except ImportError:
|
||||
DL_ENGINE_AVAILABLE = False
|
||||
DeepLearningEngine = None
|
||||
HybridDeepLearningPredictor = None
|
||||
|
||||
|
||||
class UltimateAIMLEurojackpotGenerator:
|
||||
@@ -176,11 +196,14 @@ class UltimateAIMLEurojackpotGenerator:
|
||||
"""Zeigt System-Status."""
|
||||
print("\n📊 SYSTEM STATUS:")
|
||||
print(f" 🧠 ML Available: {'✅' if ML_AVAILABLE else '❌ (pip install scikit-learn)'}")
|
||||
print(f" 🚀 Deep Learning: {'✅' if DEEP_LEARNING_AVAILABLE else '⚠️ Optional'}")
|
||||
print(f" 🚀 Deep Learning: {'✅ ACTIVE' if self.ai_ml_engine.use_deep_learning else '⚠️ Optional (pip install tensorflow)'}")
|
||||
print(f" 🎯 Models Trained: {'✅' if self.is_trained else '⚠️ Using fallback'}")
|
||||
print(f" 📁 Data Size: {len(self.df):,} drawings")
|
||||
print(f" 🎨 Patterns: {len(self.pattern_engine.pattern_frequencies)}")
|
||||
print(f" ⚡ Fast Mode: {'ON' if self.fast_mode else 'OFF'}")
|
||||
if self.ai_ml_engine.use_deep_learning:
|
||||
print(f" 🔮 LSTM: Hybrid Mode (RF 40% + DL 60%)")
|
||||
print(f" 📊 Main Numbers: 1-50 | Euro Numbers: 1-12")
|
||||
|
||||
def generate_ultimate_tips(self, num_tips=10):
|
||||
"""
|
||||
@@ -662,8 +685,8 @@ class UltimateAIMLEurojackpotGenerator:
|
||||
# ============================================================================
|
||||
|
||||
class EurojackpotAIMLEngine:
|
||||
"""AI/ML Engine für Eurojackpot."""
|
||||
|
||||
"""AI/ML Engine für Eurojackpot mit Deep Learning Support."""
|
||||
|
||||
def __init__(self, fast_mode=True):
|
||||
self.models_main = {}
|
||||
self.models_euro = {}
|
||||
@@ -672,11 +695,20 @@ class EurojackpotAIMLEngine:
|
||||
self.scaler = StandardScaler()
|
||||
self.is_trained = False
|
||||
self.fast_mode = fast_mode
|
||||
|
||||
# Deep Learning
|
||||
self.dl_engine_main = None
|
||||
self.dl_engine_euro = None
|
||||
self.hybrid_predictor_main = None
|
||||
self.hybrid_predictor_euro = None
|
||||
self.use_deep_learning = DL_ENGINE_AVAILABLE and DEEP_LEARNING_AVAILABLE
|
||||
|
||||
def initialize(self, df, features_df, cache_path):
|
||||
"""Initialisiert AI/ML mit intelligentem Retraining."""
|
||||
self.cache_path = cache_path
|
||||
self.data_file = None # Wird vom Generator gesetzt
|
||||
self.df = df # Store for DL
|
||||
self.features_df = features_df # Store for DL
|
||||
|
||||
if not ML_AVAILABLE:
|
||||
print(" ⚠️ ML not available - using fallback")
|
||||
@@ -715,6 +747,49 @@ class EurojackpotAIMLEngine:
|
||||
else:
|
||||
print(" ⚠️ Insufficient data - using fallback")
|
||||
|
||||
# Initialize Deep Learning
|
||||
if self.use_deep_learning:
|
||||
print(" 🧠 Initializing Deep Learning (LSTM)...", end=" ", flush=True)
|
||||
try:
|
||||
# Main numbers (1-50)
|
||||
self.dl_engine_main = DeepLearningEngine(
|
||||
num_numbers=50,
|
||||
sequence_length=20,
|
||||
cache_dir=os.path.join(cache_path, 'deep_learning_main'),
|
||||
fast_mode=self.fast_mode
|
||||
)
|
||||
self.dl_engine_main.train(df, features_df, force_retrain=needs_retrain)
|
||||
|
||||
# Euro numbers (1-12)
|
||||
self.dl_engine_euro = DeepLearningEngine(
|
||||
num_numbers=12,
|
||||
sequence_length=20,
|
||||
cache_dir=os.path.join(cache_path, 'deep_learning_euro'),
|
||||
fast_mode=self.fast_mode
|
||||
)
|
||||
self.dl_engine_euro.train(df, features_df, force_retrain=needs_retrain)
|
||||
|
||||
# Create hybrid predictors
|
||||
self.hybrid_predictor_main = HybridDeepLearningPredictor(
|
||||
dl_engine=self.dl_engine_main,
|
||||
rf_weight=0.4,
|
||||
dl_weight=0.6
|
||||
)
|
||||
self.hybrid_predictor_euro = HybridDeepLearningPredictor(
|
||||
dl_engine=self.dl_engine_euro,
|
||||
rf_weight=0.4,
|
||||
dl_weight=0.6
|
||||
)
|
||||
print("✅")
|
||||
except Exception as e:
|
||||
print(f"⚠️ DL init failed: {e}")
|
||||
self.use_deep_learning = False
|
||||
else:
|
||||
if not DEEP_LEARNING_AVAILABLE:
|
||||
print(" ℹ️ Deep Learning disabled (TensorFlow not installed)")
|
||||
elif not DL_ENGINE_AVAILABLE:
|
||||
print(" ℹ️ Deep Learning Engine not available")
|
||||
|
||||
def _needs_retraining(self, main_cache, euro_cache):
|
||||
"""Prüft ob Retraining nötig ist."""
|
||||
if not os.path.exists(main_cache) or not os.path.exists(euro_cache):
|
||||
@@ -827,47 +902,69 @@ class EurojackpotAIMLEngine:
|
||||
return np.array(X), np.array(y)
|
||||
|
||||
def predict_main_numbers(self, features_df):
|
||||
"""Vorhersage Main Numbers."""
|
||||
"""Vorhersage Main Numbers - mit Deep Learning Hybrid."""
|
||||
predictions = {}
|
||||
|
||||
|
||||
# Get RandomForest predictions
|
||||
if not self.is_trained or not self.trained_models_main:
|
||||
for num in range(1, 51):
|
||||
predictions[num] = 0.2 + random.random() * 0.3
|
||||
return predictions
|
||||
|
||||
current_features = self._get_current_features(features_df)
|
||||
|
||||
for number in range(1, 51):
|
||||
if number not in self.trained_models_main:
|
||||
predictions[number] = 0.15 + (number % 10) * 0.03
|
||||
continue
|
||||
|
||||
predictions[number] = self._predict_single_number(
|
||||
number, self.trained_models_main[number], current_features
|
||||
)
|
||||
|
||||
else:
|
||||
current_features = self._get_current_features(features_df)
|
||||
|
||||
for number in range(1, 51):
|
||||
if number not in self.trained_models_main:
|
||||
predictions[number] = 0.15 + (number % 10) * 0.03
|
||||
continue
|
||||
|
||||
predictions[number] = self._predict_single_number(
|
||||
number, self.trained_models_main[number], current_features
|
||||
)
|
||||
|
||||
# Use Deep Learning Hybrid if available
|
||||
if self.use_deep_learning and self.hybrid_predictor_main:
|
||||
try:
|
||||
predictions = self.hybrid_predictor_main.predict(
|
||||
predictions,
|
||||
self.df,
|
||||
self.features_df
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"⚠️ DL prediction (main) failed: {e}, using RF only")
|
||||
|
||||
return predictions
|
||||
|
||||
def predict_euro_numbers(self, features_df):
|
||||
"""Vorhersage Euro Numbers."""
|
||||
"""Vorhersage Euro Numbers - mit Deep Learning Hybrid."""
|
||||
predictions = {}
|
||||
|
||||
|
||||
# Get RandomForest predictions
|
||||
if not self.is_trained or not self.trained_models_euro:
|
||||
for num in range(1, 13):
|
||||
predictions[num] = 0.2 + random.random() * 0.3
|
||||
return predictions
|
||||
|
||||
current_features = self._get_current_features(features_df)
|
||||
|
||||
for number in range(1, 13):
|
||||
if number not in self.trained_models_euro:
|
||||
predictions[number] = 0.15 + (number % 5) * 0.05
|
||||
continue
|
||||
|
||||
predictions[number] = self._predict_single_number(
|
||||
number, self.trained_models_euro[number], current_features
|
||||
)
|
||||
|
||||
else:
|
||||
current_features = self._get_current_features(features_df)
|
||||
|
||||
for number in range(1, 13):
|
||||
if number not in self.trained_models_euro:
|
||||
predictions[number] = 0.15 + (number % 5) * 0.05
|
||||
continue
|
||||
|
||||
predictions[number] = self._predict_single_number(
|
||||
number, self.trained_models_euro[number], current_features
|
||||
)
|
||||
|
||||
# Use Deep Learning Hybrid if available
|
||||
if self.use_deep_learning and self.hybrid_predictor_euro:
|
||||
try:
|
||||
predictions = self.hybrid_predictor_euro.predict(
|
||||
predictions,
|
||||
self.df,
|
||||
self.features_df
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"⚠️ DL prediction (euro) failed: {e}, using RF only")
|
||||
|
||||
return predictions
|
||||
|
||||
def _predict_single_number(self, number, models, features):
|
||||
|
||||
Reference in New Issue
Block a user