mirror of
https://github.com/primedigitaltech/market-assistant.git
synced 2026-07-25 17:51:37 +08:00
fix(strategy): 矩阵收窄时 §5.1 集中度注明非列表行口径
strategy_scope_applied 下 concentration 来自分组内合并 SKU;修正店铺/品牌叙事措辞并加口径说明,避免与全关键词列表行混淆。 Made-with: Cursor
This commit is contained in:
parent
44fa291eb3
commit
3f6c750ac4
@ -48,8 +48,19 @@ def _num(x: Any) -> str:
|
|||||||
return str(x)
|
return str(x)
|
||||||
|
|
||||||
|
|
||||||
def _cr_narrative(label: str, cr1: Any, cr3: Any, top: Any) -> str | None:
|
def _cr_narrative(
|
||||||
"""从集中度生成一句策略向描述,无数据则返回 None(正文避免英文缩写)。"""
|
label: str,
|
||||||
|
cr1: Any,
|
||||||
|
cr3: Any,
|
||||||
|
top: Any,
|
||||||
|
*,
|
||||||
|
first_share_wording: tuple[str, str] | None = None,
|
||||||
|
) -> str | None:
|
||||||
|
"""从集中度生成一句策略向描述,无数据则返回 None(正文避免英文缩写)。
|
||||||
|
|
||||||
|
``first_share_wording`` 为 ``(第一大句前缀, 前三大句前缀)`` 时覆盖默认措辞(用于矩阵收窄口径,
|
||||||
|
避免误写「列表行」)。
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
c1 = float(cr1) if cr1 is not None else None
|
c1 = float(cr1) if cr1 is not None else None
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
@ -57,7 +68,9 @@ def _cr_narrative(label: str, cr1: Any, cr3: Any, top: Any) -> str | None:
|
|||||||
if c1 is None and not (top or "").strip():
|
if c1 is None and not (top or "").strip():
|
||||||
return None
|
return None
|
||||||
top_s = _esc(top) or "—"
|
top_s = _esc(top) or "—"
|
||||||
if "店铺" in label:
|
if first_share_wording is not None:
|
||||||
|
w1, w3 = first_share_wording
|
||||||
|
elif "店铺" in label:
|
||||||
w1, w3 = "第一大店铺约占列表行的", "前三大店铺合计约占"
|
w1, w3 = "第一大店铺约占列表行的", "前三大店铺合计约占"
|
||||||
elif "品牌" in label:
|
elif "品牌" in label:
|
||||||
w1, w3 = "第一大品牌约占", "前三大品牌合计约占"
|
w1, w3 = "第一大品牌约占", "前三大品牌合计约占"
|
||||||
@ -480,6 +493,9 @@ def build_strategy_draft_markdown(
|
|||||||
conc = brief.get("concentration") or {}
|
conc = brief.get("concentration") or {}
|
||||||
shops = conc.get("shops_from_list") or {}
|
shops = conc.get("shops_from_list") or {}
|
||||||
dbrand = conc.get("detail_brand_among_merged") or {}
|
dbrand = conc.get("detail_brand_among_merged") or {}
|
||||||
|
scope_ap = brief.get("strategy_scope_applied")
|
||||||
|
scoped_matrix = isinstance(scope_ap, dict) and bool(scope_ap.get("group"))
|
||||||
|
gname_scoped = _esc(scope_ap.get("group")) if scoped_matrix else ""
|
||||||
lines.extend(
|
lines.extend(
|
||||||
[
|
[
|
||||||
"## 五、与其它品牌有何不同",
|
"## 五、与其它品牌有何不同",
|
||||||
@ -488,17 +504,47 @@ def build_strategy_draft_markdown(
|
|||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
if scoped_matrix:
|
||||||
|
lines.append(
|
||||||
|
"*本任务已按矩阵细类收窄:**下列店铺/品牌占比均按该分组内「深入合并 SKU」条数统计**,"
|
||||||
|
"与全关键词 **PC 搜索列表行** 集中度**不是同一口径**;亦非销量或市占。*"
|
||||||
|
if not for_llm_input
|
||||||
|
else "*集中度:按所选矩阵分组内合并 SKU 条数;非全站列表行。*"
|
||||||
|
)
|
||||||
|
lines.append("")
|
||||||
|
shop_label = (
|
||||||
|
f"店铺分布(「{gname_scoped}」内样本 SKU)"
|
||||||
|
if scoped_matrix
|
||||||
|
else "列表侧店铺集中度"
|
||||||
|
)
|
||||||
|
brand_label = (
|
||||||
|
f"品牌分布(「{gname_scoped}」内样本 SKU)"
|
||||||
|
if scoped_matrix
|
||||||
|
else "深入样本内品牌集中度"
|
||||||
|
)
|
||||||
|
scoped_wording: tuple[str, str] | None = (
|
||||||
|
("第一大店铺约占该分组样本 SKU 的", "前三大店铺合计约占")
|
||||||
|
if scoped_matrix
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
scoped_brand_wording: tuple[str, str] | None = (
|
||||||
|
("第一大品牌约占该分组样本 SKU 的", "前三大品牌合计约占")
|
||||||
|
if scoped_matrix
|
||||||
|
else None
|
||||||
|
)
|
||||||
n_shop = _cr_narrative(
|
n_shop = _cr_narrative(
|
||||||
"列表侧店铺集中度",
|
shop_label,
|
||||||
concentration_first_share(shops),
|
concentration_first_share(shops),
|
||||||
concentration_top_three_share(shops),
|
concentration_top_three_share(shops),
|
||||||
shops.get("top_label"),
|
shops.get("top_label"),
|
||||||
|
first_share_wording=scoped_wording,
|
||||||
)
|
)
|
||||||
n_brand = _cr_narrative(
|
n_brand = _cr_narrative(
|
||||||
"深入样本内品牌集中度",
|
brand_label,
|
||||||
concentration_first_share(dbrand),
|
concentration_first_share(dbrand),
|
||||||
concentration_top_three_share(dbrand),
|
concentration_top_three_share(dbrand),
|
||||||
dbrand.get("top_label"),
|
dbrand.get("top_label"),
|
||||||
|
first_share_wording=scoped_brand_wording,
|
||||||
)
|
)
|
||||||
if n_shop:
|
if n_shop:
|
||||||
lines.append(n_shop)
|
lines.append(n_shop)
|
||||||
|
|||||||
@ -161,6 +161,32 @@ class StrategyDraftTests(SimpleTestCase):
|
|||||||
self.assertNotIn("子串统计命中约 **501**", md)
|
self.assertNotIn("子串统计命中约 **501**", md)
|
||||||
self.assertNotIn("场景「控糖", md)
|
self.assertNotIn("场景「控糖", md)
|
||||||
|
|
||||||
|
def test_matrix_scope_concentration_not_list_rows_wording(self) -> None:
|
||||||
|
"""收窄矩阵时 concentration 来自分组内 SKU,§5.1 勿写「列表行」。"""
|
||||||
|
brief = {
|
||||||
|
"schema_version": 1,
|
||||||
|
"keyword": "低GI",
|
||||||
|
"strategy_scope_applied": {"group": "饼干"},
|
||||||
|
"concentration": {
|
||||||
|
"shops_from_list": {
|
||||||
|
"first_share": 0.238,
|
||||||
|
"top_three_combined_share": 0.571,
|
||||||
|
"top_label": "碧翠园京东自营旗舰店",
|
||||||
|
},
|
||||||
|
"detail_brand_among_merged": {
|
||||||
|
"first_share": 0.238,
|
||||||
|
"top_three_combined_share": 0.667,
|
||||||
|
"top_label": "碧翠园",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
md = build_strategy_draft_markdown(job_id=1, keyword="低GI", brief=brief)
|
||||||
|
self.assertIn("与全关键词 **PC 搜索列表行** 集中度**不是同一口径**", md)
|
||||||
|
self.assertIn("店铺分布(「饼干」内样本 SKU)", md)
|
||||||
|
self.assertIn("该分组样本 SKU 的", md)
|
||||||
|
self.assertNotIn("列表侧店铺集中度", md)
|
||||||
|
self.assertNotIn("第一大店铺约占列表行的", md)
|
||||||
|
|
||||||
def test_shops_unique_sku_basis_rendered(self) -> None:
|
def test_shops_unique_sku_basis_rendered(self) -> None:
|
||||||
brief = {
|
brief = {
|
||||||
"schema_version": 1,
|
"schema_version": 1,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user