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:
2026-01-07 09:22:36 +01:00
co-authored by Claude Sonnet 4.5
parent 70e0638dee
commit 9049a66c1a
36 changed files with 9308 additions and 61 deletions
@@ -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):