This commit is contained in:
@@ -447,6 +447,16 @@ VARIANT_OPTION_COLOR_WORDS = {
|
||||
"月光銀影",
|
||||
}
|
||||
|
||||
VARIANT_DESCRIPTOR_NOISE_KEYWORDS = {
|
||||
"平輸航空版",
|
||||
"多色任選",
|
||||
"色號任選",
|
||||
"任選色號",
|
||||
"極細筆頭",
|
||||
"筆頭",
|
||||
"官方直營",
|
||||
}
|
||||
|
||||
SEARCH_AMBIGUOUS_PRODUCT_TERMS = {
|
||||
"保護膜",
|
||||
"保護貼",
|
||||
@@ -478,6 +488,8 @@ BRAND_ALIAS_OVERRIDES = {
|
||||
"febreze": ("febreze", "風倍清"),
|
||||
"jo malone": ("jo malone",),
|
||||
"prada": ("prada", "普拉達"),
|
||||
"za": ("za",),
|
||||
"xiaomi": ("小米有品", "小米", "xiaomi"),
|
||||
}
|
||||
|
||||
PRODUCT_TYPES = {
|
||||
@@ -1559,9 +1571,22 @@ def score_marketplace_match(
|
||||
try:
|
||||
if momo_price and competitor_price:
|
||||
ratio = float(competitor_price) / max(float(momo_price), 1.0)
|
||||
allow_price_penalty_suppression = (
|
||||
shared_anchor
|
||||
and len(shared_anchor.replace(" ", "")) >= 7
|
||||
and brand_score >= 0.95
|
||||
and not hard_veto
|
||||
and type_score >= 0.55
|
||||
and spec_score >= 0.99
|
||||
and token_score >= 0.68
|
||||
and sequence_score >= 0.72
|
||||
)
|
||||
if (ratio < 0.3 or ratio > 3.2) and token_score < 0.78:
|
||||
price_penalty = 0.12
|
||||
reasons.append("price_ratio_extreme")
|
||||
if allow_price_penalty_suppression:
|
||||
reasons.append("price_penalty_suppressed_exact_identity")
|
||||
else:
|
||||
price_penalty = 0.12
|
||||
reasons.append("price_ratio_extreme")
|
||||
elif (ratio < 0.48 or ratio > 2.2) and token_score < 0.68:
|
||||
price_penalty = 0.06
|
||||
reasons.append("price_ratio_wide")
|
||||
@@ -1662,6 +1687,35 @@ def score_marketplace_match(
|
||||
):
|
||||
score += 0.02
|
||||
reasons.append("shared_identity_anchor_core_line")
|
||||
if (
|
||||
shared_anchor
|
||||
and len(shared_anchor.replace(" ", "")) >= 6
|
||||
and brand_score >= 0.95
|
||||
and not hard_veto
|
||||
and price_penalty == 0
|
||||
and type_score >= 0.55
|
||||
and spec_score >= 0.45
|
||||
and token_score >= 0.86
|
||||
and sequence_score >= 0.75
|
||||
and not variant_descriptor_conflict
|
||||
):
|
||||
score += 0.07
|
||||
reasons.append("shared_identity_anchor_exact_line")
|
||||
if (
|
||||
shared_anchor
|
||||
and len(shared_anchor.replace(" ", "")) >= 5
|
||||
and brand_score >= 0.95
|
||||
and not hard_veto
|
||||
and price_penalty == 0
|
||||
and type_score >= 0.55
|
||||
and spec_score >= 0.45
|
||||
and token_score >= 0.74
|
||||
and sequence_score >= 0.60
|
||||
and _shared_variant_descriptors(left, right)
|
||||
and not variant_descriptor_conflict
|
||||
):
|
||||
score += 0.05
|
||||
reasons.append("shared_variant_descriptor_alignment")
|
||||
if (
|
||||
shared_anchor
|
||||
and len(shared_anchor.replace(" ", "")) >= 6
|
||||
@@ -1870,12 +1924,30 @@ def _variant_descriptors(identity: ProductIdentity) -> set[str]:
|
||||
continue
|
||||
if compact in SEARCH_NOISE_TOKENS or compact in SEARCH_BROAD_ANCHORS:
|
||||
continue
|
||||
if any(keyword in compact for keyword in VARIANT_DESCRIPTOR_NOISE_KEYWORDS):
|
||||
continue
|
||||
if re.fullmatch(r"[a-z0-9-]+", compact):
|
||||
continue
|
||||
descriptors.add(compact.removesuffix("款"))
|
||||
return {token for token in descriptors if token}
|
||||
|
||||
|
||||
def _shared_variant_descriptors(left: ProductIdentity, right: ProductIdentity) -> set[str]:
|
||||
left_descriptors = _variant_descriptors(left)
|
||||
right_descriptors = _variant_descriptors(right)
|
||||
shared: set[str] = set()
|
||||
for left_descriptor in left_descriptors:
|
||||
for right_descriptor in right_descriptors:
|
||||
if left_descriptor == right_descriptor:
|
||||
shared.add(left_descriptor)
|
||||
continue
|
||||
if len(left_descriptor) >= 2 and left_descriptor in right_descriptor:
|
||||
shared.add(left_descriptor)
|
||||
elif len(right_descriptor) >= 2 and right_descriptor in left_descriptor:
|
||||
shared.add(right_descriptor)
|
||||
return shared
|
||||
|
||||
|
||||
def _is_variant_sensitive_identity(
|
||||
left: ProductIdentity,
|
||||
right: ProductIdentity,
|
||||
|
||||
Reference in New Issue
Block a user