diff --git a/data/generated_tips/generation_history.json b/data/generated_tips/generation_history.json index e3ff754..772b363 100644 --- a/data/generated_tips/generation_history.json +++ b/data/generated_tips/generation_history.json @@ -482,6 +482,34 @@ "file": "weekly_lotto_tips_20260626_141135.csv", "avg_confidence": 0.5219070441007705, "avg_quality": 0.6255187268545161 + }, + { + "timestamp": "2026-06-30T21:16:02.790589", + "num_tips": 10, + "file": "weekly_lotto_tips_20260630_211602.csv", + "avg_confidence": 0.5318105464227114, + "avg_quality": 0.6275079602567323 + }, + { + "timestamp": "2026-07-03T21:13:49.566065", + "num_tips": 10, + "file": "weekly_lotto_tips_20260703_211349.csv", + "avg_confidence": 0.37876899788720775, + "avg_quality": 0.5692246235847265 + }, + { + "timestamp": "2026-07-04T16:44:40.964978", + "num_tips": 10, + "file": "weekly_lotto_tips_20260704_164440.csv", + "avg_confidence": 0.4386488588333005, + "avg_quality": 0.6040749203914604 + }, + { + "timestamp": "2026-07-04T16:50:51.483700", + "num_tips": 10, + "file": "weekly_lotto_tips_20260704_165051.csv", + "avg_confidence": 0.4386488588333005, + "avg_quality": 0.544752806661678 } ] } \ No newline at end of file diff --git a/scripts/generators/ultimate_ai_ml_hybrid_generator.py b/scripts/generators/ultimate_ai_ml_hybrid_generator.py index fb83667..35ba3c6 100644 --- a/scripts/generators/ultimate_ai_ml_hybrid_generator.py +++ b/scripts/generators/ultimate_ai_ml_hybrid_generator.py @@ -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")