SniperGold_ML/ml/p3/baseline/train_small_mlp.py

77 lines
No EOL
2.9 KiB
Python

# -*- coding: utf-8 -*-
"""P3-S.18 — SMALL MLP BASELINE.
Small MLP: input -> 16 hidden (tanh) -> 1 output (sigmoid), L2 alpha=1e-3,
max_iter=2000, fixed seed. NOT a reproduction of the legacy 19->12->2 MLP
(target differs: setup-outcome TP-before-SL, not 24-bar drift). Standardizer
fit on train only. Binary target: WIN vs LOSS (leads only).
"""
import csv
import json
import os
import sys
import numpy as np
from sklearn.neural_network import MLPClassifier
from sklearn.preprocessing import StandardScaler
HERE = os.path.dirname(os.path.abspath(__file__))
OUT = os.path.join(HERE, "output")
sys.path.insert(0, HERE)
sys.path.insert(0, os.path.normpath(os.path.join(HERE, "..", "setup_dataset")))
import prepare_dataset as PD # noqa: E402
SEED = 42
def main():
os.makedirs(OUT, exist_ok=True)
ctx = PD.load_verified_population()
rows = PD.build_rows(ctx)
bin_rows = [r for r in rows if r["lead"] and r["outcome"] in PD.BINARY_CLASSES]
bin_rows.sort(key=lambda r: (r["creation_bar"], r["setup_id"]))
tr, va, te, _ = PD.temporal_split(rows)
split_map = {}
for part, tag in ((tr, "train"), (va, "val"), (te, "test")):
for r in part:
split_map[r["setup_id"]] = tag
X = np.asarray([[r["feature_" + k] for k in PD.FEATURE_COLS]
for r in bin_rows], dtype=float)
y = np.asarray([1.0 if r["outcome"] == "WIN" else 0.0
for r in bin_rows], dtype=float)
splits = np.asarray([split_map[r["setup_id"]] for r in bin_rows])
scaler = StandardScaler().fit(X[splits == "train"])
Xs = scaler.transform(X)
clf = MLPClassifier(hidden_layer_sizes=(16,), activation="tanh",
alpha=1e-3, max_iter=2000, random_state=SEED)
clf.fit(Xs[splits == "train"], y[splits == "train"])
p = clf.predict_proba(Xs)[:, 1]
rows_out = []
for i, r in enumerate(bin_rows):
rows_out.append({"setup_id": r["setup_id"], "split": splits[i],
"outcome": r["outcome"], "y": int(y[i]),
"pred_mlp16": float(p[i])})
with open(os.path.join(OUT, "p3_s18_predictions_mlp.csv"), "w",
newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=list(rows_out[0].keys()))
w.writeheader()
for r in rows_out:
w.writerow(r)
with open(os.path.join(OUT, "p3_s18_mlp_model.json"), "w",
encoding="utf-8") as f:
json.dump({
"model": "MLP(hidden=(16,),tanh,alpha=1e-3,max_iter=2000)",
"feature_sha16": PD.make_manifest(rows, tr, va, te,
True)["feature_sha16"],
"seed": SEED, "n_iter": int(clf.n_iter_),
"loss_curve_len": int(len(clf.loss_curve_)),
}, f, indent=2)
print("[saved] p3_s18_predictions_mlp.csv / mlp_model.json")
return 0
if __name__ == "__main__":
sys.exit(main())