Refactor: 4 echte Strategien + cross-strategy Quality Score (Eurojackpot)
Strategien ersetzt: - PURE-AI → BALANCED-SPREAD: erzwingt L≥1 M≥1 H≥1, max. 1 Consecutive Pair - PURE-PATTERN → HIGH-EV: 2 Zahlen >31, max. 1 Lucky Number, soft Consecutive-Penalty - ENSEMBLE → SOFT-CONTRARIAN: Recency-Boost (letzte 30 Ziehungen), Zone-Balance - HYBRID-OPT: unverändert Quality Score jetzt strategieübergreifend (6 Perspektiven): Main-AI×0.25 + Euro×0.15 + Pattern×0.15 + Diversity×0.10 + Popularity×0.20 + Recency×0.15 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -496,6 +496,27 @@
|
|||||||
"file": "weekly_tips_20260626_141210.csv",
|
"file": "weekly_tips_20260626_141210.csv",
|
||||||
"avg_confidence": 0.45829977009199985,
|
"avg_confidence": 0.45829977009199985,
|
||||||
"avg_quality": 0.5822532698964943
|
"avg_quality": 0.5822532698964943
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-06-29T21:03:34.292807",
|
||||||
|
"num_tips": 10,
|
||||||
|
"file": "weekly_tips_20260629_210334.csv",
|
||||||
|
"avg_confidence": 0.4467334616642155,
|
||||||
|
"avg_quality": 0.5674017728578733
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-07-02T21:06:12.208802",
|
||||||
|
"num_tips": 10,
|
||||||
|
"file": "weekly_tips_20260702_210612.csv",
|
||||||
|
"avg_confidence": 0.48294321323816025,
|
||||||
|
"avg_quality": 0.6035966436446752
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-07-04T16:58:30.880781",
|
||||||
|
"num_tips": 10,
|
||||||
|
"file": "weekly_tips_20260704_165830.csv",
|
||||||
|
"avg_confidence": 0.5226028457900052,
|
||||||
|
"avg_quality": 0.5218641480233097
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -109,12 +109,12 @@ class UltimateAIMLEurojackpotGenerator:
|
|||||||
self.real_time_learner = EurojackpotRealTimeLearner(cache_path=self.model_cache_path) # Mit Persistenz
|
self.real_time_learner = EurojackpotRealTimeLearner(cache_path=self.model_cache_path) # Mit Persistenz
|
||||||
self.performance_tracker = EurojackpotPerformanceTracker()
|
self.performance_tracker = EurojackpotPerformanceTracker()
|
||||||
|
|
||||||
# Strategy Management (optimiert basierend auf Performance-Tests)
|
# Strategy Management: 4 echte Strategien mit echter Differenzierung
|
||||||
self.strategy_weights = {
|
self.strategy_weights = {
|
||||||
'pure_ai': 0.25, # Reduziert: 30% → 25%
|
'hybrid_optimized': 0.40, # AI + Pattern Optimierung (bester Baseline)
|
||||||
'pure_pattern': 0.15, # Reduziert: 25% → 15% (schwächste Strategie)
|
'balanced_spread': 0.30, # Erzwingt L≥1 M≥1 H≥1 aus Top-Mustern
|
||||||
'hybrid_optimized': 0.40, # Erhöht: 30% → 40% (beste Strategie)
|
'high_ev': 0.20, # EV-Optimierung: 2 Zahlen >31, wenig Lucky
|
||||||
'ensemble_best': 0.20 # Erhöht: 15% → 20%
|
'soft_contrarian': 0.10, # Bevorzugt unterrepräsentierte Zahlen (letzte 30)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.is_trained = False
|
self.is_trained = False
|
||||||
@@ -230,7 +230,10 @@ class UltimateAIMLEurojackpotGenerator:
|
|||||||
main_predictions = self.real_time_learner.adjust_main_predictions(main_predictions)
|
main_predictions = self.real_time_learner.adjust_main_predictions(main_predictions)
|
||||||
euro_predictions = self.real_time_learner.adjust_euro_predictions(euro_predictions)
|
euro_predictions = self.real_time_learner.adjust_euro_predictions(euro_predictions)
|
||||||
print("✅")
|
print("✅")
|
||||||
|
|
||||||
|
# Recency-Counts für Soft-Contrarian vorberechnen
|
||||||
|
self._recency_counts = self._compute_recency_counts(30)
|
||||||
|
|
||||||
# Determine Strategy Distribution
|
# Determine Strategy Distribution
|
||||||
distribution = self._calculate_strategy_distribution(num_tips)
|
distribution = self._calculate_strategy_distribution(num_tips)
|
||||||
|
|
||||||
@@ -332,115 +335,230 @@ class UltimateAIMLEurojackpotGenerator:
|
|||||||
for i in range(count):
|
for i in range(count):
|
||||||
tip_number = start_number + i
|
tip_number = start_number + i
|
||||||
|
|
||||||
if strategy == 'pure_ai':
|
if strategy == 'hybrid_optimized':
|
||||||
tip = self._generate_pure_ai_tip(tip_number, main_preds, euro_preds)
|
|
||||||
elif strategy == 'pure_pattern':
|
|
||||||
tip = self._generate_pure_pattern_tip(tip_number, main_preds, euro_preds)
|
|
||||||
elif strategy == 'hybrid_optimized':
|
|
||||||
tip = self._generate_hybrid_tip(tip_number, main_preds, euro_preds)
|
tip = self._generate_hybrid_tip(tip_number, main_preds, euro_preds)
|
||||||
else: # ensemble_best
|
elif strategy == 'balanced_spread':
|
||||||
tip = self._generate_ensemble_tip(tip_number, main_preds, euro_preds)
|
tip = self._generate_balanced_spread_tip(tip_number, main_preds, euro_preds)
|
||||||
|
elif strategy == 'high_ev':
|
||||||
|
tip = self._generate_high_ev_tip(tip_number, main_preds, euro_preds)
|
||||||
|
else: # soft_contrarian
|
||||||
|
tip = self._generate_soft_contrarian_tip(tip_number, main_preds, euro_preds)
|
||||||
|
|
||||||
tips.append(tip)
|
tips.append(tip)
|
||||||
|
|
||||||
return tips
|
return tips
|
||||||
|
|
||||||
def _generate_pure_ai_tip(self, tip_number, main_preds, euro_preds):
|
def _generate_balanced_spread_tip(self, tip_number, main_preds, euro_preds):
|
||||||
"""Pure AI Strategie."""
|
"""Balanced Spread: erzwingt L≥1 M≥1 H≥1, AI-gewichtet, max. 1 Consecutive Pair."""
|
||||||
random.seed(42 + tip_number * 13)
|
random.seed(42 + tip_number * 37)
|
||||||
|
|
||||||
# Main numbers
|
# 3 Zonen für EJ (1-50, 5 Zahlen)
|
||||||
sorted_main = sorted(main_preds.items(), key=lambda x: x[1], reverse=True)
|
zones = {
|
||||||
top_candidates = [num for num, score in sorted_main[:35]]
|
'L': list(range(1, 18)), # 1-17
|
||||||
|
'M': list(range(18, 35)), # 18-34
|
||||||
|
'H': list(range(35, 51)) # 35-50
|
||||||
|
}
|
||||||
|
|
||||||
|
# Muster mit allen 3 Zonen (je 5 Zahlen auf 3 Zonen verteilt)
|
||||||
|
valid_patterns = [
|
||||||
|
('L', 'L', 'M', 'H', 'H'), # ~LLMHH
|
||||||
|
('L', 'M', 'M', 'H', 'H'), # ~LMMHH
|
||||||
|
('L', 'L', 'M', 'M', 'H'), # ~LLMMH
|
||||||
|
('L', 'M', 'H', 'H', 'H'), # ~LMHHH
|
||||||
|
('L', 'L', 'L', 'M', 'H'), # ~LLLMH
|
||||||
|
]
|
||||||
|
target_zones = valid_patterns[tip_number % len(valid_patterns)]
|
||||||
|
zone_counts = Counter(target_zones)
|
||||||
|
|
||||||
selected_main = []
|
selected_main = []
|
||||||
for position in range(5):
|
for zone_char, count in zone_counts.items():
|
||||||
candidates = [n for n in top_candidates if n not in selected_main]
|
available = [n for n in zones[zone_char] if n not in selected_main]
|
||||||
|
weights = [main_preds.get(n, 0.1) for n in available]
|
||||||
if not candidates:
|
for _ in range(count):
|
||||||
candidates = [n for n in range(1, 51) if n not in selected_main]
|
if not available:
|
||||||
|
break
|
||||||
if candidates:
|
choice = random.choices(available, weights=weights)[0]
|
||||||
weights = [main_preds.get(c, 0.1) + random.random() * 0.15 for c in candidates]
|
|
||||||
if selected_main:
|
|
||||||
for i, c in enumerate(candidates):
|
|
||||||
diversity = self._calculate_diversity_score(c, selected_main)
|
|
||||||
weights[i] *= (1 + diversity * 0.3)
|
|
||||||
|
|
||||||
choice = random.choices(candidates, weights=weights)[0]
|
|
||||||
selected_main.append(choice)
|
selected_main.append(choice)
|
||||||
|
idx = available.index(choice)
|
||||||
|
available.pop(idx)
|
||||||
|
weights.pop(idx)
|
||||||
|
|
||||||
selected_main = sorted(selected_main)
|
selected_main = sorted(selected_main)
|
||||||
|
|
||||||
# Euro numbers
|
# Soft consecutive reduction: max 1 Paar
|
||||||
sorted_euro = sorted(euro_preds.items(), key=lambda x: x[1], reverse=True)
|
for _ in range(5):
|
||||||
top_euro = [num for num, score in sorted_euro[:8]]
|
consec = sum(1 for i in range(len(selected_main) - 1) if selected_main[i + 1] - selected_main[i] == 1)
|
||||||
|
if consec <= 1:
|
||||||
selected_euro = []
|
break
|
||||||
for position in range(2):
|
for i in range(len(selected_main) - 1):
|
||||||
candidates = [n for n in top_euro if n not in selected_euro]
|
if selected_main[i + 1] - selected_main[i] == 1:
|
||||||
if not candidates:
|
n = selected_main[i + 1]
|
||||||
candidates = [n for n in range(1, 13) if n not in selected_euro]
|
zone_char = 'L' if n <= 17 else 'M' if n <= 34 else 'H'
|
||||||
|
alts = [x for x in zones[zone_char] if x not in selected_main
|
||||||
if candidates:
|
and abs(x - selected_main[i]) > 1
|
||||||
weights = [euro_preds.get(c, 0.1) + random.random() * 0.1 for c in candidates]
|
and (i + 2 >= len(selected_main) or abs(x - selected_main[i + 2]) > 1)]
|
||||||
choice = random.choices(candidates, weights=weights)[0]
|
if alts:
|
||||||
selected_euro.append(choice)
|
selected_main[i + 1] = random.choices(alts, weights=[main_preds.get(x, 0.1) for x in alts])[0]
|
||||||
|
selected_main = sorted(selected_main)
|
||||||
selected_euro = sorted(selected_euro)
|
break
|
||||||
|
|
||||||
# Scores
|
# Soft sum range (EJ Q1-Q3: 107-150)
|
||||||
|
for _ in range(5):
|
||||||
|
s = sum(selected_main)
|
||||||
|
if 107 <= s <= 150:
|
||||||
|
break
|
||||||
|
if s < 107:
|
||||||
|
alts = [x for x in range(selected_main[0] + 1, 51) if x not in selected_main]
|
||||||
|
if alts:
|
||||||
|
selected_main[0] = random.choices(alts, weights=[main_preds.get(x, 0.1) for x in alts])[0]
|
||||||
|
selected_main = sorted(selected_main)
|
||||||
|
else:
|
||||||
|
alts = [x for x in range(1, selected_main[-1]) if x not in selected_main]
|
||||||
|
if alts:
|
||||||
|
selected_main[-1] = random.choices(alts, weights=[main_preds.get(x, 0.1) for x in alts])[0]
|
||||||
|
selected_main = sorted(selected_main)
|
||||||
|
|
||||||
|
selected_euro = self._get_smart_euro_numbers(tip_number, euro_preds)
|
||||||
main_ai_score = np.mean([main_preds.get(n, 0.1) for n in selected_main])
|
main_ai_score = np.mean([main_preds.get(n, 0.1) for n in selected_main])
|
||||||
euro_ai_score = np.mean([euro_preds.get(n, 0.1) for n in selected_euro])
|
euro_ai_score = np.mean([euro_preds.get(n, 0.1) for n in selected_euro])
|
||||||
pattern_weight = self.pattern_engine.calculate_pattern_weight(selected_main)
|
pattern_weight = self.pattern_engine.calculate_pattern_weight(selected_main)
|
||||||
confidence = main_ai_score * 0.5 + euro_ai_score * 0.3 + pattern_weight * 0.2
|
confidence = main_ai_score * 0.6 + euro_ai_score * 0.2 + pattern_weight * 0.2
|
||||||
quality = self._calculate_quality_score(selected_main, selected_euro, main_preds, euro_preds, pattern_weight)
|
quality = self._calculate_quality_score(selected_main, selected_euro, main_preds, euro_preds, pattern_weight)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'tip_number': tip_number,
|
'tip_number': tip_number,
|
||||||
'main_numbers': selected_main,
|
'main_numbers': selected_main,
|
||||||
'euro_numbers': selected_euro,
|
'euro_numbers': selected_euro,
|
||||||
'strategy': 'PURE-AI',
|
'strategy': 'BALANCED-SPREAD',
|
||||||
'main_ai_score': main_ai_score,
|
'main_ai_score': main_ai_score,
|
||||||
'euro_ai_score': euro_ai_score,
|
'euro_ai_score': euro_ai_score,
|
||||||
'pattern_weight': pattern_weight,
|
'pattern_weight': pattern_weight,
|
||||||
'confidence': confidence,
|
'confidence': confidence,
|
||||||
'quality': quality
|
'quality': quality
|
||||||
}
|
}
|
||||||
|
|
||||||
def _generate_pure_pattern_tip(self, tip_number, main_preds, euro_preds):
|
def _generate_high_ev_tip(self, tip_number, main_preds, euro_preds):
|
||||||
"""Pure Pattern Strategie."""
|
"""High-EV: 2 Zahlen >31, max. 1 Lucky Number, soft Consecutive-Vermeidung."""
|
||||||
random.seed(42 + tip_number * 17)
|
random.seed(42 + tip_number * 41)
|
||||||
|
|
||||||
# Main numbers mit Pattern
|
lucky_numbers = {3, 7, 9, 11, 13, 17, 19, 21, 23}
|
||||||
top_patterns = self.pattern_engine.get_top_patterns(10)
|
above_31_target = 2 # für 5 Zahlen: 2 above-31 = solide EV-Basis
|
||||||
target_pattern = top_patterns[tip_number % len(top_patterns)] if top_patterns else 'NNMMH'
|
|
||||||
|
selected_main = []
|
||||||
selected_main = self.pattern_engine.generate_for_pattern(target_pattern, tip_number)
|
|
||||||
|
# Zahlen >31 zuerst wählen (ohne Consecutives)
|
||||||
# Euro numbers - frequency based
|
above_pool = list(range(32, 51))
|
||||||
|
above_weights = [main_preds.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_main.append(choice)
|
||||||
|
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(5 - above_31_target):
|
||||||
|
if not below_pool:
|
||||||
|
break
|
||||||
|
weights = []
|
||||||
|
for n in below_pool:
|
||||||
|
w = main_preds.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_main):
|
||||||
|
w *= 0.25
|
||||||
|
weights.append(max(0.001, w))
|
||||||
|
|
||||||
|
choice = random.choices(below_pool, weights=weights)[0]
|
||||||
|
if choice in lucky_numbers:
|
||||||
|
lucky_picked += 1
|
||||||
|
selected_main.append(choice)
|
||||||
|
below_pool = [n for n in below_pool if n != choice]
|
||||||
|
|
||||||
|
selected_main = sorted(selected_main)
|
||||||
selected_euro = self._get_smart_euro_numbers(tip_number, euro_preds)
|
selected_euro = self._get_smart_euro_numbers(tip_number, euro_preds)
|
||||||
|
|
||||||
# Scores
|
|
||||||
pattern_weight = self.pattern_engine.calculate_pattern_weight(selected_main)
|
|
||||||
main_ai_score = np.mean([main_preds.get(n, 0.1) for n in selected_main])
|
main_ai_score = np.mean([main_preds.get(n, 0.1) for n in selected_main])
|
||||||
euro_ai_score = np.mean([euro_preds.get(n, 0.1) for n in selected_euro])
|
euro_ai_score = np.mean([euro_preds.get(n, 0.1) for n in selected_euro])
|
||||||
confidence = pattern_weight * 0.6 + main_ai_score * 0.25 + euro_ai_score * 0.15
|
pattern_weight = self.pattern_engine.calculate_pattern_weight(selected_main)
|
||||||
|
pop_score = self._calculate_popularity_score(selected_main)
|
||||||
|
confidence = main_ai_score * 0.4 + euro_ai_score * 0.2 + pattern_weight * 0.1 + pop_score * 0.3
|
||||||
quality = self._calculate_quality_score(selected_main, selected_euro, main_preds, euro_preds, pattern_weight)
|
quality = self._calculate_quality_score(selected_main, selected_euro, main_preds, euro_preds, pattern_weight)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'tip_number': tip_number,
|
'tip_number': tip_number,
|
||||||
'main_numbers': selected_main,
|
'main_numbers': selected_main,
|
||||||
'euro_numbers': selected_euro,
|
'euro_numbers': selected_euro,
|
||||||
'strategy': 'PURE-PATTERN',
|
'strategy': 'HIGH-EV',
|
||||||
'main_ai_score': main_ai_score,
|
'main_ai_score': main_ai_score,
|
||||||
'euro_ai_score': euro_ai_score,
|
'euro_ai_score': euro_ai_score,
|
||||||
'pattern_weight': pattern_weight,
|
'pattern_weight': pattern_weight,
|
||||||
'confidence': confidence,
|
'confidence': confidence,
|
||||||
'quality': quality,
|
'quality': quality
|
||||||
'target_pattern': target_pattern
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _generate_soft_contrarian_tip(self, tip_number, main_preds, euro_preds):
|
||||||
|
"""Soft Contrarian: bevorzugt Zahlen die in letzten 30 Ziehungen unterrepräsentiert waren."""
|
||||||
|
random.seed(42 + tip_number * 43)
|
||||||
|
|
||||||
|
expected_freq = 30 * 5 / 50 # ~3.0 Vorkommen pro Zahl erwartet
|
||||||
|
|
||||||
|
selected_main = []
|
||||||
|
for _ in range(5):
|
||||||
|
candidates = [n for n in range(1, 51) if n not in selected_main]
|
||||||
|
|
||||||
|
selected_zones = {'L' if s <= 17 else 'M' if s <= 34 else 'H' for s in selected_main}
|
||||||
|
weights = []
|
||||||
|
for c in candidates:
|
||||||
|
ai_s = main_preds.get(c, 0.1)
|
||||||
|
actual = self._recency_counts.get(c, 0)
|
||||||
|
recency_s = max(0.0, (expected_freq - actual) / expected_freq)
|
||||||
|
zone_char = 'L' if c <= 17 else 'M' if c <= 34 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_main.append(choice)
|
||||||
|
|
||||||
|
selected_main = sorted(selected_main)
|
||||||
|
selected_euro = self._get_smart_euro_numbers(tip_number, euro_preds)
|
||||||
|
main_ai_score = np.mean([main_preds.get(n, 0.1) for n in selected_main])
|
||||||
|
euro_ai_score = np.mean([euro_preds.get(n, 0.1) for n in selected_euro])
|
||||||
|
pattern_weight = self.pattern_engine.calculate_pattern_weight(selected_main)
|
||||||
|
recency_avg = np.mean([
|
||||||
|
max(0.0, (expected_freq - self._recency_counts.get(n, 0)) / expected_freq)
|
||||||
|
for n in selected_main
|
||||||
|
])
|
||||||
|
confidence = main_ai_score * 0.4 + euro_ai_score * 0.2 + pattern_weight * 0.2 + recency_avg * 0.2
|
||||||
|
quality = self._calculate_quality_score(selected_main, selected_euro, main_preds, euro_preds, pattern_weight)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'tip_number': tip_number,
|
||||||
|
'main_numbers': selected_main,
|
||||||
|
'euro_numbers': selected_euro,
|
||||||
|
'strategy': 'SOFT-CONTRARIAN',
|
||||||
|
'main_ai_score': main_ai_score,
|
||||||
|
'euro_ai_score': euro_ai_score,
|
||||||
|
'pattern_weight': pattern_weight,
|
||||||
|
'confidence': confidence,
|
||||||
|
'quality': quality
|
||||||
|
}
|
||||||
|
|
||||||
|
def _compute_recency_counts(self, lookback=30):
|
||||||
|
"""Zählt Vorkommen jeder Hauptzahl 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']:
|
||||||
|
counts[int(row[col])] += 1
|
||||||
|
return counts
|
||||||
|
|
||||||
def _generate_hybrid_tip(self, tip_number, main_preds, euro_preds):
|
def _generate_hybrid_tip(self, tip_number, main_preds, euro_preds):
|
||||||
"""Hybrid Strategie."""
|
"""Hybrid Strategie."""
|
||||||
result = self.hybrid_optimizer.optimize(tip_number, main_preds, euro_preds)
|
result = self.hybrid_optimizer.optimize(tip_number, main_preds, euro_preds)
|
||||||
@@ -462,63 +580,6 @@ class UltimateAIMLEurojackpotGenerator:
|
|||||||
'quality': quality
|
'quality': quality
|
||||||
}
|
}
|
||||||
|
|
||||||
def _generate_ensemble_tip(self, tip_number, main_preds, euro_preds):
|
|
||||||
"""Ensemble Strategie."""
|
|
||||||
random.seed(42 + tip_number * 23)
|
|
||||||
|
|
||||||
# Main numbers - ensemble approach
|
|
||||||
sorted_main = sorted(main_preds.items(), key=lambda x: x[1], reverse=True)
|
|
||||||
ai_candidates = [num for num, score in sorted_main[:25]]
|
|
||||||
|
|
||||||
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_main = []
|
|
||||||
for position in range(5):
|
|
||||||
candidates = [c for c in all_candidates if c not in selected_main]
|
|
||||||
if not candidates:
|
|
||||||
candidates = [n for n in range(1, 51) if n not in selected_main]
|
|
||||||
|
|
||||||
scores = []
|
|
||||||
for c in candidates:
|
|
||||||
ai_s = main_preds.get(c, 0.1)
|
|
||||||
pattern_s = self.pattern_engine.get_number_pattern_score(c)
|
|
||||||
diversity_s = self._calculate_diversity_score(c, selected_main) if selected_main else 0.5
|
|
||||||
scores.append(ai_s * 0.4 + pattern_s * 0.3 + diversity_s * 0.3)
|
|
||||||
|
|
||||||
# Gewichtete Zufallsauswahl: Qualität bleibt hoch, Duplikate werden vermieden
|
|
||||||
choice = random.choices(candidates, weights=scores)[0]
|
|
||||||
selected_main.append(choice)
|
|
||||||
|
|
||||||
selected_main = sorted(selected_main[:5])
|
|
||||||
|
|
||||||
# Euro numbers - best from AI
|
|
||||||
selected_euro = self._get_smart_euro_numbers(tip_number, euro_preds)
|
|
||||||
|
|
||||||
# Scores
|
|
||||||
main_ai_score = np.mean([main_preds.get(n, 0.1) for n in selected_main])
|
|
||||||
euro_ai_score = np.mean([euro_preds.get(n, 0.1) for n in selected_euro])
|
|
||||||
pattern_weight = self.pattern_engine.calculate_pattern_weight(selected_main)
|
|
||||||
confidence = (main_ai_score * 0.4 + euro_ai_score * 0.3 + pattern_weight * 0.3)
|
|
||||||
quality = self._calculate_quality_score(selected_main, selected_euro, main_preds, euro_preds, pattern_weight)
|
|
||||||
|
|
||||||
return {
|
|
||||||
'tip_number': tip_number,
|
|
||||||
'main_numbers': selected_main,
|
|
||||||
'euro_numbers': selected_euro,
|
|
||||||
'strategy': 'ENSEMBLE',
|
|
||||||
'main_ai_score': main_ai_score,
|
|
||||||
'euro_ai_score': euro_ai_score,
|
|
||||||
'pattern_weight': pattern_weight,
|
|
||||||
'confidence': confidence,
|
|
||||||
'quality': quality
|
|
||||||
}
|
|
||||||
|
|
||||||
def _passes_structural_constraints(self, main_numbers):
|
def _passes_structural_constraints(self, main_numbers):
|
||||||
"""Prüft Summenbereich und Parität."""
|
"""Prüft Summenbereich und Parität."""
|
||||||
s = sum(main_numbers)
|
s = sum(main_numbers)
|
||||||
@@ -648,29 +709,46 @@ class UltimateAIMLEurojackpotGenerator:
|
|||||||
return min(max(score, 0.0), 1.0)
|
return min(max(score, 0.0), 1.0)
|
||||||
|
|
||||||
def _calculate_quality_score(self, main_numbers, euro_numbers, main_preds, euro_preds, pattern_weight):
|
def _calculate_quality_score(self, main_numbers, euro_numbers, main_preds, euro_preds, pattern_weight):
|
||||||
"""Berechnet Qualität."""
|
"""Berechnet Qualitäts-Score aus allen 5 Strategie-Perspektiven."""
|
||||||
# Main quality
|
# HYBRID-OPT Perspektive: AI-Score gewichtet mit Streuung
|
||||||
main_scores = [main_preds.get(n, 0.1) for n in main_numbers]
|
main_scores = [main_preds.get(n, 0.1) for n in main_numbers]
|
||||||
main_quality = np.mean(main_scores) * (1 + np.std(main_scores) * 0.5)
|
main_quality = np.mean(main_scores) * (1 + np.std(main_scores) * 0.5)
|
||||||
|
|
||||||
# Euro quality
|
# Euro-Qualität (separates Signal)
|
||||||
euro_scores = [euro_preds.get(n, 0.1) for n in euro_numbers]
|
euro_scores = [euro_preds.get(n, 0.1) for n in euro_numbers]
|
||||||
euro_quality = np.mean(euro_scores)
|
euro_quality = np.mean(euro_scores)
|
||||||
|
|
||||||
# Pattern quality
|
# BALANCED-SPREAD Perspektive: historisches Mustergewicht
|
||||||
pattern_quality = pattern_weight
|
pattern_quality = pattern_weight
|
||||||
|
|
||||||
# Diversity
|
# Zonenspreizung: mittlere paarweise Distanz
|
||||||
distances = []
|
distances = []
|
||||||
for i, n1 in enumerate(main_numbers):
|
for i, n1 in enumerate(main_numbers):
|
||||||
for n2 in main_numbers[i+1:]:
|
for n2 in main_numbers[i+1:]:
|
||||||
distances.append(abs(n1 - n2))
|
distances.append(abs(n1 - n2))
|
||||||
diversity_quality = min(np.mean(distances) / 10.0, 1.0) if distances else 0.5
|
diversity_quality = min(np.mean(distances) / 10.0, 1.0) if distances else 0.5
|
||||||
|
|
||||||
# Popularity (EV-Vorteil bei Gewinn)
|
# HIGH-EV Perspektive: Popularitäts-/EV-Score
|
||||||
popularity_quality = self._calculate_popularity_score(main_numbers)
|
popularity_quality = self._calculate_popularity_score(main_numbers)
|
||||||
|
|
||||||
quality = (main_quality * 0.35 + euro_quality * 0.2 + pattern_quality * 0.15 + diversity_quality * 0.1 + popularity_quality * 0.2)
|
# SOFT-CONTRARIAN Perspektive: Recency-Score
|
||||||
|
if hasattr(self, '_recency_counts'):
|
||||||
|
expected_freq = 30 * 5 / 50
|
||||||
|
recency_quality = np.mean([
|
||||||
|
max(0.0, (expected_freq - self._recency_counts.get(n, 0)) / expected_freq)
|
||||||
|
for n in main_numbers
|
||||||
|
])
|
||||||
|
else:
|
||||||
|
recency_quality = 0.5
|
||||||
|
|
||||||
|
quality = (
|
||||||
|
main_quality * 0.25
|
||||||
|
+ euro_quality * 0.15
|
||||||
|
+ pattern_quality * 0.15
|
||||||
|
+ diversity_quality * 0.10
|
||||||
|
+ popularity_quality * 0.20
|
||||||
|
+ recency_quality * 0.15
|
||||||
|
)
|
||||||
return min(quality, 1.0)
|
return min(quality, 1.0)
|
||||||
|
|
||||||
def _print_tip_line(self, tip):
|
def _print_tip_line(self, tip):
|
||||||
@@ -730,12 +808,12 @@ class UltimateAIMLEurojackpotGenerator:
|
|||||||
strategy_avg = {}
|
strategy_avg = {}
|
||||||
total = 0
|
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 = {
|
strategy_key = {
|
||||||
'pure_ai': 'PURE-AI',
|
|
||||||
'pure_pattern': 'PURE-PATTERN',
|
|
||||||
'hybrid_optimized': 'HYBRID-OPT',
|
'hybrid_optimized': 'HYBRID-OPT',
|
||||||
'ensemble_best': 'ENSEMBLE'
|
'balanced_spread': 'BALANCED-SPREAD',
|
||||||
|
'high_ev': 'HIGH-EV',
|
||||||
|
'soft_contrarian': 'SOFT-CONTRARIAN'
|
||||||
}[strategy]
|
}[strategy]
|
||||||
|
|
||||||
if strategy_key in strategy_performance:
|
if strategy_key in strategy_performance:
|
||||||
@@ -1826,7 +1904,7 @@ def main():
|
|||||||
|
|
||||||
print("\n💡 EUROJACKPOT ADVANTAGES:")
|
print("\n💡 EUROJACKPOT ADVANTAGES:")
|
||||||
print(" 🎰 5 aus 50 + 2 aus 12 optimiert")
|
print(" 🎰 5 aus 50 + 2 aus 12 optimiert")
|
||||||
print(" 🔬 4 Strategien: Pure-AI, Pure-Pattern, Hybrid, Ensemble")
|
print(" 🔬 4 Strategien: Hybrid-OPT, Balanced-Spread, High-EV, Soft-Contrarian")
|
||||||
print(" 🧠 Separate AI für Hauptzahlen + Eurozahlen")
|
print(" 🧠 Separate AI für Hauptzahlen + Eurozahlen")
|
||||||
print(" 🎨 Pattern-Analyse für 5er-Kombinationen")
|
print(" 🎨 Pattern-Analyse für 5er-Kombinationen")
|
||||||
print(" ⚡ Multi-Objective Optimization")
|
print(" ⚡ Multi-Objective Optimization")
|
||||||
|
|||||||
Reference in New Issue
Block a user