| Weights | Method | ν | λ | ATT | 95% lower | 95% upper | Pre RMSE |
|---|---|---|---|---|---|---|---|
| cohort | Augsynth | 0.6051 | 0.0000 | -0.4733 | -0.7055 | -0.2514 | 0.0222 |
| cohort | Entropy | 0.5751 | 5.4772 | -0.4575 | -0.6906 | -0.2318 | 0.0255 |
| individual | Augsynth | 0.1516 | 0.0000 | -0.3574 | -0.6508 | -0.0838 | 0.1752 |
| individual | Entropy | 0.1412 | 0.5477 | -0.4749 | -0.7373 | -0.2536 | 0.2307 |
Balance-first tuning on Credit Markets
Native balnet regularization paths, reference-fit pooling, and matched pre-treatment RMSE
Matched comparison
The selected fits use the same 723 units, 194 never-treated donors, 10,226 pre-treatment observations, and outcome-SD scale as augsynth. ATTs average the same 17,811 treated unit-years. The main comparison shows the estimates, bootstrap intervals, and event studies.
Intervals use matched unit and calendar-time residualization. The bootstrap correction changes uncertainty only; tuning, weights, ATTs and pre-treatment RMSEs are unchanged.
The selected entropy fits have pre-treatment RMSE 0.0255 / 0.2307 SD (cohort / individual), compared with 0.0222 / 0.1752 for augsynth. The final λ values apply to the normalized balance loss. The separate reference paths and fully pooled diagnostics use an unnormalized loss.
Pre RMSE compares cohort-mean gaps for cohort fits and unit-level gaps for individual fits, on identical observations within each mode. Pooled pre RMSE averages gaps by event time first, then weights squared means by event-time support. It measures pooled balance, not individual fit quality.
Fully pooled endpoint
Both fully pooled reference paths reach the grid minimum, λ=0.000001. Their pooled balance is shown separately because these are not the selected partially pooled estimators.
| Weights | Lambda | Pooled_pre_RMSE |
|---|---|---|
| cohort | 1e-06 | 0.00000141 |
| individual | 1e-06 | 0.00113517 |
Selection procedure
- Fit a decreasing positive λ sequence for separate balance (ν=0) and fully pooled balance (ν=1). Retain the smallest penalty that passes independent optimality, simplex, and missingness-constraint checks.
- Compute ν and the loss normalizers from the selected separate fit. This is the augsynth heuristic; it does not use the minimum pooled loss as a denominator. The pooled endpoint measures attainable pooled balance.
- Hold that ν and those normalizers fixed along the final partially pooled λ path. Select the smallest certified penalty on the supplied grid. At a failed next penalty, try a geometric midpoint; keep failed attempts visible. The acceptance tolerance is never relaxed. Block paths stop after an unsuccessful boundary retry; smaller unattempted grid values remain identifiable from the requested grid.
This selects for balance subject to numerical convergence. It is not cross-validation, and the smallest tested convergent penalty is not a proof of a universal numerical lower limit. The Credit run uses 100, 30, 10, 3, 1, 0.3, 0.1, …, 0.000001, one boundary refinement, up to 10,000 coordinate-descent iterations, 500 native IRLS iterations, and 500 block sweeps per penalty. The original-scale stationarity and feasibility tolerance is 0.00001.
How ν is calculated
For group k, let n_k be its treated count and \delta_{ke} its pre-treatment mean gap at event time e. Define the vector E_k=n_k\delta_k, padded by zero where a group has no balancing moment. With K groups and L event lags:
\nu=\frac{\|K^{-1}\sum_k E_k\|_2}{K^{-1}\sum_k\|E_k\|_2},\qquad s_{\mathrm{sep}}=K^{-1}\sum_k\frac{\|E_k\|_2^2}{m_k},\qquad s_{\mathrm{pool}}=L^{-1}\|K^{-1}\sum_k E_k\|_2^2.
All three are evaluated at the separate reference fit; m_k counts its observed pre-period balancing moments. This avoids upstream’s residual != 0 denominator becoming undefined at exact zero residuals. A numerically zero reference loss causes an explicit normalization error rather than an arbitrary floor. The final balance loss is (1-\nu)L_{\mathrm{sep}}/s_{\mathrm{sep}}+\nu L_{\mathrm{pool}}/s_{\mathrm{pool}}, plus the relative-entropy penalty (with the usual one-half on squared loss). Entropy reference fits can yield a different ν from augsynth’s unpenalized quadratic-program reference. The objective’s loss definitions now match its cohort-total, zero-padded form for this complete, full-pre-window panel; the regularizer remains different. For truncated or missing pre-windows, normalizers use the actual fitted lag grid and observed moment counts.
Native path reuse
bal_multisynth_path() passes the entire decreasing λ vector to balnet() with one fixed, exactly equivalent preconditioning transformation. Balnet owns the within-path warm starts. The transformation includes an orthogonal rotation of all soft moments to improve conditioning; no directions are discarded, and acceptance is evaluated in the original coordinates. Separate groups each need only one native path. Large partially pooled fits carry primal weights between λ values; conditional subproblems use native decreasing-prefix paths. Balnet does not expose arbitrary initial dual coefficients, so conditional dual states are not claimed to persist between different subproblems.
For a complete fully pooled individual fit, an exact cohort reduction avoids repeated block sweeps. Convexity of relative entropy makes equal within-cohort weights optimal; the pooled loss is rescaled to preserve the original individual objective. The expanded individual solution is independently checked.
Log-domain weights preserve stationarity checks when tiny weights round to zero in floating-point arithmetic. No positive weight floor is inserted. Tighter solver precision can be retried, but acceptance thresholds stay fixed.
Complete path diagnostics
cohort — separate
Total path fitting time: 2.00 seconds.
| lambda | status | comparison_rmse | comparison_pooled_rmse | minimum_effective_donors | maximum_weight | kkt |
|---|---|---|---|---|---|---|
| 1.0000e+02 | certified | 0.08583 | 0.04352 | 169.73 | 0.0211 | 0.0e+00 |
| 3.0000e+01 | certified | 0.06602 | 0.02994 | 130.50 | 0.0356 | 7.0e-07 |
| 1.0000e+01 | certified | 0.05172 | 0.02181 | 98.73 | 0.0323 | 3.4e-06 |
| 3.0000e+00 | certified | 0.03812 | 0.01538 | 50.67 | 0.0760 | 1.7e-06 |
| 1.0000e+00 | certified | 0.02813 | 0.01091 | 23.70 | 0.1391 | 5.5e-06 |
| 3.0000e-01 | certified | 0.02146 | 0.00841 | 13.21 | 0.1973 | 5.3e-06 |
| 1.0000e-01 | certified | 0.01860 | 0.00776 | 10.07 | 0.2286 | 5.3e-06 |
| 3.0000e-02 | certified | 0.01741 | 0.00764 | 9.03 | 0.2567 | 7.8e-06 |
| 1.0000e-02 | certified | 0.01715 | 0.00765 | 8.74 | 0.2727 | 5.5e-06 |
| 5.4772e-03 | failed | NA | NA | NA | NA | NA |
| 3.0000e-03 | failed | NA | NA | NA | NA | NA |
| 1.0000e-03 | failed | NA | NA | NA | NA | NA |
| 3.0000e-04 | failed | NA | NA | NA | NA | NA |
| 1.0000e-04 | failed | NA | NA | NA | NA | NA |
| 3.0000e-05 | failed | NA | NA | NA | NA | NA |
| 1.0000e-05 | failed | NA | NA | NA | NA | NA |
| 3.0000e-06 | failed | NA | NA | NA | NA | NA |
| 1.0000e-06 | failed | NA | NA | NA | NA | NA |
cohort — pooled
Total path fitting time: 6.92 seconds.
| lambda | status | comparison_rmse | comparison_pooled_rmse | minimum_effective_donors | maximum_weight | kkt |
|---|---|---|---|---|---|---|
| 1e+02 | certified | 0.11610 | 0.06360 | 193.74 | 0.0063 | 1.5e-06 |
| 3e+01 | certified | 0.11144 | 0.05847 | 191.90 | 0.0090 | 1.3e-06 |
| 1e+01 | certified | 0.10301 | 0.04866 | 182.72 | 0.0166 | 1.5e-06 |
| 3e+00 | certified | 0.09201 | 0.03353 | 142.07 | 0.0396 | 1.9e-06 |
| 1e+00 | certified | 0.08678 | 0.02228 | 93.66 | 0.0677 | 3.4e-06 |
| 3e-01 | certified | 0.08531 | 0.01460 | 77.27 | 0.0717 | 4.4e-06 |
| 1e-01 | certified | 0.08470 | 0.00976 | 56.12 | 0.0887 | 4.5e-06 |
| 3e-02 | certified | 0.08454 | 0.00601 | 36.58 | 0.1359 | 4.1e-06 |
| 1e-02 | certified | 0.08504 | 0.00372 | 20.72 | 0.1724 | 3.3e-06 |
| 3e-03 | certified | 0.08590 | 0.00202 | 7.40 | 0.3274 | 2.4e-06 |
| 1e-03 | certified | 0.08695 | 0.00097 | 4.16 | 0.4613 | 2.2e-06 |
| 3e-04 | certified | 0.08780 | 0.00036 | 3.20 | 0.5353 | 2.1e-06 |
| 1e-04 | certified | 0.08815 | 0.00013 | 2.95 | 0.5597 | 2.1e-06 |
| 3e-05 | certified | 0.08829 | 0.00004 | 2.87 | 0.5684 | 2.1e-06 |
| 1e-05 | certified | 0.08833 | 0.00001 | 2.84 | 0.5708 | 2.1e-06 |
| 3e-06 | certified | 0.08835 | 0.00000 | 2.83 | 0.5717 | 2.1e-06 |
| 1e-06 | certified | 0.08835 | 0.00000 | 2.83 | 0.5720 | 2.1e-06 |
cohort — partial
Total path fitting time: 174.84 seconds.
| lambda | status | comparison_rmse | comparison_pooled_rmse | minimum_effective_donors | maximum_weight | kkt |
|---|---|---|---|---|---|---|
| 100.000000 | certified | 0.04726 | 0.01319 | 66.18 | 0.0705 | 7.9e-06 |
| 30.000000 | certified | 0.03567 | 0.00834 | 28.99 | 0.1378 | 6.3e-06 |
| 10.000000 | certified | 0.02804 | 0.00579 | 15.82 | 0.1916 | 4.1e-06 |
| 5.477226 | certified | 0.02546 | 0.00511 | 12.53 | 0.2138 | 3.1e-06 |
| 3.000000 | failed | NA | NA | NA | NA | NA |
| 1.000000 | failed | NA | NA | NA | NA | NA |
| 0.300000 | failed | NA | NA | NA | NA | NA |
| 0.100000 | failed | NA | NA | NA | NA | NA |
| 0.030000 | failed | NA | NA | NA | NA | NA |
| 0.010000 | failed | NA | NA | NA | NA | NA |
| 0.003000 | failed | NA | NA | NA | NA | NA |
| 0.001000 | failed | NA | NA | NA | NA | NA |
| 0.000300 | failed | NA | NA | NA | NA | NA |
| 0.000100 | failed | NA | NA | NA | NA | NA |
| 0.000030 | failed | NA | NA | NA | NA | NA |
| 0.000010 | failed | NA | NA | NA | NA | NA |
| 0.000003 | failed | NA | NA | NA | NA | NA |
| 0.000001 | failed | NA | NA | NA | NA | NA |
individual — separate
Total path fitting time: 49.14 seconds.
| lambda | status | comparison_rmse | comparison_pooled_rmse | minimum_effective_donors | maximum_weight | kkt |
|---|---|---|---|---|---|---|
| 100.0000000 | failed | NA | NA | NA | NA | NA |
| 30.0000000 | certified | 0.41933 | 0.06627 | 193.97 | 0.0055 | 0 |
| 10.0000000 | certified | 0.41758 | 0.06585 | 193.71 | 0.0061 | 0 |
| 3.0000000 | certified | 0.41166 | 0.06444 | 190.74 | 0.0089 | 0 |
| 1.0000000 | certified | 0.39601 | 0.06090 | 160.09 | 0.0213 | 0 |
| 0.3000000 | certified | 0.35304 | 0.05261 | 33.19 | 0.1534 | 0 |
| 0.1000000 | certified | 0.29156 | 0.04356 | 2.98 | 0.5442 | 0 |
| 0.0300000 | certified | 0.23463 | 0.03453 | 1.66 | 0.7758 | 0 |
| 0.0173205 | certified | 0.21557 | 0.03067 | 1.37 | 0.8531 | 0 |
| 0.0100000 | failed | NA | NA | NA | NA | NA |
| 0.0030000 | failed | NA | NA | NA | NA | NA |
| 0.0010000 | failed | NA | NA | NA | NA | NA |
| 0.0003000 | failed | NA | NA | NA | NA | NA |
| 0.0001000 | failed | NA | NA | NA | NA | NA |
| 0.0000300 | failed | NA | NA | NA | NA | NA |
| 0.0000100 | failed | NA | NA | NA | NA | NA |
| 0.0000030 | failed | NA | NA | NA | NA | NA |
| 0.0000010 | failed | NA | NA | NA | NA | NA |
individual — pooled
Total path fitting time: 26.07 seconds.
| lambda | status | comparison_rmse | comparison_pooled_rmse | minimum_effective_donors | maximum_weight | kkt |
|---|---|---|---|---|---|---|
| 1e+02 | failed | NA | NA | NA | NA | NA |
| 3e+01 | failed | NA | NA | NA | NA | NA |
| 1e+01 | certified | 0.42020 | 0.06646 | 194.00 | 0.0052 | 0 |
| 3e+00 | certified | 0.42019 | 0.06640 | 194.00 | 0.0052 | 0 |
| 1e+00 | certified | 0.42014 | 0.06622 | 194.00 | 0.0053 | 0 |
| 3e-01 | certified | 0.41999 | 0.06564 | 193.98 | 0.0055 | 0 |
| 1e-01 | certified | 0.41960 | 0.06411 | 193.82 | 0.0061 | 0 |
| 3e-02 | certified | 0.41851 | 0.05977 | 192.53 | 0.0082 | 0 |
| 1e-02 | certified | 0.41653 | 0.05105 | 185.90 | 0.0143 | 0 |
| 3e-03 | certified | 0.41384 | 0.03627 | 152.43 | 0.0341 | 0 |
| 1e-03 | certified | 0.41244 | 0.02413 | 101.01 | 0.0631 | 0 |
| 3e-04 | certified | 0.41204 | 0.01575 | 77.94 | 0.0740 | 0 |
| 1e-04 | certified | 0.41190 | 0.01061 | 62.45 | 0.0800 | 0 |
| 3e-05 | certified | 0.41184 | 0.00658 | 38.38 | 0.1266 | 0 |
| 1e-05 | certified | 0.41193 | 0.00411 | 25.42 | 0.1666 | 0 |
| 3e-06 | certified | 0.41209 | 0.00228 | 8.69 | 0.2957 | 0 |
| 1e-06 | certified | 0.41231 | 0.00114 | 4.52 | 0.4397 | 0 |
individual — partial
Total path fitting time: 487.09 seconds.
| lambda | status | comparison_rmse | comparison_pooled_rmse | minimum_effective_donors | maximum_weight | kkt |
|---|---|---|---|---|---|---|
| 100.0000000 | certified | 0.41469 | 0.06370 | 192.53 | 0.0078 | 4.9e-06 |
| 30.0000000 | certified | 0.40289 | 0.05846 | 179.05 | 0.0171 | 1.5e-06 |
| 10.0000000 | certified | 0.37447 | 0.04838 | 88.63 | 0.0641 | 4.9e-06 |
| 3.0000000 | certified | 0.31382 | 0.03420 | 5.72 | 0.3935 | 6.3e-06 |
| 1.0000000 | certified | 0.25543 | 0.02403 | 1.86 | 0.7013 | 9.2e-06 |
| 0.3000000 | failed | NA | NA | NA | NA | NA |
| 0.5477226 | certified | 0.23071 | 0.01975 | 1.52 | 0.8106 | 8.8e-06 |
| 0.3000000 | failed | NA | NA | NA | NA | NA |
Native balnet exposes total path time, not reliable per-λ timing. Block paths also record elapsed time per attempted penalty. These are uncached fitting runs, excluding design construction, post-fit predictions, rendering, and the old augsynth fits. They are not an identical-objective speed benchmark.
Pre-treatment figure: PNG · PDF · Summary CSV · Full path CSV, including failures · Results and numerical provenance · Runnable experiment · ATTs and event studies with intervals