Improve generator quality and fix data gaps (Apr-May 2026)

Data:
- Add 12 missing draws (2026-01-09, 2026-04-03 to 2026-05-15)
- Retrain LSTM and RF models on complete 952-draw dataset
- Run retroactive learning for all 12 skipped draws

Automation:
- Add eurojackpot-zahlen.eu web scraper as fallback when APIs fail
- Fixes recurring gap problem caused by Sazka detail-endpoint change

Generator improvements:
- Add hard structural filters (sum 95-165, min 1 even + 1 odd per tip)
- Add long-term frequency prior as learner dampener (alpha=0.2)
- Fix ENSEMBLE strategy generating duplicate tips (greedy → weighted random)
- Fix non-vectorized frequency calculation (stack().value_counts())
- Fix Division-by-Zero edge case in set_frequency_prior
- Fix potential KeyError on euro_ai_score in structural filter loop

.gitignore:
- Exclude data/backups/, weekly tip CSVs, performance reports

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-19 10:35:57 +02:00
co-authored by Claude Sonnet 4.6
parent 98a74ff2a7
commit 4fc488c668
13 changed files with 1022 additions and 112 deletions
+6
View File
@@ -27,3 +27,9 @@ logs/
# Results (optional - uncomment if you don't want to track results)
# results/
# Backups und generierte Outputs
data/backups/
data/*.backup*
data/generated_tips/weekly_tips_*.csv
data/performance_reports/
+35
View File
@@ -916,3 +916,38 @@ datum;Z1;Z2;Z3;Z4;Z5;SZ1;SZ2
2026-01-06;21;23;30;33;38;8;12
2026-01-09;1;17;19;25;41;6;12
2026-01-13;2;16;27;33;47;6;12
2026-01-16;8;16;37;39;48;5;11
2026-01-20;16;26;32;37;45;2;3
2026-01-23;18;36;39;45;50;6;9
2026-01-27;13;18;19;29;32;8;9
2026-01-30;8;13;15;17;37;3;7
2026-02-03;3;20;27;37;44;1;2
2026-02-06;8;14;38;41;48;1;11
2026-02-10;12;19;34;39;47;4;5
2026-02-13;1;21;44;45;46;2;7
2026-02-17;8;23;39;40;44;6;7
2026-02-20;11;17;23;36;40;5;6
2026-02-24;4;5;26;38;48;2;9
2026-02-27;7;17;19;28;47;2;7
2026-03-03;1;9;14;35;49;2;10
2026-03-06;8;17;26;31;47;1;6
2026-03-10;2;3;17;18;28;4;10
2026-03-13;7;23;37;44;47;2;6
2026-03-17;12;13;16;17;37;4;11
2026-03-20;2;17;21;25;30;2;6
2026-03-24;9;15;23;43;48;3;5
2026-03-27;21;23;25;38;40;7;11
2026-03-31;5;15;18;20;35;7;8
2026-04-03;9;10;18;22;37;1;11
2026-04-07;2;4;16;23;27;5;8
2026-04-10;1;6;11;18;48;10;12
2026-04-14;13;22;32;46;47;6;7
2026-04-17;16;31;35;43;44;2;9
2026-04-21;31;32;36;39;47;7;8
2026-04-24;6;21;29;39;44;1;5
2026-04-28;19;20;41;43;46;5;7
2026-05-01;10;11;13;16;27;5;7
2026-05-05;1;30;33;34;43;5;10
2026-05-08;3;17;18;31;41;6;12
2026-05-12;7;15;19;28;35;3;11
2026-05-15;1;32;33;36;37;7;12
1 datum Z1 Z2 Z3 Z4 Z5 SZ1 SZ2
916 2026-01-06 21 23 30 33 38 8 12
917 2026-01-09 1 17 19 25 41 6 12
918 2026-01-13 2 16 27 33 47 6 12
919 2026-01-16 8 16 37 39 48 5 11
920 2026-01-20 16 26 32 37 45 2 3
921 2026-01-23 18 36 39 45 50 6 9
922 2026-01-27 13 18 19 29 32 8 9
923 2026-01-30 8 13 15 17 37 3 7
924 2026-02-03 3 20 27 37 44 1 2
925 2026-02-06 8 14 38 41 48 1 11
926 2026-02-10 12 19 34 39 47 4 5
927 2026-02-13 1 21 44 45 46 2 7
928 2026-02-17 8 23 39 40 44 6 7
929 2026-02-20 11 17 23 36 40 5 6
930 2026-02-24 4 5 26 38 48 2 9
931 2026-02-27 7 17 19 28 47 2 7
932 2026-03-03 1 9 14 35 49 2 10
933 2026-03-06 8 17 26 31 47 1 6
934 2026-03-10 2 3 17 18 28 4 10
935 2026-03-13 7 23 37 44 47 2 6
936 2026-03-17 12 13 16 17 37 4 11
937 2026-03-20 2 17 21 25 30 2 6
938 2026-03-24 9 15 23 43 48 3 5
939 2026-03-27 21 23 25 38 40 7 11
940 2026-03-31 5 15 18 20 35 7 8
941 2026-04-03 9 10 18 22 37 1 11
942 2026-04-07 2 4 16 23 27 5 8
943 2026-04-10 1 6 11 18 48 10 12
944 2026-04-14 13 22 32 46 47 6 7
945 2026-04-17 16 31 35 43 44 2 9
946 2026-04-21 31 32 36 39 47 7 8
947 2026-04-24 6 21 29 39 44 1 5
948 2026-04-28 19 20 41 43 46 5 7
949 2026-05-01 10 11 13 16 27 5 7
950 2026-05-05 1 30 33 34 43 5 10
951 2026-05-08 3 17 18 31 41 6 12
952 2026-05-12 7 15 19 28 35 3 11
953 2026-05-15 1 32 33 36 37 7 12
@@ -1,9 +1,9 @@
{
"trained_at": "2026-01-06T21:00:43.268063",
"num_samples": 895,
"trained_at": "2026-05-19T09:04:48.801117",
"num_samples": 932,
"num_features": 20,
"final_loss": 0.3324819803237915,
"final_val_loss": 0.3310294995705287,
"best_val_loss": 0.3291587332884471,
"epochs_trained": 25
"final_loss": 0.33304641644159955,
"final_val_loss": 0.32588819166024524,
"best_val_loss": 0.32180650532245636,
"epochs_trained": 26
}
@@ -1,9 +1,9 @@
{
"trained_at": "2026-01-06T21:00:33.679894",
"num_samples": 895,
"trained_at": "2026-05-19T09:04:39.307548",
"num_samples": 932,
"num_features": 20,
"final_loss": 0.33361901148505835,
"final_val_loss": 0.33026839792728424,
"best_val_loss": 0.32894887030124664,
"epochs_trained": 21
"final_loss": 0.3328763085107009,
"final_val_loss": 0.32958758374055225,
"best_val_loss": 0.32844950755437213,
"epochs_trained": 22
}
+69 -69
View File
@@ -1,78 +1,78 @@
{
"adjustments_main": {
"1": -0.014850499375000001,
"2": -0.014850499375000001,
"3": -0.014850499375000001,
"4": -0.014850499375000001,
"5": -0.014850499375000001,
"6": -0.014850499375000001,
"7": -0.014850499375000001,
"8": -0.014850499375000001,
"9": -0.014850499375000001,
"10": 0.014775998750000002,
"11": -0.014850499375000001,
"12": -0.014850499375000001,
"13": -0.014850499375000001,
"14": -0.014850499375000001,
"15": 0.014775998750000002,
"16": -0.014850499375000001,
"17": -0.014850499375000001,
"18": -0.014850499375000001,
"19": -0.014850499375000001,
"20": -0.014850499375000001,
"21": 7.450062499999855e-05,
"22": -0.014850499375000001,
"23": 7.450062499999855e-05,
"24": -0.014850499375000001,
"25": -0.014850499375000001,
"26": -0.014850499375000001,
"27": -0.014850499375000001,
"28": -0.014850499375000001,
"29": 0.014775998750000002,
"30": 7.450062499999855e-05,
"31": -0.014850499375000001,
"32": -0.014850499375000001,
"33": 7.450062499999855e-05,
"34": 0.014775998750000002,
"35": -0.014850499375000001,
"36": -0.014850499375000001,
"37": -0.014850499375000001,
"38": 0.029700998750000002,
"39": -0.014850499375000001,
"40": -0.014850499375000001,
"41": -0.014850499375000001,
"42": -0.014850499375000001,
"43": -0.014850499375000001,
"44": -0.014850499375000001,
"45": -0.014850499375000001,
"46": -0.014850499375000001,
"47": -0.014850499375000001,
"48": -0.014850499375000001,
"49": -0.014850499375000001,
"50": -0.014850499375000001
"1": -0.10279380235968341,
"2": -0.13095716137873015,
"3": -0.13124242248231174,
"4": -0.14500126295064525,
"5": -0.14528446311640075,
"6": -0.14417565349659103,
"7": -0.13063873780471033,
"8": -0.10750108984264332,
"9": -0.1310946271473281,
"10": -0.11881089921672196,
"11": -0.130293827736181,
"12": -0.14582604934178367,
"13": -0.10413094415362395,
"14": -0.14616329674563025,
"15": -0.09211480770812712,
"16": -0.09017423391013749,
"17": -0.049600737978451416,
"18": -0.07614090054869561,
"19": -0.08971018550072041,
"20": -0.1310497715983718,
"21": -0.10520101666420224,
"22": -0.1439620032143183,
"23": -0.07798238201251459,
"24": -0.17256771756515152,
"25": -0.13075509390384546,
"26": -0.13311702644877058,
"27": -0.13069306022006943,
"28": -0.130706924524329,
"29": -0.12087771213609635,
"30": -0.13149344990505507,
"31": -0.11517763380456655,
"32": -0.1181751293364082,
"33": -0.14526819693037055,
"34": -0.1198965423651197,
"35": -0.11574265121076999,
"36": -0.13206568352604026,
"37": -0.08004627851465437,
"38": -0.0950011097652101,
"39": -0.09245600556232672,
"40": -0.13225374226263362,
"41": -0.11599365320609464,
"42": -0.17256771756515152,
"43": -0.11483608658156753,
"44": -0.09121964210096198,
"45": -0.13410369632947294,
"46": -0.13042728917431096,
"47": -0.09006064815945719,
"48": -0.10552865925858317,
"49": -0.15913391270414332,
"50": -0.15985457481061624
},
"adjustments_euro": {
"1": -0.014850499375000001,
"2": 0.014775998750000002,
"3": -0.014850499375000001,
"4": -0.014850499375000001,
"5": -0.014850499375000001,
"6": -0.014850499375000001,
"7": -0.014850499375000001,
"8": 7.450062499999855e-05,
"9": 0.014775998750000002,
"10": -0.014850499375000001,
"11": -0.014850499375000001,
"12": 7.450062499999855e-05
"1": -0.10494098821942058,
"2": -0.027056675057008192,
"3": -0.11830793960044857,
"4": -0.1322568921376643,
"5": -0.047440853691181416,
"6": -0.049155618915874,
"7": -0.033897465674045044,
"8": -0.10446160077280368,
"9": -0.09443567741509633,
"10": -0.11645028869966062,
"11": -0.09027104593141426,
"12": -0.11673125927629154
},
"stats": {
"incorrect_main": 135,
"correct_main": 15,
"incorrect_euro": 30,
"correct_euro": 6,
"cycles": 3,
"last_update": "2026-01-06T21:00:43.269037"
"incorrect_main": 1710,
"correct_main": 190,
"incorrect_euro": 380,
"correct_euro": 76,
"cycles": 38,
"last_update": "2026-05-19T09:04:48.805027"
},
"learning_rate": 0.1,
"last_saved": "2026-01-06T21:00:43.269127"
"last_saved": "2026-05-19T09:04:48.805048"
}
Binary file not shown.
Binary file not shown.
+273
View File
@@ -132,6 +132,279 @@
"file": "weekly_tips_20260112_210015.csv",
"avg_confidence": 0.49425787623829,
"avg_quality": 0.6145839981272502
},
{
"timestamp": "2026-01-15T21:00:36.397005",
"num_tips": 10,
"file": "weekly_tips_20260115_210036.csv",
"avg_confidence": 0.47344565270354505,
"avg_quality": 0.5904032822464804
},
{
"timestamp": "2026-01-19T21:00:16.311402",
"num_tips": 10,
"file": "weekly_tips_20260119_210016.csv",
"avg_confidence": 0.5070366197890103,
"avg_quality": 0.6226148247071303
},
{
"timestamp": "2026-01-22T21:00:14.287352",
"num_tips": 10,
"file": "weekly_tips_20260122_210014.csv",
"avg_confidence": 0.47075732576357926,
"avg_quality": 0.5803838357908581
},
{
"timestamp": "2026-01-26T21:00:17.434360",
"num_tips": 10,
"file": "weekly_tips_20260126_210017.csv",
"avg_confidence": 0.49936013462178497,
"avg_quality": 0.6116474055527096
},
{
"timestamp": "2026-01-29T21:00:16.110547",
"num_tips": 10,
"file": "weekly_tips_20260129_210016.csv",
"avg_confidence": 0.5027779055427531,
"avg_quality": 0.6187842481123684
},
{
"timestamp": "2026-02-02T21:00:16.361899",
"num_tips": 10,
"file": "weekly_tips_20260202_210016.csv",
"avg_confidence": 0.5083071846982502,
"avg_quality": 0.6241986235247045
},
{
"timestamp": "2026-02-05T21:00:16.014229",
"num_tips": 10,
"file": "weekly_tips_20260205_210016.csv",
"avg_confidence": 0.47884710375116424,
"avg_quality": 0.5928701100797202
},
{
"timestamp": "2026-02-09T21:00:11.982561",
"num_tips": 10,
"file": "weekly_tips_20260209_210011.csv",
"avg_confidence": 0.506005904420015,
"avg_quality": 0.6214382457606871
},
{
"timestamp": "2026-02-12T21:00:17.021168",
"num_tips": 10,
"file": "weekly_tips_20260212_210017.csv",
"avg_confidence": 0.516596004507797,
"avg_quality": 0.6331268375743684
},
{
"timestamp": "2026-02-16T21:00:16.623850",
"num_tips": 10,
"file": "weekly_tips_20260216_210016.csv",
"avg_confidence": 0.5310911070168177,
"avg_quality": 0.646703887932404
},
{
"timestamp": "2026-02-19T21:00:20.011565",
"num_tips": 10,
"file": "weekly_tips_20260219_210020.csv",
"avg_confidence": 0.46533191116318023,
"avg_quality": 0.5782823546857643
},
{
"timestamp": "2026-02-23T21:00:17.473274",
"num_tips": 10,
"file": "weekly_tips_20260223_210017.csv",
"avg_confidence": 0.5473864222555807,
"avg_quality": 0.664821754795175
},
{
"timestamp": "2026-02-26T21:00:20.683783",
"num_tips": 10,
"file": "weekly_tips_20260226_210020.csv",
"avg_confidence": 0.48232944543098605,
"avg_quality": 0.5979756965479743
},
{
"timestamp": "2026-03-02T21:00:16.983767",
"num_tips": 10,
"file": "weekly_tips_20260302_210016.csv",
"avg_confidence": 0.48588377032008034,
"avg_quality": 0.5990305136121646
},
{
"timestamp": "2026-03-05T21:00:16.042941",
"num_tips": 10,
"file": "weekly_tips_20260305_210016.csv",
"avg_confidence": 0.48148432120929235,
"avg_quality": 0.5954960663012538
},
{
"timestamp": "2026-03-09T21:00:44.719111",
"num_tips": 10,
"file": "weekly_tips_20260309_210044.csv",
"avg_confidence": 0.47513731607893117,
"avg_quality": 0.5901054825014217
},
{
"timestamp": "2026-03-12T21:00:12.672070",
"num_tips": 10,
"file": "weekly_tips_20260312_210012.csv",
"avg_confidence": 0.5165879893938297,
"avg_quality": 0.631957616666093
},
{
"timestamp": "2026-03-16T21:00:15.064301",
"num_tips": 10,
"file": "weekly_tips_20260316_210015.csv",
"avg_confidence": 0.4437112546020575,
"avg_quality": 0.5636041119770521
},
{
"timestamp": "2026-03-19T21:02:48.840594",
"num_tips": 10,
"file": "weekly_tips_20260319_210248.csv",
"avg_confidence": 0.520967549190745,
"avg_quality": 0.6380107770109229
},
{
"timestamp": "2026-03-23T21:00:16.623635",
"num_tips": 10,
"file": "weekly_tips_20260323_210016.csv",
"avg_confidence": 0.4511070123898933,
"avg_quality": 0.5706980214609187
},
{
"timestamp": "2026-03-26T21:00:35.316354",
"num_tips": 10,
"file": "weekly_tips_20260326_210035.csv",
"avg_confidence": 0.45118965830170754,
"avg_quality": 0.5677275907732668
},
{
"timestamp": "2026-03-31T11:49:39.227248",
"num_tips": 10,
"file": "weekly_tips_20260331_114939.csv",
"avg_confidence": 0.4916429475874513,
"avg_quality": 0.6106521030019004
},
{
"timestamp": "2026-04-02T21:00:24.425902",
"num_tips": 10,
"file": "weekly_tips_20260402_210024.csv",
"avg_confidence": 0.4519687967653286,
"avg_quality": 0.5709825204600992
},
{
"timestamp": "2026-04-06T21:00:15.654198",
"num_tips": 10,
"file": "weekly_tips_20260406_210015.csv",
"avg_confidence": 0.4519687967653286,
"avg_quality": 0.5709825204600992
},
{
"timestamp": "2026-04-09T21:00:17.621420",
"num_tips": 10,
"file": "weekly_tips_20260409_210017.csv",
"avg_confidence": 0.4519687967653286,
"avg_quality": 0.5709825204600992
},
{
"timestamp": "2026-04-13T21:13:31.089816",
"num_tips": 10,
"file": "weekly_tips_20260413_211331.csv",
"avg_confidence": 0.4519687967653286,
"avg_quality": 0.5709825204600992
},
{
"timestamp": "2026-04-16T21:00:15.952947",
"num_tips": 10,
"file": "weekly_tips_20260416_210015.csv",
"avg_confidence": 0.4519687967653286,
"avg_quality": 0.5709825204600992
},
{
"timestamp": "2026-04-20T21:00:14.991940",
"num_tips": 10,
"file": "weekly_tips_20260420_210014.csv",
"avg_confidence": 0.4519687967653286,
"avg_quality": 0.5709825204600992
},
{
"timestamp": "2026-04-23T21:12:08.255403",
"num_tips": 10,
"file": "weekly_tips_20260423_211208.csv",
"avg_confidence": 0.4519687967653286,
"avg_quality": 0.5709825204600992
},
{
"timestamp": "2026-04-27T21:00:13.534906",
"num_tips": 10,
"file": "weekly_tips_20260427_210013.csv",
"avg_confidence": 0.48127824496557114,
"avg_quality": 0.5980047795669126
},
{
"timestamp": "2026-04-30T21:00:18.020165",
"num_tips": 10,
"file": "weekly_tips_20260430_210018.csv",
"avg_confidence": 0.48127824496557114,
"avg_quality": 0.5980047795669126
},
{
"timestamp": "2026-05-04T21:00:17.575648",
"num_tips": 10,
"file": "weekly_tips_20260504_210017.csv",
"avg_confidence": 0.48127824496557114,
"avg_quality": 0.5980047795669126
},
{
"timestamp": "2026-05-07T21:00:21.292869",
"num_tips": 10,
"file": "weekly_tips_20260507_210021.csv",
"avg_confidence": 0.48127824496557114,
"avg_quality": 0.5980047795669126
},
{
"timestamp": "2026-05-11T21:00:15.718384",
"num_tips": 10,
"file": "weekly_tips_20260511_210015.csv",
"avg_confidence": 0.48127824496557114,
"avg_quality": 0.5980047795669126
},
{
"timestamp": "2026-05-14T21:00:17.802557",
"num_tips": 10,
"file": "weekly_tips_20260514_210017.csv",
"avg_confidence": 0.48127824496557114,
"avg_quality": 0.5980047795669126
},
{
"timestamp": "2026-05-18T21:00:15.215525",
"num_tips": 10,
"file": "weekly_tips_20260518_210015.csv",
"avg_confidence": 0.48127824496557114,
"avg_quality": 0.5980047795669126
},
{
"timestamp": "2026-05-19T09:06:31.632241",
"num_tips": 10,
"file": "weekly_tips_20260519_090631.csv",
"avg_confidence": 0.4653688395892314,
"avg_quality": 0.5851349854679404
},
{
"timestamp": "2026-05-19T09:28:02.588177",
"num_tips": 10,
"file": "weekly_tips_20260519_092802.csv",
"avg_confidence": 0.49658478135540934,
"avg_quality": 0.6106212035500489
},
{
"timestamp": "2026-05-19T09:30:17.610297",
"num_tips": 10,
"file": "weekly_tips_20260519_093017.csv",
"avg_confidence": 0.47597948672799795,
"avg_quality": 0.5941141824821975
}
]
}
+493
View File
@@ -25,6 +25,499 @@
"main": 0.0,
"euro": 0.2
}
},
{
"timestamp": "2026-01-14T11:55:27.020649",
"draw_date": "2026-01-13",
"evaluation": {
"main": 3,
"euro": 1,
"tip": 5
},
"avg_matches": {
"main": 0.9,
"euro": 0.1
}
},
{
"timestamp": "2026-01-17T08:00:38.348746",
"draw_date": "2026-01-16",
"evaluation": {
"main": 1,
"euro": 2,
"tip": 6
},
"avg_matches": {
"main": 0.6,
"euro": 1.0
}
},
{
"timestamp": "2026-01-21T08:00:36.393922",
"draw_date": "2026-01-20",
"evaluation": {
"main": 2,
"euro": 0,
"tip": 7
},
"avg_matches": {
"main": 0.4,
"euro": 0.0
}
},
{
"timestamp": "2026-01-24T08:00:39.548611",
"draw_date": "2026-01-23",
"evaluation": {
"main": 1,
"euro": 0,
"tip": 2
},
"avg_matches": {
"main": 0.4,
"euro": 0.0
}
},
{
"timestamp": "2026-01-28T08:00:33.205219",
"draw_date": "2026-01-27",
"evaluation": {
"main": 2,
"euro": 0,
"tip": 6
},
"avg_matches": {
"main": 0.4,
"euro": 0.2
}
},
{
"timestamp": "2026-01-31T08:00:32.122558",
"draw_date": "2026-01-30",
"evaluation": {
"main": 2,
"euro": 0,
"tip": 5
},
"avg_matches": {
"main": 0.6,
"euro": 0.0
}
},
{
"timestamp": "2026-02-04T08:15:31.767102",
"draw_date": "2026-02-03",
"evaluation": {
"main": 1,
"euro": 1,
"tip": 1
},
"avg_matches": {
"main": 0.7,
"euro": 0.4
}
},
{
"timestamp": "2026-02-07T08:09:09.885694",
"draw_date": "2026-02-06",
"evaluation": {
"main": 1,
"euro": 1,
"tip": 1
},
"avg_matches": {
"main": 0.7,
"euro": 0.7
}
},
{
"timestamp": "2026-02-11T08:00:51.090316",
"draw_date": "2026-02-10",
"evaluation": {
"main": 2,
"euro": 1,
"tip": 6
},
"avg_matches": {
"main": 0.5,
"euro": 0.6
}
},
{
"timestamp": "2026-02-14T08:00:37.526380",
"draw_date": "2026-02-13",
"evaluation": {
"main": 1,
"euro": 1,
"tip": 1
},
"avg_matches": {
"main": 0.5,
"euro": 0.5
}
},
{
"timestamp": "2026-02-18T08:00:35.624032",
"draw_date": "2026-02-17",
"evaluation": {
"main": 1,
"euro": 1,
"tip": 6
},
"avg_matches": {
"main": 0.1,
"euro": 0.2
}
},
{
"timestamp": "2026-02-21T08:00:36.839728",
"draw_date": "2026-02-20",
"evaluation": {
"main": 1,
"euro": 0,
"tip": 2
},
"avg_matches": {
"main": 0.2,
"euro": 0.0
}
},
{
"timestamp": "2026-02-25T08:00:32.739559",
"draw_date": "2026-02-24",
"evaluation": {
"main": 3,
"euro": 0,
"tip": 8
},
"avg_matches": {
"main": 1.6,
"euro": 0.1
}
},
{
"timestamp": "2026-02-28T08:00:36.899068",
"draw_date": "2026-02-27",
"evaluation": {
"main": 1,
"euro": 0,
"tip": 1
},
"avg_matches": {
"main": 0.9,
"euro": 0.0
}
},
{
"timestamp": "2026-03-04T08:00:35.914866",
"draw_date": "2026-03-03",
"evaluation": {
"main": 1,
"euro": 0,
"tip": 1
},
"avg_matches": {
"main": 0.2,
"euro": 0.4
}
},
{
"timestamp": "2026-03-07T08:01:50.476303",
"draw_date": "2026-03-06",
"evaluation": {
"main": 0,
"euro": 1,
"tip": 1
},
"avg_matches": {
"main": 0.0,
"euro": 0.6
}
},
{
"timestamp": "2026-03-11T08:05:41.163992",
"draw_date": "2026-03-10",
"evaluation": {
"main": 3,
"euro": 0,
"tip": 6
},
"avg_matches": {
"main": 1.2,
"euro": 0.3
}
},
{
"timestamp": "2026-03-14T08:04:02.373169",
"draw_date": "2026-03-13",
"evaluation": {
"main": 1,
"euro": 0,
"tip": 1
},
"avg_matches": {
"main": 0.2,
"euro": 0.4
}
},
{
"timestamp": "2026-03-18T08:00:37.435414",
"draw_date": "2026-03-17",
"evaluation": {
"main": 1,
"euro": 2,
"tip": 10
},
"avg_matches": {
"main": 0.2,
"euro": 0.8
}
},
{
"timestamp": "2026-03-21T08:09:51.906930",
"draw_date": "2026-03-20",
"evaluation": {
"main": 2,
"euro": 1,
"tip": 6
},
"avg_matches": {
"main": 0.5,
"euro": 0.1
}
},
{
"timestamp": "2026-03-25T08:01:44.927862",
"draw_date": "2026-03-24",
"evaluation": {
"main": 1,
"euro": 1,
"tip": 3
},
"avg_matches": {
"main": 0.6,
"euro": 0.5
}
},
{
"timestamp": "2026-03-28T08:00:38.065825",
"draw_date": "2026-03-27",
"evaluation": {
"main": 1,
"euro": 1,
"tip": 1
},
"avg_matches": {
"main": 0.2,
"euro": 0.6
}
},
{
"timestamp": "2026-04-01T08:15:32.393678",
"draw_date": "2026-03-31",
"evaluation": {
"main": 1,
"euro": 0,
"tip": 2
},
"avg_matches": {
"main": 0.6,
"euro": 0.1
}
},
{
"timestamp": "2026-04-25T08:00:37.702550",
"draw_date": "2026-04-24",
"evaluation": {
"main": 1,
"euro": 1,
"tip": 6
},
"avg_matches": {
"main": 0.2,
"euro": 0.4
}
},
{
"timestamp": "2026-05-19T09:01:38.051039",
"draw_date": "2026-05-15",
"evaluation": {
"main": 1,
"euro": 1,
"tip": 8
},
"avg_matches": {
"main": 0.5,
"euro": 0.3
}
},
{
"timestamp": "2026-05-19T09:04:48.802220",
"draw_date": "2026-01-09",
"evaluation": {
"main": 0,
"euro": 0,
"tip": 0
},
"avg_matches": {
"main": 0.0,
"euro": 0.0
},
"note": "retroactive_learning"
},
{
"timestamp": "2026-05-19T09:04:48.802560",
"draw_date": "2026-04-03",
"evaluation": {
"main": 0,
"euro": 0,
"tip": 0
},
"avg_matches": {
"main": 0.0,
"euro": 0.0
},
"note": "retroactive_learning"
},
{
"timestamp": "2026-05-19T09:04:48.802849",
"draw_date": "2026-04-07",
"evaluation": {
"main": 0,
"euro": 0,
"tip": 0
},
"avg_matches": {
"main": 0.0,
"euro": 0.0
},
"note": "retroactive_learning"
},
{
"timestamp": "2026-05-19T09:04:48.803128",
"draw_date": "2026-04-10",
"evaluation": {
"main": 0,
"euro": 0,
"tip": 0
},
"avg_matches": {
"main": 0.0,
"euro": 0.0
},
"note": "retroactive_learning"
},
{
"timestamp": "2026-05-19T09:04:48.803396",
"draw_date": "2026-04-14",
"evaluation": {
"main": 0,
"euro": 0,
"tip": 0
},
"avg_matches": {
"main": 0.0,
"euro": 0.0
},
"note": "retroactive_learning"
},
{
"timestamp": "2026-05-19T09:04:48.803660",
"draw_date": "2026-04-17",
"evaluation": {
"main": 0,
"euro": 0,
"tip": 0
},
"avg_matches": {
"main": 0.0,
"euro": 0.0
},
"note": "retroactive_learning"
},
{
"timestamp": "2026-05-19T09:04:48.803919",
"draw_date": "2026-04-21",
"evaluation": {
"main": 0,
"euro": 0,
"tip": 0
},
"avg_matches": {
"main": 0.0,
"euro": 0.0
},
"note": "retroactive_learning"
},
{
"timestamp": "2026-05-19T09:04:48.804186",
"draw_date": "2026-04-28",
"evaluation": {
"main": 0,
"euro": 0,
"tip": 0
},
"avg_matches": {
"main": 0.0,
"euro": 0.0
},
"note": "retroactive_learning"
},
{
"timestamp": "2026-05-19T09:04:48.804444",
"draw_date": "2026-05-01",
"evaluation": {
"main": 0,
"euro": 0,
"tip": 0
},
"avg_matches": {
"main": 0.0,
"euro": 0.0
},
"note": "retroactive_learning"
},
{
"timestamp": "2026-05-19T09:04:48.804706",
"draw_date": "2026-05-05",
"evaluation": {
"main": 0,
"euro": 0,
"tip": 0
},
"avg_matches": {
"main": 0.0,
"euro": 0.0
},
"note": "retroactive_learning"
},
{
"timestamp": "2026-05-19T09:04:48.804960",
"draw_date": "2026-05-08",
"evaluation": {
"main": 0,
"euro": 0,
"tip": 0
},
"avg_matches": {
"main": 0.0,
"euro": 0.0
},
"note": "retroactive_learning"
},
{
"timestamp": "2026-05-19T09:04:48.805219",
"draw_date": "2026-05-12",
"evaluation": {
"main": 0,
"euro": 0,
"tip": 0
},
"avg_matches": {
"main": 0.0,
"euro": 0.0
},
"note": "retroactive_learning"
}
]
}
+11 -1
View File
@@ -27,6 +27,7 @@ project_dir = os.path.dirname(os.path.dirname(script_dir))
sys.path.insert(0, project_dir)
from scripts.utils.update_from_api import EurojackpotAPIUpdater
from scripts.utils.update_from_eurojackpot_zahlen_eu import EurojackpotUpdater as WebScraper
from scripts.generators.ultimate_ai_ml_eurojackpot_generator import UltimateAIMLEurojackpotGenerator
from scripts.utils.notifier import EurojackpotNotifier
@@ -129,7 +130,16 @@ class AutoUpdateAndLearn:
if success:
print(" ✅ Daten erfolgreich aktualisiert")
else:
print(" ⚠️ Update ohne neue Daten")
print(" ⚠️ API-Update ohne neue Daten, versuche Web-Scraper...")
try:
scraper = WebScraper(self.data_file)
success = scraper.update(create_backup=False)
if success:
print(" ✅ Web-Scraper erfolgreich")
else:
print(" ⚠️ Web-Scraper ohne neue Daten")
except Exception as scrape_err:
print(f" ❌ Web-Scraper Fehler: {scrape_err}")
return success
@@ -164,6 +164,12 @@ class UltimateAIMLEurojackpotGenerator:
# 6. Initialize Real-Time Learning
print("📚 Activating Real-Time Learning...", end=" ", flush=True)
self.real_time_learner.initialize(self.features_df)
# Langzeit-Frequenz als Dämpfer übergeben
_main_counts = self.df[['Z1','Z2','Z3','Z4','Z5']].stack().value_counts()
_euro_counts = self.df[['SZ1','SZ2']].stack().value_counts()
freq_main = {n: int(_main_counts.get(n, 0)) for n in range(1, 51)}
freq_euro = {n: int(_euro_counts.get(n, 0)) for n in range(1, 13)}
self.real_time_learner.set_frequency_prior(freq_main, freq_euro)
print("")
self.is_trained = self.ai_ml_engine.is_trained
@@ -251,6 +257,21 @@ class UltimateAIMLEurojackpotGenerator:
tip_counter += len(tips)
print(f"✅ ({count} tips)")
# Strukturfilter: Summe + Parität korrigieren
fixed_count = 0
for tip in all_tips:
if not self._passes_structural_constraints(tip['main_numbers']):
tip['main_numbers'] = self._apply_structural_fix(tip['main_numbers'], main_predictions)
tip['main_ai_score'] = np.mean([main_predictions.get(n, 0.1) for n in tip['main_numbers']])
tip['pattern_weight'] = self.pattern_engine.calculate_pattern_weight(tip['main_numbers'])
tip['confidence'] = tip['main_ai_score'] * 0.5 + tip.get('euro_ai_score', 0.0) * 0.3 + tip['pattern_weight'] * 0.2
tip['quality'] = self._calculate_quality_score(
tip['main_numbers'], tip['euro_numbers'], main_predictions, euro_predictions, tip['pattern_weight']
)
fixed_count += 1
if fixed_count:
print(f" 🔧 {fixed_count} Tip(s) via Strukturfilter korrigiert (Summe/Parität)")
# Output all tips
print(f"\n📋 RESULTS:")
print("=" * 100)
@@ -459,27 +480,20 @@ class UltimateAIMLEurojackpotGenerator:
selected_main = []
for position in range(5):
best_candidate = None
best_score = -1
for candidate in all_candidates:
if candidate not in selected_main:
ai_s = main_preds.get(candidate, 0.1)
pattern_s = self.pattern_engine.get_number_pattern_score(candidate)
diversity_s = self._calculate_diversity_score(candidate, selected_main) if selected_main else 0.5
ensemble_score = (ai_s * 0.4 + pattern_s * 0.3 + diversity_s * 0.3)
if ensemble_score > best_score:
best_score = ensemble_score
best_candidate = candidate
if best_candidate:
selected_main.append(best_candidate)
else:
available = [n for n in range(1, 51) if n not in selected_main]
if available:
selected_main.append(random.choice(available))
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])
@@ -505,6 +519,69 @@ class UltimateAIMLEurojackpotGenerator:
'quality': quality
}
def _passes_structural_constraints(self, main_numbers):
"""Prüft Summenbereich und Parität."""
s = sum(main_numbers)
if s < 95 or s > 165:
return False
even = sum(1 for n in main_numbers if n % 2 == 0)
if even == 0 or even == 5:
return False
return True
def _apply_structural_fix(self, main_numbers, main_preds):
"""Korrigiert Summe/Parität durch minimalen Tausch."""
numbers = list(main_numbers)
# Parität: mind. 1 gerade und 1 ungerade
even = [n for n in numbers if n % 2 == 0]
odd = [n for n in numbers if n % 2 != 0]
if len(even) == 0:
# alle ungerade → tausche den am schlechtesten bewerteten gegen bestes gerades
worst = min(odd, key=lambda n: main_preds.get(n, 0))
candidates = sorted(
[n for n in range(2, 51, 2) if n not in numbers],
key=lambda n: -main_preds.get(n, 0)
)
if candidates:
numbers.remove(worst)
numbers.append(candidates[0])
elif len(odd) == 0:
worst = min(even, key=lambda n: main_preds.get(n, 0))
candidates = sorted(
[n for n in range(1, 51, 2) if n not in numbers],
key=lambda n: -main_preds.get(n, 0)
)
if candidates:
numbers.remove(worst)
numbers.append(candidates[0])
# Summe korrigieren
for _ in range(10):
s = sum(numbers)
if 95 <= s <= 165:
break
if s > 165:
highest = max(numbers)
candidates = sorted(
[n for n in range(1, highest) if n not in numbers],
key=lambda n: -main_preds.get(n, 0)
)
if candidates:
numbers.remove(highest)
numbers.append(candidates[0])
else:
lowest = min(numbers)
candidates = sorted(
[n for n in range(lowest + 1, 51) if n not in numbers],
key=lambda n: -main_preds.get(n, 0)
)
if candidates:
numbers.remove(lowest)
numbers.append(candidates[0])
return sorted(numbers)
def _calculate_diversity_score(self, candidate, selected):
"""Berechnet Diversität."""
if not selected:
@@ -1473,6 +1550,9 @@ class EurojackpotRealTimeLearner:
self.stats = defaultdict(int)
self.cache_path = cache_path
self.learning_state_file = os.path.join(cache_path, 'learning_state.json') if cache_path else None
self.freq_prior_main = {} # Langzeit-Frequenz Dämpfer
self.freq_prior_euro = {}
self.freq_alpha = 0.2 # 20% Langzeit-Frequenz, 80% Learner
# Lade gespeicherten State
if self.learning_state_file and os.path.exists(self.learning_state_file):
@@ -1482,24 +1562,37 @@ class EurojackpotRealTimeLearner:
"""Initialisiert Learning."""
self.features_df = features_df
def adjust_main_predictions(self, predictions):
"""Passt Main Predictions an."""
adjusted = {}
def set_frequency_prior(self, freq_main, freq_euro):
"""Setzt Langzeit-Frequenz als Dämpfer (normalisiert auf [0,1])."""
max_main = max(freq_main.values(), default=0) or 1
max_euro = max(freq_euro.values(), default=0) or 1
self.freq_prior_main = {n: v / max_main for n, v in freq_main.items()}
self.freq_prior_euro = {n: v / max_euro for n, v in freq_euro.items()}
def adjust_main_predictions(self, predictions):
"""Passt Main Predictions an, gedämpft durch Langzeit-Frequenz."""
adjusted = {}
for number, pred in predictions.items():
adjustment = self.adjustments_main.get(number, 0)
adjusted[number] = np.clip(pred + adjustment * self.learning_rate, 0, 1)
learner_val = np.clip(pred + adjustment * self.learning_rate, 0, 1)
if self.freq_prior_main:
freq_val = self.freq_prior_main.get(number, 0.5)
adjusted[number] = (1 - self.freq_alpha) * learner_val + self.freq_alpha * freq_val
else:
adjusted[number] = learner_val
return adjusted
def adjust_euro_predictions(self, predictions):
"""Passt Euro Predictions an."""
"""Passt Euro Predictions an, gedämpft durch Langzeit-Frequenz."""
adjusted = {}
for number, pred in predictions.items():
adjustment = self.adjustments_euro.get(number, 0)
adjusted[number] = np.clip(pred + adjustment * self.learning_rate, 0, 1)
learner_val = np.clip(pred + adjustment * self.learning_rate, 0, 1)
if self.freq_prior_euro:
freq_val = self.freq_prior_euro.get(number, 0.5)
adjusted[number] = (1 - self.freq_alpha) * learner_val + self.freq_alpha * freq_val
else:
adjusted[number] = learner_val
return adjusted
def learn_from_result(self, drawing):