71 lines
2.0 KiB
Python
71 lines
2.0 KiB
Python
import argparse
|
|
import json
|
|
import os
|
|
import joblib
|
|
import numpy as np
|
|
from pathlib import Path
|
|
|
|
# =========================================================
|
|
# Configuration (Must match training)
|
|
# =========================================================
|
|
MAX_NOTES = 2000
|
|
FACTOR_COUNT = 4
|
|
INPUT_DIM = MAX_NOTES * FACTOR_COUNT
|
|
|
|
MODEL_FILENAME = "model.pkl"
|
|
SCALER_FILENAME = "scaler.pkl"
|
|
|
|
def safe_float(value):
|
|
try: return float(value)
|
|
except: return 0.0
|
|
|
|
def predict():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--workingDir", required=True)
|
|
parser.add_argument("--songno", required=True)
|
|
parser.add_argument("--factor", required=False) # Input factor JSON file
|
|
args = parser.parse_args()
|
|
|
|
model_path = os.path.join(args.workingDir, MODEL_FILENAME)
|
|
scaler_path = os.path.join(args.workingDir, SCALER_FILENAME)
|
|
|
|
if not os.path.exists(model_path):
|
|
print(f"Model not found: {model_path}")
|
|
return
|
|
|
|
model = joblib.load(model_path)
|
|
scaler = joblib.load(scaler_path)
|
|
|
|
with open(args.factor or (Path(args.workingDir) / 'factors.json'), "r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
|
|
# Filter by songno
|
|
targets = [item for item in data if str(item["songno"]) == str(args.songno)]
|
|
if not targets:
|
|
print(f"No data found for songno: {args.songno}")
|
|
return
|
|
|
|
results = []
|
|
for item in targets:
|
|
raw_factors = item["factors"]
|
|
vector = np.zeros(INPUT_DIM, dtype=np.float32)
|
|
|
|
for i in range(min(len(raw_factors), MAX_NOTES)):
|
|
for j in range(FACTOR_COUNT):
|
|
vector[i * FACTOR_COUNT + j] = safe_float(raw_factors[i][j])
|
|
|
|
# Scale and Predict
|
|
X = scaler.transform([vector])
|
|
pred = model.predict(X)[0]
|
|
|
|
results.append({
|
|
"songno": item["songno"],
|
|
"diff": item["difficulty"],
|
|
"predicted": float(pred)
|
|
})
|
|
|
|
print(json.dumps(results, indent=2))
|
|
|
|
if __name__ == "__main__":
|
|
predict()
|