Refactor: 4 echte Strategien + cross-strategy Quality Score (Lotto)
Strategien ersetzt: - PURE-AI → BALANCED-SPREAD: erzwingt N≥1 M≥1 H≥1, max. 1 Consecutive Pair, AI-gewichtet - PURE-PATTERN → HIGH-EV: 2-3 Zahlen >31, max. 1 Lucky Number, soft Consecutive-Penalty - ENSEMBLE → SOFT-CONTRARIAN: Recency-Boost (letzte 30 Ziehungen), Zone-Balance - HYBRID-OPT: unverändert (bester Baseline) Quality Score jetzt strategieübergreifend (5 Perspektiven): AI×0.30 + Pattern×0.20 + Diversity×0.15 + Popularity×0.20 + Recency×0.15 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -91,12 +91,12 @@ class UltimateAIMLHybridGenerator:
|
||||
self.real_time_learner = RealTimeLearner(cache_path=self.model_cache_path) # Mit Persistenz
|
||||
self.performance_tracker = PerformanceTracker()
|
||||
|
||||
# Strategy Management (optimiert basierend auf Performance-Tests)
|
||||
# Strategy Management: 4 echte Strategien mit echter Differenzierung
|
||||
self.strategy_weights = {
|
||||
'pure_ai': 0.25, # Reduziert: 30% → 25%
|
||||
'pure_pattern': 0.15, # Reduziert: 25% → 15% (schwächste Strategie)
|
||||
'hybrid_optimized': 0.40, # Erhöht: 30% → 40% (beste Strategie)
|
||||
'ensemble_best': 0.20 # Erhöht: 15% → 20%
|
||||
'hybrid_optimized': 0.40, # AI + Pattern Optimierung (bester Baseline)
|
||||
'balanced_spread': 0.30, # Erzwingt N≥1 M≥1 H≥1 aus Top-Mustern
|
||||
'high_ev': 0.20, # EV-Optimierung: 2-3 Zahlen >31, wenig Lucky
|
||||
'soft_contrarian': 0.10, # Bevorzugt unterrepräsentierte Zahlen (letzte 30)
|
||||
}
|
||||
|
||||
self.is_trained = False
|
||||
@@ -205,7 +205,10 @@ class UltimateAIMLHybridGenerator:
|
||||
ai_predictions = self.ai_ml_engine.predict_all_numbers(self.features_df)
|
||||
ai_predictions = self.real_time_learner.adjust_predictions(ai_predictions)
|
||||
print("✅")
|
||||
|
||||
|
||||
# Recency-Counts für Soft-Contrarian vorberechnen
|
||||
self._recency_counts = self._compute_recency_counts(30)
|
||||
|
||||
# Determine Strategy Distribution
|
||||
distribution = self._calculate_strategy_distribution(num_tips)
|
||||
|
||||
@@ -301,90 +304,223 @@ class UltimateAIMLHybridGenerator:
|
||||
for i in range(count):
|
||||
tip_number = start_number + i
|
||||
|
||||
if strategy == 'pure_ai':
|
||||
tip = self._generate_pure_ai_tip(tip_number, ai_predictions)
|
||||
elif strategy == 'pure_pattern':
|
||||
tip = self._generate_pure_pattern_tip(tip_number, ai_predictions)
|
||||
elif strategy == 'hybrid_optimized':
|
||||
if strategy == 'hybrid_optimized':
|
||||
tip = self._generate_hybrid_tip(tip_number, ai_predictions)
|
||||
else: # ensemble_best
|
||||
tip = self._generate_ensemble_tip(tip_number, ai_predictions)
|
||||
elif strategy == 'balanced_spread':
|
||||
tip = self._generate_balanced_spread_tip(tip_number, ai_predictions)
|
||||
elif strategy == 'high_ev':
|
||||
tip = self._generate_high_ev_tip(tip_number, ai_predictions)
|
||||
else: # soft_contrarian
|
||||
tip = self._generate_soft_contrarian_tip(tip_number, ai_predictions)
|
||||
|
||||
tips.append(tip)
|
||||
|
||||
return tips
|
||||
|
||||
def _generate_pure_ai_tip(self, tip_number, ai_predictions):
|
||||
"""Pure AI-ML Strategie."""
|
||||
random.seed(42 + tip_number * 13)
|
||||
|
||||
sorted_preds = sorted(ai_predictions.items(), key=lambda x: x[1], reverse=True)
|
||||
top_candidates = [num for num, score in sorted_preds[:30]]
|
||||
|
||||
def _generate_balanced_spread_tip(self, tip_number, ai_predictions):
|
||||
"""Balanced Spread: erzwingt N≥1 M≥1 H≥1, AI-gewichtet innerhalb Zonen, max. 1 Consecutive Pair."""
|
||||
random.seed(42 + tip_number * 37)
|
||||
|
||||
zones = {
|
||||
'N': list(range(1, 17)),
|
||||
'M': list(range(17, 33)),
|
||||
'H': list(range(33, 50))
|
||||
}
|
||||
|
||||
# Nur Muster mit allen 3 Zonen (historisch top)
|
||||
top_patterns = self.pattern_engine.get_top_patterns(10)
|
||||
valid_patterns = [p for p in top_patterns if 'N' in p and 'M' in p and 'H' in p]
|
||||
if not valid_patterns:
|
||||
valid_patterns = ['NNMMHH', 'NNMHHH', 'NMMHHH', 'NNMMMH', 'NNNMMH']
|
||||
|
||||
target_pattern = valid_patterns[tip_number % len(valid_patterns)]
|
||||
pattern_counts = Counter(target_pattern)
|
||||
|
||||
selected = []
|
||||
|
||||
for position in range(6):
|
||||
candidates = [n for n in top_candidates if n not in selected]
|
||||
|
||||
if not candidates:
|
||||
candidates = [n for n in range(1, 50) if n not in selected]
|
||||
|
||||
if candidates:
|
||||
weights = [ai_predictions.get(c, 0.1) + random.random() * 0.15 for c in candidates]
|
||||
if selected:
|
||||
for i, c in enumerate(candidates):
|
||||
diversity = self._calculate_diversity_score(c, selected)
|
||||
weights[i] *= (1 + diversity * 0.3)
|
||||
|
||||
choice = random.choices(candidates, weights=weights)[0]
|
||||
for zone_char, count in pattern_counts.items():
|
||||
available = [n for n in zones[zone_char] if n not in selected]
|
||||
weights = [ai_predictions.get(n, 0.1) for n in available]
|
||||
for _ in range(count):
|
||||
if not available:
|
||||
break
|
||||
choice = random.choices(available, weights=weights)[0]
|
||||
selected.append(choice)
|
||||
|
||||
idx = available.index(choice)
|
||||
available.pop(idx)
|
||||
weights.pop(idx)
|
||||
|
||||
selected = sorted(selected)
|
||||
|
||||
# Soft consecutive reduction: max 1 Paar erlaubt
|
||||
for _ in range(5):
|
||||
consec = sum(1 for i in range(len(selected) - 1) if selected[i + 1] - selected[i] == 1)
|
||||
if consec <= 1:
|
||||
break
|
||||
for i in range(len(selected) - 1):
|
||||
if selected[i + 1] - selected[i] == 1:
|
||||
n = selected[i + 1]
|
||||
zone_char = 'N' if n <= 16 else 'M' if n <= 32 else 'H'
|
||||
alts = [x for x in zones[zone_char] if x not in selected
|
||||
and abs(x - selected[i]) > 1
|
||||
and (i + 2 >= len(selected) or abs(x - selected[i + 2]) > 1)]
|
||||
if alts:
|
||||
alt_w = [ai_predictions.get(x, 0.1) for x in alts]
|
||||
selected[i + 1] = random.choices(alts, weights=alt_w)[0]
|
||||
selected = sorted(selected)
|
||||
break
|
||||
|
||||
# Soft sum range (Q1–Q3: 127–171)
|
||||
for _ in range(5):
|
||||
s = sum(selected)
|
||||
if 127 <= s <= 171:
|
||||
break
|
||||
if s < 127:
|
||||
alts = [x for x in range(selected[0] + 1, 50) if x not in selected]
|
||||
if alts:
|
||||
selected[0] = random.choices(alts, weights=[ai_predictions.get(x, 0.1) for x in alts])[0]
|
||||
selected = sorted(selected)
|
||||
else:
|
||||
alts = [x for x in range(1, selected[-1]) if x not in selected]
|
||||
if alts:
|
||||
selected[-1] = random.choices(alts, weights=[ai_predictions.get(x, 0.1) for x in alts])[0]
|
||||
selected = sorted(selected)
|
||||
|
||||
superzahl = self._get_smart_superzahl(tip_number)
|
||||
|
||||
ai_score = np.mean([ai_predictions.get(n, 0.1) for n in selected])
|
||||
pattern_weight = self.pattern_engine.calculate_pattern_weight(selected)
|
||||
confidence = ai_score * 0.8 + pattern_weight * 0.2
|
||||
confidence = ai_score * 0.7 + pattern_weight * 0.3
|
||||
quality = self._calculate_quality_score(selected, ai_predictions, pattern_weight)
|
||||
|
||||
|
||||
return {
|
||||
'tip_number': tip_number,
|
||||
'numbers': selected,
|
||||
'superzahl': superzahl,
|
||||
'strategy': 'PURE-AI',
|
||||
'strategy': 'BALANCED-SPREAD',
|
||||
'ai_score': ai_score,
|
||||
'pattern_weight': pattern_weight,
|
||||
'confidence': confidence,
|
||||
'quality': quality
|
||||
}
|
||||
|
||||
def _generate_pure_pattern_tip(self, tip_number, ai_predictions):
|
||||
"""Pure Pattern Strategie."""
|
||||
random.seed(42 + tip_number * 17)
|
||||
|
||||
top_patterns = self.pattern_engine.get_top_patterns(10)
|
||||
target_pattern = top_patterns[tip_number % len(top_patterns)] if top_patterns else 'NNMMHH'
|
||||
|
||||
selected = self.pattern_engine.generate_for_pattern(target_pattern, tip_number)
|
||||
|
||||
def _generate_high_ev_tip(self, tip_number, ai_predictions):
|
||||
"""High-EV: 2–3 Zahlen >31, max. 1 Lucky Number, soft Consecutive-Vermeidung."""
|
||||
random.seed(42 + tip_number * 41)
|
||||
|
||||
lucky_numbers = {3, 7, 9, 11, 13, 17, 19, 21, 23}
|
||||
above_31_target = 2 + (tip_number % 2) # wechselt zwischen 2 und 3
|
||||
|
||||
selected = []
|
||||
|
||||
# Zahlen >31 wählen (ohne Consecutives)
|
||||
above_pool = list(range(32, 50))
|
||||
above_weights = [ai_predictions.get(n, 0.1) for n in above_pool]
|
||||
for _ in range(above_31_target):
|
||||
if not above_pool:
|
||||
break
|
||||
choice = random.choices(above_pool, weights=above_weights)[0]
|
||||
selected.append(choice)
|
||||
# Benachbarte aus Pool entfernen → keine Consecutives innerhalb above-31
|
||||
new_pool, new_weights = [], []
|
||||
for n, w in zip(above_pool, above_weights):
|
||||
if n != choice and abs(n - choice) > 1:
|
||||
new_pool.append(n)
|
||||
new_weights.append(w)
|
||||
above_pool, above_weights = new_pool, new_weights
|
||||
|
||||
# Zahlen ≤31 wählen (max. 1 Lucky, soft Consecutive-Penalty)
|
||||
below_pool = list(range(1, 32))
|
||||
lucky_picked = 0
|
||||
for _ in range(6 - above_31_target):
|
||||
if not below_pool:
|
||||
break
|
||||
weights = []
|
||||
for n in below_pool:
|
||||
w = ai_predictions.get(n, 0.1)
|
||||
if n in lucky_numbers:
|
||||
w *= (0.2 if lucky_picked >= 1 else 0.6)
|
||||
if any(abs(n - s) == 1 for s in selected):
|
||||
w *= 0.25 # soft Penalty für Consecutive
|
||||
weights.append(max(0.001, w))
|
||||
|
||||
choice = random.choices(below_pool, weights=weights)[0]
|
||||
if choice in lucky_numbers:
|
||||
lucky_picked += 1
|
||||
selected.append(choice)
|
||||
below_pool = [n for n in below_pool if n != choice]
|
||||
|
||||
selected = sorted(selected)
|
||||
superzahl = self._get_smart_superzahl(tip_number)
|
||||
|
||||
pattern_weight = self.pattern_engine.calculate_pattern_weight(selected)
|
||||
ai_score = np.mean([ai_predictions.get(n, 0.1) for n in selected])
|
||||
confidence = pattern_weight * 0.7 + ai_score * 0.3
|
||||
pattern_weight = self.pattern_engine.calculate_pattern_weight(selected)
|
||||
pop_score = self._calculate_popularity_score(selected)
|
||||
confidence = ai_score * 0.5 + pattern_weight * 0.2 + pop_score * 0.3
|
||||
quality = self._calculate_quality_score(selected, ai_predictions, pattern_weight)
|
||||
|
||||
|
||||
return {
|
||||
'tip_number': tip_number,
|
||||
'numbers': selected,
|
||||
'superzahl': superzahl,
|
||||
'strategy': 'PURE-PATTERN',
|
||||
'strategy': 'HIGH-EV',
|
||||
'ai_score': ai_score,
|
||||
'pattern_weight': pattern_weight,
|
||||
'confidence': confidence,
|
||||
'quality': quality,
|
||||
'target_pattern': target_pattern
|
||||
'quality': quality
|
||||
}
|
||||
|
||||
|
||||
def _generate_soft_contrarian_tip(self, tip_number, ai_predictions):
|
||||
"""Soft Contrarian: bevorzugt Zahlen die in letzten 30 Ziehungen unterrepräsentiert waren."""
|
||||
random.seed(42 + tip_number * 43)
|
||||
|
||||
expected_freq = 30 * 6 / 49 # ~3.67 Vorkommen pro Zahl erwartet
|
||||
|
||||
selected = []
|
||||
for _ in range(6):
|
||||
candidates = [n for n in range(1, 50) if n not in selected]
|
||||
|
||||
weights = []
|
||||
selected_zones = {'N' if s <= 16 else 'M' if s <= 32 else 'H' for s in selected}
|
||||
for c in candidates:
|
||||
ai_s = ai_predictions.get(c, 0.1)
|
||||
actual = self._recency_counts.get(c, 0)
|
||||
recency_s = max(0.0, (expected_freq - actual) / expected_freq)
|
||||
zone_char = 'N' if c <= 16 else 'M' if c <= 32 else 'H'
|
||||
zone_s = 0.8 if zone_char not in selected_zones else 0.4
|
||||
weights.append(max(0.001, ai_s * 0.5 + recency_s * 0.3 + zone_s * 0.2))
|
||||
|
||||
choice = random.choices(candidates, weights=weights)[0]
|
||||
selected.append(choice)
|
||||
|
||||
selected = sorted(selected)
|
||||
superzahl = self._get_smart_superzahl(tip_number)
|
||||
ai_score = np.mean([ai_predictions.get(n, 0.1) for n in selected])
|
||||
pattern_weight = self.pattern_engine.calculate_pattern_weight(selected)
|
||||
recency_avg = np.mean([
|
||||
max(0.0, (expected_freq - self._recency_counts.get(n, 0)) / expected_freq)
|
||||
for n in selected
|
||||
])
|
||||
confidence = ai_score * 0.5 + pattern_weight * 0.3 + recency_avg * 0.2
|
||||
quality = self._calculate_quality_score(selected, ai_predictions, pattern_weight)
|
||||
|
||||
return {
|
||||
'tip_number': tip_number,
|
||||
'numbers': selected,
|
||||
'superzahl': superzahl,
|
||||
'strategy': 'SOFT-CONTRARIAN',
|
||||
'ai_score': ai_score,
|
||||
'pattern_weight': pattern_weight,
|
||||
'confidence': confidence,
|
||||
'quality': quality
|
||||
}
|
||||
|
||||
def _compute_recency_counts(self, lookback=30):
|
||||
"""Zählt Vorkommen jeder Zahl in den letzten N Ziehungen."""
|
||||
recent = self.df.tail(lookback)
|
||||
counts = Counter()
|
||||
for _, row in recent.iterrows():
|
||||
for col in ['Z1', 'Z2', 'Z3', 'Z4', 'Z5', 'Z6']:
|
||||
counts[int(row[col])] += 1
|
||||
return counts
|
||||
|
||||
def _generate_hybrid_tip(self, tip_number, ai_predictions):
|
||||
"""Hybrid Strategie."""
|
||||
result = self.hybrid_optimizer.optimize(tip_number, ai_predictions)
|
||||
@@ -405,56 +541,6 @@ class UltimateAIMLHybridGenerator:
|
||||
'quality': quality
|
||||
}
|
||||
|
||||
def _generate_ensemble_tip(self, tip_number, ai_predictions):
|
||||
"""Ensemble Strategie."""
|
||||
random.seed(42 + tip_number * 23)
|
||||
|
||||
sorted_preds = sorted(ai_predictions.items(), key=lambda x: x[1], reverse=True)
|
||||
ai_candidates = [num for num, score in sorted_preds[:20]]
|
||||
|
||||
top_patterns = self.pattern_engine.get_top_patterns(3)
|
||||
pattern_candidates = []
|
||||
for pattern in top_patterns[:2]:
|
||||
pcands = self.pattern_engine.generate_for_pattern(pattern, tip_number)
|
||||
pattern_candidates.extend(pcands)
|
||||
|
||||
all_candidates = list(set(ai_candidates + pattern_candidates))
|
||||
|
||||
selected = []
|
||||
for position in range(6):
|
||||
candidates = [c for c in all_candidates if c not in selected]
|
||||
if not candidates:
|
||||
candidates = [n for n in range(1, 50) if n not in selected]
|
||||
|
||||
scores = []
|
||||
for c in candidates:
|
||||
ai_s = ai_predictions.get(c, 0.1)
|
||||
pattern_s = self.pattern_engine.get_number_pattern_score(c)
|
||||
diversity_s = self._calculate_diversity_score(c, selected) if selected else 0.5
|
||||
scores.append(max(0.001, ai_s * 0.4 + pattern_s * 0.3 + diversity_s * 0.3))
|
||||
|
||||
choice = random.choices(candidates, weights=scores)[0]
|
||||
selected.append(choice)
|
||||
|
||||
selected = sorted(selected)
|
||||
superzahl = self._get_smart_superzahl(tip_number)
|
||||
|
||||
ai_score = np.mean([ai_predictions.get(n, 0.1) for n in selected])
|
||||
pattern_weight = self.pattern_engine.calculate_pattern_weight(selected)
|
||||
confidence = (ai_score + pattern_weight) / 2
|
||||
quality = self._calculate_quality_score(selected, ai_predictions, pattern_weight)
|
||||
|
||||
return {
|
||||
'tip_number': tip_number,
|
||||
'numbers': selected,
|
||||
'superzahl': superzahl,
|
||||
'strategy': 'ENSEMBLE',
|
||||
'ai_score': ai_score,
|
||||
'pattern_weight': pattern_weight,
|
||||
'confidence': confidence,
|
||||
'quality': quality
|
||||
}
|
||||
|
||||
def _passes_structural_constraints(self, numbers):
|
||||
"""Prüft Summenbereich (122-176) und Parität (mind. 1G + 1U)."""
|
||||
s = sum(numbers)
|
||||
@@ -588,21 +674,41 @@ class UltimateAIMLHybridGenerator:
|
||||
return min(max(score, 0.0), 1.0)
|
||||
|
||||
def _calculate_quality_score(self, numbers, ai_predictions, pattern_weight):
|
||||
"""Berechnet Qualitäts-Score."""
|
||||
"""Berechnet Qualitäts-Score aus allen 5 Strategie-Perspektiven."""
|
||||
# HYBRID-OPT Perspektive: AI-Score gewichtet mit Streuung
|
||||
ai_scores = [ai_predictions.get(n, 0.1) for n in numbers]
|
||||
ai_quality = np.mean(ai_scores) * (1 + np.std(ai_scores))
|
||||
|
||||
# BALANCED-SPREAD Perspektive: historisches Mustergewicht
|
||||
pattern_quality = pattern_weight
|
||||
|
||||
# Zonenspreizung: mittlere paarweise Distanz
|
||||
distances = []
|
||||
for i, n1 in enumerate(numbers):
|
||||
for n2 in numbers[i+1:]:
|
||||
distances.append(abs(n1 - n2))
|
||||
diversity_quality = min(np.mean(distances) / 8.0, 1.0) if distances else 0.5
|
||||
|
||||
# HIGH-EV Perspektive: Popularitäts-/EV-Score
|
||||
popularity_quality = self._calculate_popularity_score(numbers)
|
||||
|
||||
quality = (ai_quality * 0.35 + pattern_quality * 0.25 + diversity_quality * 0.2 + popularity_quality * 0.2)
|
||||
# SOFT-CONTRARIAN Perspektive: Recency-Score (wie stark unterrepräsentiert?)
|
||||
if hasattr(self, '_recency_counts'):
|
||||
expected_freq = 30 * 6 / 49
|
||||
recency_quality = np.mean([
|
||||
max(0.0, (expected_freq - self._recency_counts.get(n, 0)) / expected_freq)
|
||||
for n in numbers
|
||||
])
|
||||
else:
|
||||
recency_quality = 0.5 # neutral wenn noch nicht berechnet
|
||||
|
||||
quality = (
|
||||
ai_quality * 0.30
|
||||
+ pattern_quality * 0.20
|
||||
+ diversity_quality * 0.15
|
||||
+ popularity_quality * 0.20
|
||||
+ recency_quality * 0.15
|
||||
)
|
||||
return min(quality, 1.0)
|
||||
|
||||
def _print_tip_line(self, tip):
|
||||
@@ -659,12 +765,12 @@ class UltimateAIMLHybridGenerator:
|
||||
strategy_avg = {}
|
||||
total = 0
|
||||
|
||||
for strategy in ['pure_ai', 'pure_pattern', 'hybrid_optimized', 'ensemble_best']:
|
||||
for strategy in ['hybrid_optimized', 'balanced_spread', 'high_ev', 'soft_contrarian']:
|
||||
strategy_key = {
|
||||
'pure_ai': 'PURE-AI',
|
||||
'pure_pattern': 'PURE-PATTERN',
|
||||
'hybrid_optimized': 'HYBRID-OPT',
|
||||
'ensemble_best': 'ENSEMBLE'
|
||||
'balanced_spread': 'BALANCED-SPREAD',
|
||||
'high_ev': 'HIGH-EV',
|
||||
'soft_contrarian': 'SOFT-CONTRARIAN'
|
||||
}[strategy]
|
||||
|
||||
if strategy_key in strategy_performance:
|
||||
@@ -1565,7 +1671,7 @@ def main():
|
||||
print(f"📚 Learning: ✅")
|
||||
|
||||
print("\n💡 ADVANTAGES:")
|
||||
print(" 🔬 4 Strategien: Pure-AI, Pure-Pattern, Hybrid, Ensemble")
|
||||
print(" 🔬 4 Strategien: Hybrid-OPT, Balanced-Spread, High-EV, Soft-Contrarian")
|
||||
print(" 🧠 AI/ML Ensemble: RandomForest + GradientBoosting")
|
||||
print(" 🎨 Pattern Analysis: Historische Verteilungen")
|
||||
print(" ⚡ Multi-Objective: AI + Pattern + Diversity")
|
||||
|
||||
Reference in New Issue
Block a user