| import json |
| import sys |
| from pathlib import Path |
|
|
| import numpy as np |
| from scipy.optimize import least_squares |
| |
| |
|
|
|
|
| def sigma(x, k, mu): |
| return 100.0 / (1.0 + np.exp(-k * (x - mu))) |
|
|
|
|
|
|
| def load_dataset(fp): |
| with open(fp, "r", encoding="utf-8") as f: |
| data = json.load(f) |
| return data |
|
|
|
|
| def build_arrays(data): |
| s_cos, J, G = [], [], [] |
| acc_targets, flu_targets = [], [] |
|
|
| for ex in data: |
| src, tgt = ex["german"], ex["english"] |
|
|
| |
| |
| |
|
|
| |
| |
| |
|
|
| |
| |
|
|
| s_cos.append(ex["bertscore"]) |
| J.append(ex["fluency_score"]) |
| G.append(ex["grammar_score"]) |
|
|
| acc_targets.append(ex["accuracy"]) |
| flu_targets.append(ex["fluency"]) |
|
|
| |
| return (np.array(s_cos), |
| np.array(J, dtype=float), |
| np.array(G, dtype=float), |
| np.array(acc_targets, dtype=float), |
| np.array(flu_targets, dtype=float)) |
|
|
|
|
| def fit_accuracy(s_cos, acc_target): |
| def resid(params, x, y): |
| lam, k1, mu1, k2, mu2 = params |
| s1 = sigma(x, k1, mu1) |
| s2 = sigma(x, k2, mu2) |
| pred = lam * s1 + (1 - lam) * s2 |
| return pred - y |
|
|
|
|
| init = [0.5, 5.0, 0.6, 11.0, 0.6] |
| bounds = ( |
| [0.2, 1.0, 0.4, 5.0, 0.4], |
| [0.8, 11.0, 0.8, 20.0, 0.8] |
| ) |
|
|
| res = least_squares(resid, init, args=(s_cos, acc_target), bounds=bounds) |
| lam, k1, mu1, k2, mu2 = res.x |
| return dict(lam=lam, k1=k1, mu1=mu1, k2=k2, mu2=mu2) |
|
|
|
|
| |
| |
| def fit_fluency(J, G, flu_target): |
| def resid(params, J_, G_, y): |
| lam, kP, muP, kG, muG = params |
| P = sigma(J_, kP, muP) |
| G = sigma(G_, kG, muG) |
| pred = lam * P + (1 - lam) * G |
| return pred - y |
|
|
| init = [0.5, 0.1, 5.0, 0.1, 5.0] |
| bounds = ([0.2, 0, 0, 0, 0], |
| [1, np.inf, np.inf, np.inf, np.inf]) |
| res = least_squares(resid, init, args=(J, G, flu_target), bounds=bounds) |
| lam, kP, muP, kG, muG = res.x |
| return dict(lambda_F=lam, k_P=kP, mu_P=muP, k_G=kG, mu_G=muG) |
|
|
|
|
| |
| def main(in_path, out_path): |
| print("Loading dataset from", in_path) |
| data = load_dataset(in_path) |
|
|
| print("Building arrays...") |
| s_cos, J, G, acc_t, flu_t = build_arrays(data) |
|
|
| print("Fitting accuracy parameters...") |
| acc_params = fit_accuracy(s_cos, acc_t) |
| print("Fitting fluency parameters...") |
| flu_params = fit_fluency(J, G, flu_t) |
|
|
| |
| acc_params = {k: round(v, 2) for k, v in acc_params.items()} |
| flu_params = {k: round(v, 2) for k, v in flu_params.items()} |
|
|
| params = { |
| "accuracy_params": acc_params, |
| "fluency_params": flu_params |
| } |
|
|
| Path(out_path).write_text(json.dumps(params, indent=2)) |
| print("Saved parameters to", out_path) |
|
|
|
|
| if __name__ == "__main__": |
| if len(sys.argv) != 3: |
| print("Usage: python fit_qe_params.py translations.json fitted_params.json") |
| sys.exit(1) |
|
|
| main(sys.argv[1], sys.argv[2]) |
|
|