271 lines
10 KiB
Python
271 lines
10 KiB
Python
#!/usr/bin/env python3
|
|||
|
|
"""
|
||
|
|
Eurojackpot Treffer-Analyse (umschlüsselte Werte)
|
||
|
|
|
||
|
|
Analysiert, wo die größten Treffer-Wahrscheinlichkeiten bei den umschlüsselten Werten liegen.
|
||
|
|
"""
|
||
|
|
|
||
|
|
import pandas as pd
|
||
|
|
from collections import Counter, defaultdict
|
||
|
|
import numpy as np
|
||
|
|
|
||
|
|
def analyze_hit_probabilities():
|
||
|
|
"""Analysiert die Treffer-Wahrscheinlichkeiten der umschlüsselten Werte."""
|
||
|
|
|
||
|
|
# Umschlüsselte Daten laden
|
||
|
|
df = pd.read_csv("/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/AlleEurojackpotzahlen_umschluesselt.csv", sep=';')
|
||
|
|
|
||
|
|
print("🎯 TREFFER-ANALYSE UMSCHLÜSSELTE WERTE (1-10)")
|
||
|
|
print("="*60)
|
||
|
|
print(f"Analysierte Ziehungen: {len(df)}")
|
||
|
|
|
||
|
|
# 1. Einzelne Gruppen-Wahrscheinlichkeiten pro Position
|
||
|
|
print(f"\n🏆 HÖCHSTE TREFFER-WAHRSCHEINLICHKEITEN PRO POSITION:")
|
||
|
|
print("="*55)
|
||
|
|
|
||
|
|
positions = ['z1', 'z2', 'z3', 'z4', 'z5']
|
||
|
|
position_stats = {}
|
||
|
|
|
||
|
|
for pos in positions:
|
||
|
|
group_counts = Counter(df[pos])
|
||
|
|
total = len(df)
|
||
|
|
|
||
|
|
# Beste Gruppe für diese Position
|
||
|
|
best_group = max(group_counts, key=group_counts.get)
|
||
|
|
best_count = group_counts[best_group]
|
||
|
|
best_probability = (best_count / total) * 100
|
||
|
|
|
||
|
|
position_stats[pos] = {
|
||
|
|
'best_group': best_group,
|
||
|
|
'probability': best_probability,
|
||
|
|
'count': best_count,
|
||
|
|
'all_groups': group_counts
|
||
|
|
}
|
||
|
|
|
||
|
|
print(f"\n{pos.upper()}: Gruppe {best_group} führt mit {best_probability:.1f}% ({best_count}/{total})")
|
||
|
|
|
||
|
|
# Top 3 für diese Position
|
||
|
|
top_3 = group_counts.most_common(3)
|
||
|
|
print(f" Top 3: ", end="")
|
||
|
|
for i, (group, count) in enumerate(top_3):
|
||
|
|
prob = (count / total) * 100
|
||
|
|
print(f"{i+1}.Gruppe {group}({prob:.1f}%)", end="")
|
||
|
|
if i < 2:
|
||
|
|
print(" > ", end="")
|
||
|
|
print()
|
||
|
|
|
||
|
|
# 2. Beste Gesamtkombination
|
||
|
|
print(f"\n🔥 OPTIMAL-KOMBINATION (höchste Einzelwahrscheinlichkeiten):")
|
||
|
|
print("="*60)
|
||
|
|
|
||
|
|
optimal_combination = []
|
||
|
|
total_probability = 1.0
|
||
|
|
|
||
|
|
for pos in positions:
|
||
|
|
best_group = position_stats[pos]['best_group']
|
||
|
|
probability = position_stats[pos]['probability'] / 100
|
||
|
|
optimal_combination.append(best_group)
|
||
|
|
total_probability *= probability
|
||
|
|
|
||
|
|
print(f"{pos}: Gruppe {best_group} ({position_stats[pos]['probability']:.1f}%)")
|
||
|
|
|
||
|
|
optimal_string = '-'.join(map(str, optimal_combination))
|
||
|
|
print(f"\nOptimal-Kombination: {optimal_string}")
|
||
|
|
print(f"Theoretische Wahrscheinlichkeit: {total_probability*100:.6f}%")
|
||
|
|
print(f"Das entspricht etwa 1 in {1/total_probability:,.0f} Ziehungen")
|
||
|
|
|
||
|
|
# 3. Tatsächlich aufgetretene häufigste Kombinationen
|
||
|
|
print(f"\n📊 REAL AUFGETRETENE HÄUFIGSTE KOMBINATIONEN:")
|
||
|
|
print("="*50)
|
||
|
|
|
||
|
|
combination_counts = Counter(df['kombination_umschluesselt'])
|
||
|
|
|
||
|
|
print(f"Top 20 real aufgetretene Kombinationen:")
|
||
|
|
for i, (combination, count) in enumerate(combination_counts.most_common(20), 1):
|
||
|
|
probability = (count / len(df)) * 100
|
||
|
|
print(f"{i:2}. {combination:15} {count}x ({probability:.2f}%)")
|
||
|
|
|
||
|
|
# 4. Bereichs-Kombinationen mit höchster Wahrscheinlichkeit
|
||
|
|
print(f"\n🎲 BEREICHS-KOMBINATIONEN MIT HÖCHSTER WAHRSCHEINLICHKEIT:")
|
||
|
|
print("="*60)
|
||
|
|
|
||
|
|
# Niedrig (1-3), Mittel (4-7), Hoch (8-10) Kombinationen
|
||
|
|
range_combinations = defaultdict(int)
|
||
|
|
|
||
|
|
for _, row in df.iterrows():
|
||
|
|
ranges = []
|
||
|
|
for pos in positions:
|
||
|
|
val = row[pos]
|
||
|
|
if 1 <= val <= 3:
|
||
|
|
ranges.append('N') # Niedrig
|
||
|
|
elif 4 <= val <= 7:
|
||
|
|
ranges.append('M') # Mittel
|
||
|
|
else:
|
||
|
|
ranges.append('H') # Hoch
|
||
|
|
|
||
|
|
range_pattern = ''.join(ranges)
|
||
|
|
range_combinations[range_pattern] += 1
|
||
|
|
|
||
|
|
print(f"Häufigste Bereichsmuster (N=Niedrig1-3, M=Mittel4-7, H=Hoch8-10):")
|
||
|
|
sorted_patterns = sorted(range_combinations.items(), key=lambda x: x[1], reverse=True)
|
||
|
|
|
||
|
|
for i, (pattern, count) in enumerate(sorted_patterns[:15], 1):
|
||
|
|
probability = (count / len(df)) * 100
|
||
|
|
pattern_readable = pattern.replace('N', 'Niedrig').replace('M', 'Mittel').replace('H', 'Hoch')
|
||
|
|
print(f"{i:2}. {pattern:5} ({pattern_readable:25}) {count:3}x ({probability:5.1f}%)")
|
||
|
|
|
||
|
|
# 5. Positions-spezifische Empfehlungen
|
||
|
|
print(f"\n💡 POSITIONS-SPEZIFISCHE EMPFEHLUNGEN:")
|
||
|
|
print("="*45)
|
||
|
|
|
||
|
|
recommendations = {}
|
||
|
|
|
||
|
|
for pos in positions:
|
||
|
|
group_counts = position_stats[pos]['all_groups']
|
||
|
|
total = len(df)
|
||
|
|
|
||
|
|
# Top 3 Gruppen für maximale Abdeckung
|
||
|
|
top_groups = [group for group, count in group_counts.most_common(3)]
|
||
|
|
top_coverage = sum(group_counts[group] for group in top_groups)
|
||
|
|
coverage_percentage = (top_coverage / total) * 100
|
||
|
|
|
||
|
|
recommendations[pos] = {
|
||
|
|
'top_groups': top_groups,
|
||
|
|
'coverage': coverage_percentage
|
||
|
|
}
|
||
|
|
|
||
|
|
print(f"\n{pos.upper()}: Empfohlene Gruppen {top_groups}")
|
||
|
|
print(f" Abdeckung: {coverage_percentage:.1f}% aller Ziehungen")
|
||
|
|
|
||
|
|
# Wahrscheinlichkeitsverteilung
|
||
|
|
print(f" Verteilung: ", end="")
|
||
|
|
for group in top_groups:
|
||
|
|
prob = (group_counts[group] / total) * 100
|
||
|
|
print(f"Gruppe {group}({prob:.1f}%)", end="")
|
||
|
|
if group != top_groups[-1]:
|
||
|
|
print(", ", end="")
|
||
|
|
print()
|
||
|
|
|
||
|
|
# 6. Strategische Kombinationen
|
||
|
|
print(f"\n🎯 STRATEGISCHE KOMBINATIONEN FÜR MAXIMALE TREFFER:")
|
||
|
|
print("="*55)
|
||
|
|
|
||
|
|
# Berechne verschiedene Strategien
|
||
|
|
strategies = {
|
||
|
|
'Konservativ': {
|
||
|
|
'z1': [1, 2], # Top 2 der Position z1
|
||
|
|
'z2': [3, 4], # Top 2 der Position z2
|
||
|
|
'z3': [5, 6], # Top 2 der Position z3
|
||
|
|
'z4': [7, 8], # Top 2 der Position z4
|
||
|
|
'z5': [9, 10] # Top 2 der Position z5
|
||
|
|
},
|
||
|
|
'Ausgewogen': {
|
||
|
|
'z1': [1, 2, 3], # Top 3 jeder Position
|
||
|
|
'z2': [3, 4, 5],
|
||
|
|
'z3': [4, 5, 6, 7],
|
||
|
|
'z4': [6, 7, 8],
|
||
|
|
'z5': [8, 9, 10]
|
||
|
|
},
|
||
|
|
'Optimal': {} # Wird basierend auf tatsächlichen Daten gefüllt
|
||
|
|
}
|
||
|
|
|
||
|
|
# Optimal-Strategie basierend auf echten Top-3 pro Position
|
||
|
|
for pos in positions:
|
||
|
|
top_3_groups = recommendations[pos]['top_groups']
|
||
|
|
strategies['Optimal'][pos] = top_3_groups
|
||
|
|
|
||
|
|
for strategy_name, strategy in strategies.items():
|
||
|
|
if strategy: # Nur wenn Strategie gefüllt ist
|
||
|
|
print(f"\n{strategy_name}-Strategie:")
|
||
|
|
total_combinations = 1
|
||
|
|
coverage_per_position = []
|
||
|
|
|
||
|
|
for pos in positions:
|
||
|
|
recommended_groups = strategy[pos]
|
||
|
|
pos_stats = position_stats[pos]['all_groups']
|
||
|
|
total_pos = len(df)
|
||
|
|
|
||
|
|
# Abdeckung dieser Gruppen
|
||
|
|
coverage = sum(pos_stats.get(group, 0) for group in recommended_groups)
|
||
|
|
coverage_pct = (coverage / total_pos) * 100
|
||
|
|
coverage_per_position.append(coverage_pct)
|
||
|
|
|
||
|
|
total_combinations *= len(recommended_groups)
|
||
|
|
|
||
|
|
print(f" {pos}: Gruppen {recommended_groups} ({coverage_pct:.1f}% Abdeckung)")
|
||
|
|
|
||
|
|
avg_coverage = np.mean(coverage_per_position)
|
||
|
|
print(f" Durchschnittliche Abdeckung: {avg_coverage:.1f}%")
|
||
|
|
print(f" Mögliche Kombinationen: {total_combinations:,}")
|
||
|
|
|
||
|
|
# 7. Heiße und kalte Zahlen
|
||
|
|
print(f"\n🔥❄️ HEISSE UND KALTE GRUPPEN:")
|
||
|
|
print("="*35)
|
||
|
|
|
||
|
|
# Alle Gruppen über alle Positionen sammeln
|
||
|
|
all_groups = []
|
||
|
|
for pos in positions:
|
||
|
|
all_groups.extend(df[pos].tolist())
|
||
|
|
|
||
|
|
group_total_counts = Counter(all_groups)
|
||
|
|
total_appearances = len(all_groups)
|
||
|
|
expected_per_group = total_appearances / 10 # 10 Gruppen
|
||
|
|
|
||
|
|
print(f"Erwartete Häufigkeit pro Gruppe: {expected_per_group:.1f}")
|
||
|
|
print(f"\nHeisse Gruppen (über Erwartung):")
|
||
|
|
hot_groups = []
|
||
|
|
for group in range(1, 11):
|
||
|
|
actual = group_total_counts.get(group, 0)
|
||
|
|
deviation = actual - expected_per_group
|
||
|
|
if deviation > 0:
|
||
|
|
hot_groups.append((group, actual, deviation))
|
||
|
|
|
||
|
|
hot_groups.sort(key=lambda x: x[2], reverse=True)
|
||
|
|
for group, count, deviation in hot_groups:
|
||
|
|
percentage = (count / total_appearances) * 100
|
||
|
|
print(f" Gruppe {group}: {count} (+{deviation:.1f}, {percentage:.1f}%)")
|
||
|
|
|
||
|
|
print(f"\nKalte Gruppen (unter Erwartung):")
|
||
|
|
cold_groups = []
|
||
|
|
for group in range(1, 11):
|
||
|
|
actual = group_total_counts.get(group, 0)
|
||
|
|
deviation = actual - expected_per_group
|
||
|
|
if deviation < 0:
|
||
|
|
cold_groups.append((group, actual, deviation))
|
||
|
|
|
||
|
|
cold_groups.sort(key=lambda x: x[2])
|
||
|
|
for group, count, deviation in cold_groups:
|
||
|
|
percentage = (count / total_appearances) * 100
|
||
|
|
print(f" Gruppe {group}: {count} ({deviation:.1f}, {percentage:.1f}%)")
|
||
|
|
|
||
|
|
# 8. Export der Empfehlungen
|
||
|
|
print(f"\n💾 EMPFEHLUNGEN EXPORT:")
|
||
|
|
print("="*25)
|
||
|
|
|
||
|
|
# Erstelle Empfehlungs-DataFrame
|
||
|
|
recommendation_data = []
|
||
|
|
|
||
|
|
# Für jede Position die besten Empfehlungen
|
||
|
|
for pos in positions:
|
||
|
|
pos_recommendations = recommendations[pos]
|
||
|
|
for group in pos_recommendations['top_groups']:
|
||
|
|
prob = (position_stats[pos]['all_groups'][group] / len(df)) * 100
|
||
|
|
recommendation_data.append({
|
||
|
|
'position': pos,
|
||
|
|
'gruppe': group,
|
||
|
|
'wahrscheinlichkeit_prozent': prob,
|
||
|
|
'anzahl_auftreten': position_stats[pos]['all_groups'][group],
|
||
|
|
'empfehlung_rang': pos_recommendations['top_groups'].index(group) + 1
|
||
|
|
})
|
||
|
|
|
||
|
|
rec_df = pd.DataFrame(recommendation_data)
|
||
|
|
output_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Eurojackpot/treffer_empfehlungen_umschluesselt.csv"
|
||
|
|
rec_df.to_csv(output_file, sep=';', index=False)
|
||
|
|
|
||
|
|
print(f"✅ Empfehlungen gespeichert: treffer_empfehlungen_umschluesselt.csv")
|
||
|
|
|
||
|
|
return position_stats, recommendations
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
analyze_hit_probabilities()
|