This project includes multiple AI/ML-based lottery number generators for German Lotto 6aus49, including pattern analysis, weighted predictions, and hybrid approaches. Features automated weekly tip generation, performance tracking, and Telegram bot integration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
423 lines
16 KiB
Python
423 lines
16 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
AI-GENERATOR MIT MUSTER-GEWICHTUNG
|
|
Erweitert den AI-Generator um explizite Muster-Gewichtung (NNMMHH, etc.)
|
|
|
|
Neue Features:
|
|
- Historische Muster-Analyse (NNMMHH, NMMHHH, etc.)
|
|
- Muster-Erfolgsquoten berechnen
|
|
- Muster-basierte Tip-Optimierung
|
|
- Pattern-Scoring für bessere Kombinationen
|
|
"""
|
|
|
|
import pandas as pd
|
|
import numpy as np
|
|
from collections import Counter, defaultdict
|
|
import random
|
|
|
|
class PatternWeightedAI:
|
|
def __init__(self, df):
|
|
self.df = df
|
|
self.pattern_frequencies = Counter()
|
|
self.pattern_success_rates = {}
|
|
self.optimal_patterns = []
|
|
|
|
# Analysiere historische Muster
|
|
self._analyze_historical_patterns()
|
|
|
|
def _analyze_historical_patterns(self):
|
|
"""Analysiert alle historischen Muster und deren Erfolgsquoten."""
|
|
print("\n🎨 MUSTER-ANALYSE GESTARTET...")
|
|
|
|
if len(self.df) == 0:
|
|
return
|
|
|
|
total_drawings = len(self.df)
|
|
|
|
for _, row in self.df.iterrows():
|
|
numbers = sorted([row['Z1'], row['Z2'], row['Z3'], row['Z4'], row['Z5'], row['Z6']])
|
|
pattern = self._get_pattern(numbers)
|
|
self.pattern_frequencies[pattern] += 1
|
|
|
|
# Berechne Erfolgsquoten
|
|
for pattern, count in self.pattern_frequencies.items():
|
|
success_rate = count / total_drawings
|
|
self.pattern_success_rates[pattern] = success_rate
|
|
|
|
# Identifiziere optimale Muster (Top 10)
|
|
self.optimal_patterns = [
|
|
pattern for pattern, _ in self.pattern_frequencies.most_common(10)
|
|
]
|
|
|
|
print("🎯 MUSTER-ERFOLGSQUOTEN:")
|
|
print("Pattern Häufigkeit Erfolgsrate Bewertung")
|
|
print("-" * 50)
|
|
|
|
for i, (pattern, count) in enumerate(self.pattern_frequencies.most_common(15)):
|
|
success_rate = self.pattern_success_rates[pattern]
|
|
|
|
if success_rate >= 0.08:
|
|
bewertung = "🏆 EXCELLENT"
|
|
elif success_rate >= 0.06:
|
|
bewertung = "🥇 SEHR GUT"
|
|
elif success_rate >= 0.04:
|
|
bewertung = "🥈 GUT"
|
|
elif success_rate >= 0.02:
|
|
bewertung = "🥉 DURCHSCHNITT"
|
|
else:
|
|
bewertung = "❌ SCHWACH"
|
|
|
|
print(f"{pattern:<10} {count:>8} {success_rate:>8.3f} {bewertung}")
|
|
|
|
def _get_pattern(self, numbers):
|
|
"""Konvertiert Zahlen zu N/M/H Muster."""
|
|
pattern = ""
|
|
for num in numbers:
|
|
if 1 <= num <= 16:
|
|
pattern += "N" # Niedrig
|
|
elif 17 <= num <= 32:
|
|
pattern += "M" # Mittel
|
|
else:
|
|
pattern += "H" # Hoch
|
|
return pattern
|
|
|
|
def calculate_pattern_weight(self, numbers):
|
|
"""Berechnet Gewichtung basierend auf Muster-Erfolgsquote."""
|
|
pattern = self._get_pattern(sorted(numbers))
|
|
|
|
# Basis-Gewichtung aus historischer Erfolgsquote
|
|
base_weight = self.pattern_success_rates.get(pattern, 0.01)
|
|
|
|
# Bonus für Top-Muster
|
|
if pattern in self.optimal_patterns[:5]:
|
|
bonus = 0.3
|
|
elif pattern in self.optimal_patterns[:10]:
|
|
bonus = 0.2
|
|
else:
|
|
bonus = 0.0
|
|
|
|
# Penalty für nie aufgetretene Muster
|
|
if pattern not in self.pattern_frequencies:
|
|
penalty = -0.2
|
|
else:
|
|
penalty = 0.0
|
|
|
|
final_weight = base_weight + bonus + penalty
|
|
return max(0.01, min(1.0, final_weight)) # Clamp 0.01-1.0
|
|
|
|
def get_pattern_recommendations(self):
|
|
"""Liefert Muster-Empfehlungen für Tip-Generierung."""
|
|
recommendations = {}
|
|
|
|
# Top 5 erfolgreichste Muster
|
|
recommendations['top_patterns'] = self.optimal_patterns[:5]
|
|
|
|
# Muster mit bester Erfolgsquote
|
|
if self.pattern_success_rates:
|
|
best_pattern = max(self.pattern_success_rates.items(), key=lambda x: x[1])
|
|
recommendations['best_pattern'] = best_pattern[0]
|
|
recommendations['best_success_rate'] = best_pattern[1]
|
|
|
|
# Muster-Statistiken
|
|
recommendations['total_patterns'] = len(self.pattern_frequencies)
|
|
recommendations['pattern_diversity'] = len([p for p, rate in self.pattern_success_rates.items() if rate >= 0.02])
|
|
|
|
return recommendations
|
|
|
|
def optimize_combination_for_pattern(self, target_pattern="NNMMHH"):
|
|
"""Optimiert Zahlen-Kombination für spezifisches Muster."""
|
|
|
|
# Definiere Bereiche
|
|
ranges = {
|
|
'N': list(range(1, 17)), # Niedrig: 1-16
|
|
'M': list(range(17, 33)), # Mittel: 17-32
|
|
'H': list(range(33, 50)) # Hoch: 33-49
|
|
}
|
|
|
|
# Parse target pattern
|
|
pattern_counts = Counter(target_pattern)
|
|
needed_n = pattern_counts.get('N', 0)
|
|
needed_m = pattern_counts.get('M', 0)
|
|
needed_h = pattern_counts.get('H', 0)
|
|
|
|
selected = []
|
|
|
|
# Wähle Zahlen für Muster
|
|
if needed_n > 0:
|
|
n_numbers = random.sample(ranges['N'], min(needed_n, len(ranges['N'])))
|
|
selected.extend(n_numbers)
|
|
|
|
if needed_m > 0:
|
|
m_numbers = random.sample(ranges['M'], min(needed_m, len(ranges['M'])))
|
|
selected.extend(m_numbers)
|
|
|
|
if needed_h > 0:
|
|
h_numbers = random.sample(ranges['H'], min(needed_h, len(ranges['H'])))
|
|
selected.extend(h_numbers)
|
|
|
|
# Auffüllen falls nötig
|
|
while len(selected) < 6:
|
|
all_ranges = ranges['N'] + ranges['M'] + ranges['H']
|
|
available = [n for n in all_ranges if n not in selected]
|
|
if available:
|
|
selected.append(random.choice(available))
|
|
else:
|
|
break
|
|
|
|
return sorted(selected[:6])
|
|
|
|
class EnhancedAIGenerator:
|
|
"""Erweitert den ursprünglichen AI-Generator um Muster-Gewichtung."""
|
|
|
|
def __init__(self, data_path):
|
|
self.data_path = data_path
|
|
self.df = None
|
|
self.pattern_ai = None
|
|
|
|
# Load data
|
|
self._load_data()
|
|
|
|
# Initialize Pattern AI
|
|
if self.df is not None and len(self.df) > 0:
|
|
self.pattern_ai = PatternWeightedAI(self.df)
|
|
|
|
def _load_data(self):
|
|
"""Lädt Daten."""
|
|
try:
|
|
self.df = pd.read_csv(self.data_path, sep=';')
|
|
if 'datum' in self.df.columns:
|
|
self.df['datum'] = pd.to_datetime(self.df['datum'], format='%Y-%m-%d', errors='coerce')
|
|
self.df = self.df.sort_values('datum')
|
|
print(f"✅ {len(self.df)} Ziehungen geladen")
|
|
except Exception as e:
|
|
print(f"❌ Fehler beim Laden: {e}")
|
|
self.df = pd.DataFrame()
|
|
|
|
def generate_pattern_optimized_tips(self, num_tips=10):
|
|
"""Generiert Tipps mit expliziter Muster-Gewichtung."""
|
|
|
|
if not self.pattern_ai:
|
|
print("❌ Pattern AI nicht verfügbar")
|
|
return []
|
|
|
|
print("\n🎨 PATTERN-OPTIMIERTE TIPP-GENERIERUNG")
|
|
print("=" * 60)
|
|
|
|
# Muster-Empfehlungen abrufen
|
|
recommendations = self.pattern_ai.get_pattern_recommendations()
|
|
|
|
print("🎯 MUSTER-EMPFEHLUNGEN:")
|
|
print(f" Bestes Muster: {recommendations.get('best_pattern', 'N/A')} ({recommendations.get('best_success_rate', 0)*100:.1f}%)")
|
|
print(f" Top 5 Muster: {', '.join(recommendations.get('top_patterns', [])[:5])}")
|
|
print(f" Pattern-Diversität: {recommendations.get('pattern_diversity', 0)} erfolgreiche Muster")
|
|
|
|
tips = []
|
|
|
|
print(f"\n🎲 GENERIERE {num_tips} PATTERN-OPTIMIERTE TIPPS:")
|
|
print("=" * 80)
|
|
print("Nr 6 Pattern-Numbers Pattern Weight Confidence Success-Rate")
|
|
print("-" * 80)
|
|
|
|
# Verschiedene Strategien für verschiedene Tipps
|
|
strategies = [
|
|
('best', "Bestes Muster"),
|
|
('top5', "Top 5 Rotation"),
|
|
('balanced', "Ausgewogene Muster"),
|
|
('diverse', "Diversifizierte Muster")
|
|
]
|
|
|
|
for i in range(1, num_tips + 1):
|
|
strategy = strategies[(i-1) % len(strategies)]
|
|
tip = self._generate_pattern_tip(i, strategy[0], recommendations)
|
|
tips.append(tip)
|
|
|
|
# Output
|
|
zahlen_str = '-'.join([f"{n:2}" for n in tip['numbers']])
|
|
success_rate = self.pattern_ai.pattern_success_rates.get(tip['pattern'], 0)
|
|
|
|
print(f"{i:2} {zahlen_str} {tip['pattern']:<8} {tip['pattern_weight']:.3f} {tip['confidence']:.3f} {success_rate:.3f}")
|
|
|
|
# Zusammenfassung
|
|
self._print_pattern_summary(tips)
|
|
|
|
return tips
|
|
|
|
def _generate_pattern_tip(self, tip_number, strategy, recommendations):
|
|
"""Generiert einzelnen pattern-optimierten Tipp."""
|
|
|
|
# Seed für Konsistenz
|
|
random.seed(42 + tip_number)
|
|
|
|
if strategy == 'best':
|
|
# Nutze bestes Muster
|
|
target_pattern = recommendations.get('best_pattern', 'NNMMHH')
|
|
elif strategy == 'top5':
|
|
# Rotiere durch Top 5
|
|
top_patterns = recommendations.get('top_patterns', ['NNMMHH'])
|
|
target_pattern = top_patterns[(tip_number - 1) % len(top_patterns)]
|
|
elif strategy == 'balanced':
|
|
# Ausgewogene beliebte Muster
|
|
balanced_patterns = ['NNMMHH', 'NMMHHH', 'NMMMHH', 'NNMHHH']
|
|
target_pattern = balanced_patterns[(tip_number - 1) % len(balanced_patterns)]
|
|
else: # diverse
|
|
# Diversifizierte Muster für Abdeckung
|
|
diverse_patterns = ['NNMMHH', 'MMHHHH', 'NNNNMM', 'NMHHHH', 'NNNMMH']
|
|
target_pattern = diverse_patterns[(tip_number - 1) % len(diverse_patterns)]
|
|
|
|
# Generiere Kombination für Ziel-Muster
|
|
numbers = self.pattern_ai.optimize_combination_for_pattern(target_pattern)
|
|
|
|
# Validiere und korrigiere falls nötig
|
|
actual_pattern = self.pattern_ai._get_pattern(numbers)
|
|
|
|
# Pattern Weight berechnen
|
|
pattern_weight = self.pattern_ai.calculate_pattern_weight(numbers)
|
|
|
|
# Confidence basierend auf Pattern Success Rate
|
|
success_rate = self.pattern_ai.pattern_success_rates.get(actual_pattern, 0.01)
|
|
confidence = pattern_weight * 0.6 + success_rate * 0.4
|
|
|
|
# Superzahl
|
|
superzahl = self._get_pattern_superzahl(tip_number)
|
|
|
|
return {
|
|
'tip_number': tip_number,
|
|
'numbers': numbers,
|
|
'pattern': actual_pattern,
|
|
'target_pattern': target_pattern,
|
|
'pattern_weight': pattern_weight,
|
|
'confidence': confidence,
|
|
'success_rate': success_rate,
|
|
'superzahl': superzahl,
|
|
'strategy': strategy
|
|
}
|
|
|
|
def _get_pattern_superzahl(self, tip_number):
|
|
"""Pattern-optimierte Superzahl."""
|
|
# Basis häufigste Superzahlen
|
|
frequent_sz = [7, 6, 3, 2, 0, 1, 4, 5, 8, 9]
|
|
|
|
# Tip-spezifische Auswahl
|
|
return frequent_sz[tip_number % len(frequent_sz)]
|
|
|
|
def _print_pattern_summary(self, tips):
|
|
"""Druckt Pattern-Zusammenfassung."""
|
|
print(f"\n🏆 PATTERN-OPTIMIERUNG ZUSAMMENFASSUNG:")
|
|
print("=" * 50)
|
|
|
|
# Pattern-Verteilung
|
|
pattern_dist = Counter([tip['pattern'] for tip in tips])
|
|
print("📊 PATTERN-VERTEILUNG:")
|
|
for pattern, count in pattern_dist.most_common():
|
|
avg_success = np.mean([self.pattern_ai.pattern_success_rates.get(pattern, 0)] * count)
|
|
print(f" {pattern}: {count}x (Ø Success: {avg_success:.3f})")
|
|
|
|
# Durchschnittliche Metriken
|
|
avg_weight = np.mean([tip['pattern_weight'] for tip in tips])
|
|
avg_confidence = np.mean([tip['confidence'] for tip in tips])
|
|
avg_success = np.mean([tip['success_rate'] for tip in tips])
|
|
|
|
print(f"\n📈 DURCHSCHNITTLICHE METRIKEN:")
|
|
print(f" Pattern-Weight: {avg_weight:.3f}")
|
|
print(f" Confidence: {avg_confidence:.3f}")
|
|
print(f" Success-Rate: {avg_success:.3f}")
|
|
|
|
# Beste Tipps
|
|
best_tip = max(tips, key=lambda x: x['confidence'])
|
|
print(f"\n⭐ BESTER PATTERN-TIPP:")
|
|
zahlen_str = '-'.join([f"{n:2}" for n in best_tip['numbers']])
|
|
print(f" Tipp {best_tip['tip_number']}: {zahlen_str}")
|
|
print(f" Pattern: {best_tip['pattern']} (Weight: {best_tip['pattern_weight']:.3f})")
|
|
print(f" Success-Rate: {best_tip['success_rate']:.3f}")
|
|
|
|
def demonstrate_pattern_weighting():
|
|
"""Demonstriert Pattern-Gewichtung mit Beispiel-Daten."""
|
|
|
|
print("🎨 PATTERN-GEWICHTUNG DEMONSTRATION")
|
|
print("=" * 50)
|
|
|
|
# Beispiel-Daten erstellen
|
|
sample_data = []
|
|
patterns_to_simulate = ['NNMMHH', 'NMMHHH', 'NMMMHH', 'NNMHHH', 'MMHHHH']
|
|
|
|
for i in range(100):
|
|
# Simuliere Ziehungen mit verschiedenen Mustern
|
|
pattern = random.choice(patterns_to_simulate)
|
|
numbers = []
|
|
|
|
for char in pattern:
|
|
if char == 'N':
|
|
numbers.append(random.randint(1, 16))
|
|
elif char == 'M':
|
|
numbers.append(random.randint(17, 32))
|
|
else: # 'H'
|
|
numbers.append(random.randint(33, 49))
|
|
|
|
# Sicherstellen dass alle Zahlen einzigartig sind
|
|
numbers = sorted(list(set(numbers)))
|
|
while len(numbers) < 6:
|
|
missing_range = random.choice(['N', 'M', 'H'])
|
|
if missing_range == 'N':
|
|
new_num = random.randint(1, 16)
|
|
elif missing_range == 'M':
|
|
new_num = random.randint(17, 32)
|
|
else:
|
|
new_num = random.randint(33, 49)
|
|
|
|
if new_num not in numbers:
|
|
numbers.append(new_num)
|
|
numbers.sort()
|
|
|
|
numbers = numbers[:6]
|
|
|
|
sample_data.append({
|
|
'Z1': numbers[0], 'Z2': numbers[1], 'Z3': numbers[2],
|
|
'Z4': numbers[3], 'Z5': numbers[4], 'Z6': numbers[5],
|
|
'SZ': random.randint(0, 9)
|
|
})
|
|
|
|
# DataFrame erstellen
|
|
df_sample = pd.DataFrame(sample_data)
|
|
|
|
# Enhanced AI Generator mit Pattern-Gewichtung
|
|
print("\n🚀 STARTE PATTERN-GEWICHTETEN GENERATOR...")
|
|
|
|
# Simuliere Generator
|
|
generator = EnhancedAIGenerator.__new__(EnhancedAIGenerator)
|
|
generator.df = df_sample
|
|
generator.pattern_ai = PatternWeightedAI(df_sample)
|
|
|
|
# Generiere pattern-optimierte Tipps
|
|
pattern_tips = generator.generate_pattern_optimized_tips(8)
|
|
|
|
print(f"\n💡 PATTERN-GEWICHTUNG ERKLÄRT:")
|
|
print("=" * 40)
|
|
print("🎯 Jede Kombination wird bewertet basierend auf:")
|
|
print(" 1. Historischer Erfolgsquote des Musters")
|
|
print(" 2. Bonus für Top-5 erfolgreichste Muster")
|
|
print(" 3. Penalty für nie aufgetretene Muster")
|
|
print(" 4. Kombinierte Pattern-Weight für finalen Score")
|
|
|
|
return pattern_tips
|
|
|
|
def main():
|
|
"""Hauptfunktion für Pattern-gewichteten Generator."""
|
|
data_path = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/AlleLottozahlen.csv"
|
|
|
|
try:
|
|
# Versuche mit echten Daten
|
|
generator = EnhancedAIGenerator(data_path)
|
|
|
|
if generator.pattern_ai and len(generator.df) > 0:
|
|
pattern_tips = generator.generate_pattern_optimized_tips(10)
|
|
else:
|
|
print("🔄 Echte Daten nicht verfügbar - verwende Demo...")
|
|
pattern_tips = demonstrate_pattern_weighting()
|
|
|
|
except Exception as e:
|
|
print(f"⚠️ Fallback zu Demo-Modus: {e}")
|
|
pattern_tips = demonstrate_pattern_weighting()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|