docs(decision): correct the record against the re-measured evidence
The audit's own numbers were right; several claims built on them were not, and the advisors found each one: - 'wins both axes at both resolutions' - false at live, where the lane trades 59% coverage for 93% precision against Van's 66% at 39%. Stated as the trade it is. - G1's bootstrap now exists: the local lane's correct set is a strict superset of Van's on the stream, so the 95% lower bound is a hard +0.0 pp - a floor of that pairing, not a margin. tracks_final.json is level with Van and does not clear it. - The far-unknown rate is 0.066% on 4580 crops at the shipped configuration, not 0.30% on 2650 at the old one. - The E-3 ablation compared text-presence *and* a different argmax; both arms now go through the same DecisionPolicy ordering. Text adds 9-10 pp of coverage at full resolution while raising precision. - The sweep table swept one axis while pinning the other; replaced with the joint sweep. - The two Re-measured tables are dated snapshots, labeled as such.
This commit is contained in:
parent
730a5e782b
commit
7736465bee
2 changed files with 132 additions and 43 deletions
|
|
@ -178,6 +178,63 @@ class TextLaneSignatureTests(unittest.TestCase):
|
|||
"sku_l08",
|
||||
)
|
||||
|
||||
def test_one_shared_pair_is_refused_by_the_floor_alone(self):
|
||||
"""Everything but the evidence floor says answer, and it says no.
|
||||
|
||||
"アンース" holds one pair the catalog knows - "ース" - so the row scores
|
||||
a perfect 1.0 with the whole margin over an empty runner-up, and the
|
||||
read carries three pairs, so `carries_identity` passes as well. Only
|
||||
`TEXT_MIN_SHARED` stands between a coincidental pair and a named
|
||||
product, which is why the test asserts the score is 1.0: it pins the
|
||||
floor as the only thing doing the refusing.
|
||||
"""
|
||||
from identity_lanes import DecisionPolicy, TextLane
|
||||
|
||||
lane = TextLane.from_catalog(
|
||||
[{"sku_id": "sku_x", "product_name": "オイスターソース"}],
|
||||
"no-such-dir",
|
||||
ocr_engine=None,
|
||||
)
|
||||
read = "アンース"
|
||||
self.assertEqual(lane.scores_from_text(read)["sku_x"], 1.0)
|
||||
self.assertIsNone(
|
||||
DecisionPolicy(signatures=lane.signatures).decide(
|
||||
[], [("sku_x", 1.0)], text_read=read
|
||||
)["best_sku"],
|
||||
"one shared pair is not enough to name a row",
|
||||
)
|
||||
|
||||
def test_a_thin_read_still_vetoes_even_though_it_cannot_name(self):
|
||||
"""The floor is a floor on naming, not on contradicting.
|
||||
|
||||
"北海道塩" shares three bigrams with sku_b - one short of the floor -
|
||||
so it cannot name that row. It is still the row the text prefers over
|
||||
the local answer, and the local lane clears its own line at 5.0 against
|
||||
a line of 4.0, so if the floor also sat under the veto this would come
|
||||
back as sku_a: a three-bigram read would have rescued a match the
|
||||
geometry earned.
|
||||
"""
|
||||
from identity_lanes import DecisionPolicy, TextLane
|
||||
|
||||
lane = TextLane.from_catalog(
|
||||
[
|
||||
{"sku_id": "sku_a", "product_name": "キューピー ハーフマヨネーズ 400g"},
|
||||
{"sku_id": "sku_b", "product_name": "北海道塩"},
|
||||
],
|
||||
"no-such-dir",
|
||||
ocr_engine=None,
|
||||
)
|
||||
read = "北海道塩"
|
||||
ranked = sorted(lane.scores_from_text(read).items(),
|
||||
key=lambda kv: kv[1], reverse=True)
|
||||
self.assertEqual((ranked[0][0], ranked[0][1]), ("sku_b", 1.0))
|
||||
self.assertIsNone(
|
||||
DecisionPolicy(signatures=lane.signatures).decide(
|
||||
[("sku_a", 5.0)], ranked, text_read=read
|
||||
)["best_sku"],
|
||||
"a read too thin to name a row still refuses the local answer",
|
||||
)
|
||||
|
||||
|
||||
class FakeDetector:
|
||||
"""Records concurrency and returns fixed boxes."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue