Prediksi untuk hasil selanjutnya yang akurat dan j...

Creato il: 30 maggio 2026

Risposto usando GPT-5.5 Thinking da Chat01

Domanda

data_ekstraksi.json

Prediksi untuk hasil selanjutnya yang akurat dan jitu dan buatkan scriptnya untuk di jalankan di google colab

Python

python
import json, os, textwrap, statistics, math, itertools, collections, re, pandas as pd, numpy as np path='/mnt/data/data_ekstraksi.json' with open(path,'r',encoding='utf-8') as f: data=json.load(f) type(data), len(data), data[0].keys(), data[-1].keys() (list, 645, dict_keys(['tanggal', 'waktu', 'daftar_prize']), dict_keys(['tanggal', 'waktu', 'daftar_prize']))

Python

python
data[-3:] [{'tanggal': '29 Mei 2026', 'waktu': '21:30', 'daftar_prize': [{'kode': '8454', 'angka': [0, 1, 2, 3, 6, 7, 9]}, {'kode': '5906', 'angka': [1, 2, 3, 4, 7, 8]}, {'kode': '3294', 'angka': [0, 1, 5, 6, 7, 8]}, {'kode': '0491', 'angka': [2, 3, 5, 6, 7, 8]}, {'kode': '0302', 'angka': [1, 4, 5, 6, 7, 8, 9]}, {'kode': '9610', 'angka': [2, 3, 4, 5, 7, 8]}, {'kode': '1017', 'angka': [2, 3, 4, 5, 6, 8, 9]}, {'kode': '3490', 'angka': [1, 2, 5, 6, 7, 8]}, {'kode': '1588', 'angka': [0, 2, 3, 4, 6, 7, 9]}, {'kode': '5763', 'angka': [0, 1, 2, 4, 8, 9]}, {'kode': '8529', 'angka': [0, 1, 3, 4, 6, 7]}, {'kode': '4732', 'angka': [0, 1, 5, 6, 8, 9]}, {'kode': '8571', 'angka': [0, 2, 3, 4, 6, 9]}]}, {'tanggal': '30 Mei 2026', 'waktu': '03:30', 'daftar_prize': [{'kode': '5282', 'angka': [0, 1, 3, 4, 6, 7, 9]}, {'kode': '8368', 'angka': [0, 1, 2, 4, 5, 7, 9]}, {'kode': '0338', 'angka': [1, 2, 4, 5, 6, 7, 9]}, {'kode': '9217', 'angka': [0, 3, 4, 5, 6, 8]}, {'kode': '1632', 'angka': [0, 4, 5, 7, 8, 9]}, {'kode': '6303', 'angka': [1, 2, 4, 5, 7, 8, 9]}, {'kode': '5016', 'angka': [2, 3, 4, 7, 8, 9]}, {'kode': '7698', 'angka': [0, 1, 2, 3, 4, 5]}, {'kode': '0893', 'angka': [1, 2, 4, 5, 6, 7]}, {'kode': '2251', 'angka': [0, 3, 4, 6, 7, 8, 9]}, {'kode': '4553', 'angka': [0, 1, 2, 6, 7, 8, 9]}, {'kode': '2034', 'angka': [1, 5, 6, 7, 8, 9]}, {'kode': '2940', 'angka': [1, 3, 5, 6, 7, 8]}]}, {'tanggal': '30 Mei 2026', 'waktu': '06:30', 'daftar_prize': [{'kode': '4049', 'angka': [1, 2, 3, 5, 6, 7, 8]}, {'kode': '6606', 'angka': [1, 2, 3, 4, 5, 7, 8, 9]}, {'kode': '0339', 'angka': [1, 2, 4, 5, 6, 7, 8]}, {'kode': '7823', 'angka': [0, 1, 4, 5, 6, 9]}, {'kode': '1254', 'angka': [0, 3, 6, 7, 8, 9]}, {'kode': '6841', 'angka': [0, 2, 3, 5, 7, 9]}, {'kode': '5917', 'angka': [0, 2, 3, 4, 6, 8]}, {'kode': '7261', 'angka': [0, 3, 4, 5, 8, 9]}, {'kode': '3955', 'angka': [0, 1, 2, 4, 6, 7, 8]}, {'kode': '7657', 'angka': [0, 1, 2, 3, 4, 8, 9]}, {'kode': '4269', 'angka': [0, 1, 3, 5, 7, 8]}, {'kode': '1604', 'angka': [2, 3, 5, 7, 8, 9]}, {'kode': '1555', 'angka': [0, 2, 3, 4, 6, 7, 8, 9]}]}]

Python

python
# Parse Indonesian dates and build flattened dataframe months = { 'Januari':1, 'Februari':2, 'Maret':3, 'April':4, 'Mei':5, 'Juni':6, 'Juli':7, 'Agustus':8, 'September':9, 'Oktober':10, 'November':11, 'Desember':12 } from datetime import datetime, timedelta, date, time rows=[] for i, draw in enumerate(data): tgl=draw['tanggal'] parts=tgl.split() d=int(parts[0]); m=months[parts[1]]; y=int(parts[2]) hh,mm=map(int,draw['waktu'].split(':')) dt=datetime(y,m,d,hh,mm) for j,p in enumerate(draw['daftar_prize'], start=1): kode=str(p['kode']).zfill(4) rows.append({ 'draw_idx':i, 'prize':j, 'datetime':dt, 'tanggal':tgl, 'waktu':draw['waktu'], 'kode':kode, 'angka':p.get('angka',[]) }) df=pd.DataFrame(rows) df.shape, df.head(), df.tail() ((8385, 7), draw_idx prize datetime ... waktu kode angka 0 0 1 2026-02-10 21:30:00 ... 21:30 6112 [0, 3, 4, 5, 7, 8, 9] 1 0 2 2026-02-10 21:30:00 ... 21:30 0236 [1, 4, 5, 7, 8, 9] 2 0 3 2026-02-10 21:30:00 ... 21:30 7341 [0, 2, 5, 6, 8, 9] 3 0 4 2026-02-10 21:30:00 ... 21:30 5278 [0, 1, 3, 4, 6, 9] 4 0 5 2026-02-10 21:30:00 ... 21:30 3328 [0, 1, 4, 5, 6, 7, 9] [5 rows x 7 columns], draw_idx prize ... kode angka 8380 644 9 ... 3955 [0, 1, 2, 4, 6, 7, 8] 8381 644 10 ... 7657 [0, 1, 2, 3, 4, 8, 9] 8382 644 11 ... 4269 [0, 1, 3, 5, 7, 8] 8383 644 12 ... 1604 [2, 3, 5, 7, 8, 9] 8384 644 13 ... 1555 [0, 2, 3, 4, 6, 7, 8, 9] [5 rows x 7 columns])

Python

python
from collections import Counter, defaultdict import numpy as np, math, itertools, pandas as pd SCHEDULE = ["03:30","06:30","11:30","13:30","17:30","21:30"] last_draw=data[-1] last_dt=max(df['datetime']) last_time=last_draw['waktu'] next_time = SCHEDULE[(SCHEDULE.index(last_time)+1)%len(SCHEDULE)] next_date = (last_dt.date() + (timedelta(days=1) if next_time==SCHEDULE[0] and last_time==SCHEDULE[-1] else timedelta(days=0))) next_dt = datetime.combine(next_date, datetime.strptime(next_time,"%H:%M").time()) last_dt, next_dt (Timestamp('2026-05-30 06:30:00'), datetime.datetime(2026, 5, 30, 11, 30))

Python

python
def pos_counts_probs(subdf, decay=None, smooth=1.0): # returns list of dict prob for positions 0-3 counts = [Counter() for _ in range(4)] if decay is None: for code in subdf['kode']: for i,ch in enumerate(code): counts[i][ch]+=1 else: n=len(subdf) for idx, code in enumerate(subdf['kode']): # recent gets more weight; subdf assumed chronological w = decay**(n-1-idx) for i,ch in enumerate(code): counts[i][ch]+=w probs=[] for c in counts: total=sum(c.values()) + smooth*10 probs.append({str(d):(c.get(str(d),0)+smooth)/total for d in range(10)}) return probs def global_digit_probs(subdf, decay=None, smooth=1.0): c=Counter() if decay is None: for code in subdf['kode']: for ch in code: c[ch]+=1 else: n=len(subdf) for idx, code in enumerate(subdf['kode']): w = decay**(n-1-idx) for ch in code: c[ch]+=w total=sum(c.values())+smooth*10 return {str(d):(c.get(str(d),0)+smooth)/total for d in range(10)} def pair_probs(subdf, decay=None, smooth=0.2): # adjacent pair all positions together c=Counter() if decay is None: for code in subdf['kode']: for i in range(3): c[code[i:i+2]]+=1 else: n=len(subdf) for idx, code in enumerate(subdf['kode']): w=decay**(n-1-idx) for i in range(3): c[code[i:i+2]]+=w total=sum(c.values()) + smooth*100 return {f"{a}{b}":(c.get(f"{a}{b}",0)+smooth)/total for a in range(10) for b in range(10)} def pattern_key(code): # e.g. AAAA, AABC, ABCA, AABB, ABCD etc based on first appearance mapping={} nxt='A' out=[] for ch in code: if ch not in mapping: mapping[ch]=chr(ord('A')+len(mapping)) out.append(mapping[ch]) return ''.join(out) def pattern_probs(subdf, smooth=0.5): c=Counter(pattern_key(code) for code in subdf['kode']) keys=set(pattern_key(''.join(p)) for p in itertools.product('0123456789', repeat=4)) total=sum(c.values())+smooth*len(keys) return {k:(c.get(k,0)+smooth)/total for k in keys} all_df = df.sort_values(['datetime','prize']).reset_index(drop=True) recent_records = all_df.tail(360) # about 27-28 draws same_time_df = all_df[all_df['waktu']==next_time] recent_same_time_df = same_time_df.tail(140) # last ~10 draws at same time? Actually 13*~10 overall_df=all_df p_recent=pos_counts_probs(recent_records, decay=0.992, smooth=1.5) p_same=pos_counts_probs(same_time_df, decay=0.995, smooth=1.5) p_overall=pos_counts_probs(overall_df, smooth=1.0) p_global_recent=global_digit_probs(recent_records, decay=0.992, smooth=1.0) p_pairs=pair_probs(recent_records, decay=0.995, smooth=0.5) p_pat=pattern_probs(overall_df, smooth=0.2) # recently appeared penalty last_k = set(all_df.tail(13*8)['kode']) # last 8 draw periods last_100 = set(all_df.tail(100)['kode']) all_codes_recent=Counter(all_df.tail(13*60)['kode']) def score_code(code): eps=1e-12 s=0 # positional for i,ch in enumerate(code): s += 0.45*math.log(p_recent[i][ch]+eps) s += 0.30*math.log(p_same[i][ch]+eps) s += 0.15*math.log(p_overall[i][ch]+eps) s += 0.05*math.log(p_global_recent[ch]+eps) # pair for i in range(3): s += 0.08*math.log(p_pairs[code[i:i+2]]+eps) s += 0.10*math.log(p_pat[pattern_key(code)]+eps) # mild penalty if exact code appeared too recently (to diversify) if code in last_k: s -= 0.6 elif code in last_100: s -= 0.25 return s codes = [''.join(p) for p in itertools.product('0123456789', repeat=4)] scores=np.array([score_code(c) for c in codes]) top_idx=scores.argsort()[::-1][:200] top=[(codes[i], scores[i]) for i in top_idx] top[:20] [('4539', np.float64(-9.205975831554762)), ('4579', np.float64(-9.28215367567872)), ('1539', np.float64(-9.284964369868089)), ('0539', np.float64(-9.28532236642733)), ('4537', np.float64(-9.287951592859763)), ('4639', np.float64(-9.314753292554647)), ('6539', np.float64(-9.338119406263703)), ('0639', np.float64(-9.349920744162711)), ('1579', np.float64(-9.361142213992046)), ('4517', np.float64(-9.361275994775518)), ('0579', np.float64(-9.361500210551288)), ('4536', np.float64(-9.361976221861195)), ('4519', np.float64(-9.363486546334185)), ('1537', np.float64(-9.366940131173088)), ('0537', np.float64(-9.36729812773233)), ('4576', np.float64(-9.372307938459999)), ('4531', np.float64(-9.374691132884884)), ('7539', np.float64(-9.376974493718734)), ('4532', np.float64(-9.3826684541451)), ('4589', np.float64(-9.39129745795769))]

Python

python
def hamming(a,b): return sum(x!=y for x,y in zip(a,b)) selected=[] for c,s in top: if all(hamming(c, sc)>=2 for sc,_ in selected): selected.append((c,s)) if len(selected)>=13: break selected [('4539', np.float64(-9.205975831554762)), ('0639', np.float64(-9.349920744162711)), ('1579', np.float64(-9.361142213992046)), ('4517', np.float64(-9.361275994775518)), ('1537', np.float64(-9.366940131173088)), ('4576', np.float64(-9.372307938459999)), ('4637', np.float64(-9.396729053859644)), ('0534', np.float64(-9.412823583278069)), ('4503', np.float64(-9.424430359591923)), ('0519', np.float64(-9.442833081206754)), ('5239', np.float64(-9.457165191799929)), ('4591', np.float64(-9.465176346711981)), ('0571', np.float64(-9.474098950564036))]

Python

python
# top positional digits combined probability maybe normalized with composite model from recent/same/overall def combined_pos_prob(): cps=[] for i in range(4): raw={} for d in '0123456789': # geometric mixture raw[d] = (p_recent[i][d]**0.45)*(p_same[i][d]**0.30)*(p_overall[i][d]**0.15)*(p_global_recent[d]**0.05) total=sum(raw.values()) cps.append({d: raw[d]/total for d in raw}) return cps cps=combined_pos_prob() top_pos = [] for i, probs in enumerate(cps): top_pos.append(sorted(probs.items(), key=lambda x:x[1], reverse=True)[:5]) top_pos [[('4', 0.11530221879118886), ('5', 0.10826228896872851), ('0', 0.10804371992297049), ('1', 0.10712706491976147), ('6', 0.10376651839024517)], [('5', 0.12693138916364988), ('6', 0.11377492682817938), ('2', 0.10261092089918457), ('7', 0.10162053986033169), ('1', 0.10001918638874585)], [('3', 0.11891302517749018), ('7', 0.10819756634325789), ('1', 0.10531058338661999), ('9', 0.10461202976008604), ('5', 0.10417633591212482)], [('9', 0.11426846944641028), ('7', 0.10925690168731315), ('4', 0.10231078795157017), ('3', 0.102011713826025), ('1', 0.10093939661232787)]]

Python

python
hot_global=sorted(p_global_recent.items(), key=lambda x:x[1], reverse=True) hot_global[:10] [('5', 0.11101250514585953), ('3', 0.10862552164007927), ('1', 0.10523631562278919), ('6', 0.10367183240913914), ('9', 0.1006173298754166), ('7', 0.09949177409906795), ('0', 0.09735398901579999), ('4', 0.09283555735271357), ('2', 0.09228764086192014), ('8', 0.08886753397721464)]

Pensiero

Planning script for prediction model and backtesting

I’m thinking of creating a Colab script with these steps: upload JSON, load and flatten the data, determine the next time, compute a prediction model with factors like Laplace smoothing and recency, then print results. I could also include a backtest to check if predictions match actual codes and show the match rate. The performance seems manageable with 645 draws and 10k predictions.

Thought for 1m 27s

Risposta

Saya sudah baca file data_ekstraksi.json; isinya 645 periode hasil, tiap periode ada 13 daftar_prize dengan kode 4 digit dan angka sebagai digit komplemen/angka yang tidak muncul di kode. (data_ekstraksi.json)

Catatan penting: hasil seperti ini tidak bisa diprediksi 100% akurat karena sifatnya acak. Jadi prediksi di bawah ini adalah prediksi statistik berbasis frekuensi, recency, pola posisi digit, dan pola pasangan digit, bukan jaminan menang.

Prediksi berikutnya dari data terakhir

Data terakhir di file: 30 Mei 2026 06:30
Periode selanjutnya yang diperkirakan: 30 Mei 2026 11:30

Digit kuat per posisi:

PosisiKandidat digit kuat
Ribuan4, 5, 0, 1, 6
Ratusan5, 6, 2, 7, 1
Puluhan3, 7, 1, 9, 5
Satuan9, 7, 4, 3, 1

BBFS / digit utama: 0 1 3 4 5 6 7 9

13 kandidat 4D prioritas:

text
4539 0639 1579 4517 1537 4576 4637 0534 4503 0519 5239 4591 0571

Script Google Colab

Copy semua kode ini ke 1 cell Google Colab, lalu jalankan. Upload file data_ekstraksi.json saat diminta.

python
# ============================================ # PREDIKSI 4D BERBASIS DATA JSON # Cocok dijalankan di Google Colab # ============================================ import json import math import itertools from collections import Counter from datetime import datetime, timedelta import numpy as np import pandas as pd # Untuk Google Colab try: from google.colab import files uploaded = files.upload() FILE_PATH = list(uploaded.keys())[0] except: FILE_PATH = "data_ekstraksi.json" # ========================= # 1. Load data # ========================= with open(FILE_PATH, "r", encoding="utf-8") as f: data = json.load(f) bulan_map = { "Januari": 1, "Februari": 2, "Maret": 3, "April": 4, "Mei": 5, "Juni": 6, "Juli": 7, "Agustus": 8, "September": 9, "Oktober": 10, "November": 11, "Desember": 12 } def parse_tanggal(tanggal, waktu): d, bulan, y = tanggal.split() hh, mm = waktu.split(":") return datetime(int(y), bulan_map[bulan], int(d), int(hh), int(mm)) rows = [] for draw_idx, item in enumerate(data): dt = parse_tanggal(item["tanggal"], item["waktu"]) for prize_idx, prize in enumerate(item["daftar_prize"], start=1): kode = str(prize["kode"]).zfill(4) rows.append({ "draw_idx": draw_idx, "prize": prize_idx, "datetime": dt, "tanggal": item["tanggal"], "waktu": item["waktu"], "kode": kode, "angka": prize.get("angka", []) }) df = pd.DataFrame(rows).sort_values(["datetime", "prize"]).reset_index(drop=True) print("Total periode:", len(data)) print("Total kode:", len(df)) print("Data terakhir:", df.iloc[-1]["tanggal"], df.iloc[-1]["waktu"]) # ========================= # 2. Tentukan jadwal berikutnya # ========================= SCHEDULE = ["03:30", "06:30", "11:30", "13:30", "17:30", "21:30"] last_dt = df["datetime"].max() last_time = df.iloc[-1]["waktu"] next_time = SCHEDULE[(SCHEDULE.index(last_time) + 1) % len(SCHEDULE)] if last_time == SCHEDULE[-1] and next_time == SCHEDULE[0]: next_date = last_dt.date() + timedelta(days=1) else: next_date = last_dt.date() next_dt = datetime.combine( next_date, datetime.strptime(next_time, "%H:%M").time() ) print("Prediksi untuk periode berikutnya:", next_dt.strftime("%d-%m-%Y %H:%M")) # ========================= # 3. Fungsi statistik # ========================= def pattern_key(code): """ Mengubah pola angka menjadi bentuk umum: 4539 -> ABCD 1555 -> ABBB 1128 -> AABC """ mapping = {} output = [] for ch in code: if ch not in mapping: mapping[ch] = chr(ord("A") + len(mapping)) output.append(mapping[ch]) return "".join(output) def pos_probs(subdf, decay=None, smooth=1.0): counts = [Counter() for _ in range(4)] if len(subdf) == 0: return [{str(d): 0.1 for d in range(10)} for _ in range(4)] if decay is None: for code in subdf["kode"]: for i, ch in enumerate(code): counts[i][ch] += 1 else: n = len(subdf) for idx, code in enumerate(subdf["kode"]): w = decay ** (n - 1 - idx) for i, ch in enumerate(code): counts[i][ch] += w probs = [] for c in counts: total = sum(c.values()) + smooth * 10 probs.append({ str(d): (c.get(str(d), 0) + smooth) / total for d in range(10) }) return probs def global_digit_probs(subdf, decay=None, smooth=1.0): c = Counter() if len(subdf) == 0: return {str(d): 0.1 for d in range(10)} if decay is None: for code in subdf["kode"]: for ch in code: c[ch] += 1 else: n = len(subdf) for idx, code in enumerate(subdf["kode"]): w = decay ** (n - 1 - idx) for ch in code: c[ch] += w total = sum(c.values()) + smooth * 10 return { str(d): (c.get(str(d), 0) + smooth) / total for d in range(10) } def pair_probs(subdf, decay=None, smooth=0.5): c = Counter() if len(subdf) == 0: return {f"{a}{b}": 0.01 for a in range(10) for b in range(10)} if decay is None: for code in subdf["kode"]: for i in range(3): c[code[i:i+2]] += 1 else: n = len(subdf) for idx, code in enumerate(subdf["kode"]): w = decay ** (n - 1 - idx) for i in range(3): c[code[i:i+2]] += w total = sum(c.values()) + smooth * 100 return { f"{a}{b}": (c.get(f"{a}{b}", 0) + smooth) / total for a in range(10) for b in range(10) } def pattern_probs(subdf, smooth=0.2): all_patterns = set( pattern_key("".join(p)) for p in itertools.product("0123456789", repeat=4) ) c = Counter(pattern_key(code) for code in subdf["kode"]) total = sum(c.values()) + smooth * len(all_patterns) return { p: (c.get(p, 0) + smooth) / total for p in all_patterns } def hamming(a, b): return sum(x != y for x, y in zip(a, b)) # ========================= # 4. Model prediksi # ========================= def predict_codes(flat_df, target_waktu, top_n=13, candidate_pool=200): flat_df = flat_df.sort_values(["datetime", "prize"]).reset_index(drop=True) recent_df = flat_df.tail(360) same_time_df = flat_df[flat_df["waktu"] == target_waktu] p_recent = pos_probs(recent_df, decay=0.992, smooth=1.5) p_same = pos_probs(same_time_df, decay=0.995, smooth=1.5) p_overall = pos_probs(flat_df, decay=None, smooth=1.0) p_global = global_digit_probs(recent_df, decay=0.992, smooth=1.0) p_pair = pair_probs(recent_df, decay=0.995, smooth=0.5) p_pattern = pattern_probs(flat_df, smooth=0.2) recent_exact = set(flat_df.tail(13 * 8)["kode"]) last_100 = set(flat_df.tail(100)["kode"]) def score_code(code): eps = 1e-12 score = 0.0 for i, ch in enumerate(code): score += 0.45 * math.log(p_recent[i][ch] + eps) score += 0.30 * math.log(p_same[i][ch] + eps) score += 0.15 * math.log(p_overall[i][ch] + eps) score += 0.05 * math.log(p_global[ch] + eps) for i in range(3): score += 0.08 * math.log(p_pair[code[i:i+2]] + eps) score += 0.10 * math.log(p_pattern[pattern_key(code)] + eps) # Penalti ringan jika kode sudah sangat baru muncul, # agar kandidat lebih variatif. if code in recent_exact: score -= 0.60 elif code in last_100: score -= 0.25 return score all_codes = ["".join(p) for p in itertools.product("0123456789", repeat=4)] scored = [(code, score_code(code)) for code in all_codes] scored = sorted(scored, key=lambda x: x[1], reverse=True) # Ambil kandidat beragam, tidak terlalu mirip semua selected = [] for code, score in scored[:candidate_pool]: if all(hamming(code, old_code) >= 2 for old_code, _ in selected): selected.append((code, score)) if len(selected) >= top_n: break # Digit kuat per posisi combined_pos = [] for i in range(4): raw = {} for d in "0123456789": raw[d] = ( p_recent[i][d] ** 0.45 * p_same[i][d] ** 0.30 * p_overall[i][d] ** 0.15 * p_global[d] ** 0.05 ) total = sum(raw.values()) combined_pos.append({ d: raw[d] / total for d in raw }) top_pos_digits = { f"posisi_{i+1}": sorted( combined_pos[i].items(), key=lambda x: x[1], reverse=True )[:5] for i in range(4) } hot_digits = sorted( p_global.items(), key=lambda x: x[1], reverse=True ) return selected, top_pos_digits, hot_digits prediksi, top_pos_digits, hot_digits = predict_codes( df, target_waktu=next_time, top_n=13 ) # ========================= # 5. Tampilkan hasil # ========================= print("\n=== DIGIT KUAT PER POSISI ===") nama_posisi = ["Ribuan", "Ratusan", "Puluhan", "Satuan"] for i, nama in enumerate(nama_posisi, start=1): digits = [d for d, p in top_pos_digits[f"posisi_{i}"]] print(f"{nama}: {', '.join(digits)}") bbfs = [d for d, p in hot_digits[:8]] print("\nBBFS / Digit utama:", " ".join(bbfs)) print("\n=== 13 KANDIDAT 4D PRIORITAS ===") for rank, (code, score) in enumerate(prediksi, start=1): print(f"{rank:02d}. {code} | score: {score:.4f}") # ========================= # 6. Optional: Backtest sederhana # ========================= RUN_BACKTEST = True BACKTEST_LAST_N_DRAWS = 60 TOP_N = 13 if RUN_BACKTEST: print("\n=== BACKTEST SEDERHANA ===") print("Catatan: hit dihitung jika salah satu kandidat top-N muncul di 13 prize periode target.") draw_ids = sorted(df["draw_idx"].unique()) test_ids = draw_ids[-BACKTEST_LAST_N_DRAWS:] hits = 0 total = 0 for target_draw_idx in test_ids: train_df = df[df["draw_idx"] < target_draw_idx].copy() target_df = df[df["draw_idx"] == target_draw_idx].copy() if len(train_df) < 100 or len(target_df) == 0: continue target_waktu = target_df.iloc[0]["waktu"] actual_codes = set(target_df["kode"].tolist()) preds, _, _ = predict_codes( train_df, target_waktu=target_waktu, top_n=TOP_N ) pred_codes = set(code for code, score in preds) if len(pred_codes & actual_codes) > 0: hits += 1 total += 1 if total > 0: print(f"Periode diuji: {total}") print(f"Hit: {hits}") print(f"Hit rate: {hits / total * 100:.2f}%") else: print("Data belum cukup untuk backtest.")

Gunakan hasilnya sebagai alat analisis, bukan patokan pasti. Untuk meningkatkan kualitas, jalankan ulang script setiap kali ada hasil terbaru agar bobot recency ikut berubah.

Condividi questa Q&A