|
@@ -368,6 +368,7 @@ def _items_to_materials(
|
|
|
sim_threshold: float,
|
|
sim_threshold: float,
|
|
|
*,
|
|
*,
|
|
|
apply_cover_blacklist: bool = True,
|
|
apply_cover_blacklist: bool = True,
|
|
|
|
|
+ min_cost: Optional[float] = None,
|
|
|
) -> tuple:
|
|
) -> tuple:
|
|
|
"""把召回 items 过滤 + 转 Material。
|
|
"""把召回 items 过滤 + 转 Material。
|
|
|
|
|
|
|
@@ -375,6 +376,7 @@ def _items_to_materials(
|
|
|
- modality=MATERIAL(防御性)
|
|
- modality=MATERIAL(防御性)
|
|
|
- cover URL 不在黑名单
|
|
- cover URL 不在黑名单
|
|
|
- score >= sim_threshold
|
|
- score >= sim_threshold
|
|
|
|
|
+ - min_cost is not None 时:历史成本(cost, 元) >= min_cost(严格,无成本数据也排除)
|
|
|
|
|
|
|
|
CTR / impressions 只作为审批展示和兜底排序参考,不再作为硬筛。
|
|
CTR / impressions 只作为审批展示和兜底排序参考,不再作为硬筛。
|
|
|
返回 (materials, stats)。
|
|
返回 (materials, stats)。
|
|
@@ -383,6 +385,7 @@ def _items_to_materials(
|
|
|
stats = {
|
|
stats = {
|
|
|
"blacklist": 0,
|
|
"blacklist": 0,
|
|
|
"low_score": 0,
|
|
"low_score": 0,
|
|
|
|
|
+ "low_cost": 0,
|
|
|
"low_imp": 0,
|
|
"low_imp": 0,
|
|
|
"low_ctr": 0,
|
|
"low_ctr": 0,
|
|
|
}
|
|
}
|
|
@@ -404,13 +407,18 @@ def _items_to_materials(
|
|
|
continue
|
|
continue
|
|
|
md = it.get("materialDetail") or {}
|
|
md = it.get("materialDetail") or {}
|
|
|
q = md.get("quality") or {}
|
|
q = md.get("quality") or {}
|
|
|
|
|
+ raw_cost = q.get("cost")
|
|
|
|
|
+ cost = _as_float(raw_cost) if raw_cost is not None else None
|
|
|
|
|
+ if min_cost is not None and (cost is None or cost < min_cost):
|
|
|
|
|
+ stats["low_cost"] += 1
|
|
|
|
|
+ continue
|
|
|
out.append(Material(
|
|
out.append(Material(
|
|
|
material_id=str(mid),
|
|
material_id=str(mid),
|
|
|
score=score,
|
|
score=score,
|
|
|
title=it.get("title") or "",
|
|
title=it.get("title") or "",
|
|
|
cover=cover,
|
|
cover=cover,
|
|
|
video_url=it.get("videoUrl") or "",
|
|
video_url=it.get("videoUrl") or "",
|
|
|
- cost=_as_float(q.get("cost")) if q.get("cost") is not None else None,
|
|
|
|
|
|
|
+ cost=cost,
|
|
|
ctr=_as_float(q.get("ctr")) if q.get("ctr") is not None else None,
|
|
ctr=_as_float(q.get("ctr")) if q.get("ctr") is not None else None,
|
|
|
cvr=_as_float(q.get("cvr")) if q.get("cvr") is not None else None,
|
|
cvr=_as_float(q.get("cvr")) if q.get("cvr") is not None else None,
|
|
|
roi=_as_float(q.get("roi")) if q.get("roi") is not None else None,
|
|
roi=_as_float(q.get("roi")) if q.get("roi") is not None else None,
|
|
@@ -577,6 +585,7 @@ def recall_materials_for_video(
|
|
|
source_labels: Optional[List[str]] = None,
|
|
source_labels: Optional[List[str]] = None,
|
|
|
element_features: Optional[Iterable] = None,
|
|
element_features: Optional[Iterable] = None,
|
|
|
apply_cover_blacklist: bool = True,
|
|
apply_cover_blacklist: bool = True,
|
|
|
|
|
+ min_cost: Optional[float] = None,
|
|
|
) -> List[Material]:
|
|
) -> List[Material]:
|
|
|
"""素材召回:用 ODPS 多维特征并行召回并合并排序。
|
|
"""素材召回:用 ODPS 多维特征并行召回并合并排序。
|
|
|
|
|
|
|
@@ -585,16 +594,21 @@ def recall_materials_for_video(
|
|
|
2. 多 query 并行调用 batchByText。
|
|
2. 多 query 并行调用 batchByText。
|
|
|
3. 汇总、material_id 去重、score>=阈值、按 cost 倒序。
|
|
3. 汇总、material_id 去重、score>=阈值、按 cost 倒序。
|
|
|
|
|
|
|
|
- 当前硬筛只保留相似度阈值;曝光/CTR 进入审批表但不拦截。
|
|
|
|
|
|
|
+ 硬筛:相似度阈值 + 历史成本(cost>=min_cost,min_cost 默认取 config.RECALL_MIN_COST_YUAN)。
|
|
|
|
|
+ 曝光/CTR 进入审批表但不拦截。
|
|
|
"""
|
|
"""
|
|
|
from config import (
|
|
from config import (
|
|
|
RECALL_ALPHA, RECALL_DAYS, RECALL_DECONSTRUCT_BOOST,
|
|
RECALL_ALPHA, RECALL_DAYS, RECALL_DECONSTRUCT_BOOST,
|
|
|
- RECALL_DISPLAY_K, RECALL_PARALLEL_MAX_WORKERS, RECALL_QUERY_LIMIT_PER_VIDEO,
|
|
|
|
|
|
|
+ RECALL_DISPLAY_K, RECALL_MIN_COST_YUAN, RECALL_PARALLEL_MAX_WORKERS,
|
|
|
|
|
+ RECALL_QUERY_LIMIT_PER_VIDEO,
|
|
|
RECALL_SIM_THRESHOLD, RECALL_SOURCE_LABELS,
|
|
RECALL_SIM_THRESHOLD, RECALL_SOURCE_LABELS,
|
|
|
RECALL_W_CTR, RECALL_W_CVR, RECALL_W_FISSION_RATE,
|
|
RECALL_W_CTR, RECALL_W_CVR, RECALL_W_FISSION_RATE,
|
|
|
RECALL_W_OPEN_RATE, RECALL_W_ROI,
|
|
RECALL_W_OPEN_RATE, RECALL_W_ROI,
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+ if min_cost is None:
|
|
|
|
|
+ min_cost = RECALL_MIN_COST_YUAN
|
|
|
|
|
+
|
|
|
if element_features is None:
|
|
if element_features is None:
|
|
|
element_features = landing.raw.get("element_features") or []
|
|
element_features = landing.raw.get("element_features") or []
|
|
|
queries = _build_recall_queries_from_features(
|
|
queries = _build_recall_queries_from_features(
|
|
@@ -646,13 +660,15 @@ def recall_materials_for_video(
|
|
|
items,
|
|
items,
|
|
|
RECALL_SIM_THRESHOLD,
|
|
RECALL_SIM_THRESHOLD,
|
|
|
apply_cover_blacklist=apply_cover_blacklist,
|
|
apply_cover_blacklist=apply_cover_blacklist,
|
|
|
|
|
+ min_cost=min_cost,
|
|
|
)
|
|
)
|
|
|
query_materials.append((query, mats))
|
|
query_materials.append((query, mats))
|
|
|
logger.info(
|
|
logger.info(
|
|
|
- "[material_recall] 策略=%s q=%r configCode=%s 返回 %d 条,⊘ 黑名单 %d,⊘ score<%.2f %d → 保留 %d",
|
|
|
|
|
|
|
+ "[material_recall] 策略=%s q=%r configCode=%s 返回 %d 条,⊘ 黑名单 %d,⊘ score<%.2f %d,⊘ cost<%.0f %d → 保留 %d",
|
|
|
query.strategy_name, query.query_text[:30], query.config_code,
|
|
query.strategy_name, query.query_text[:30], query.config_code,
|
|
|
len(items), stats["blacklist"], RECALL_SIM_THRESHOLD,
|
|
len(items), stats["blacklist"], RECALL_SIM_THRESHOLD,
|
|
|
- stats["low_score"], len(mats),
|
|
|
|
|
|
|
+ stats["low_score"], min_cost, stats["low_cost"],
|
|
|
|
|
+ len(mats),
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
merged = _merge_materials_by_policy(query_materials)
|
|
merged = _merge_materials_by_policy(query_materials)
|
|
@@ -684,6 +700,7 @@ def recall_materials_for_video(
|
|
|
fallback_items,
|
|
fallback_items,
|
|
|
RECALL_SIM_THRESHOLD,
|
|
RECALL_SIM_THRESHOLD,
|
|
|
apply_cover_blacklist=apply_cover_blacklist,
|
|
apply_cover_blacklist=apply_cover_blacklist,
|
|
|
|
|
+ min_cost=min_cost,
|
|
|
)
|
|
)
|
|
|
fquery = RecallQuery(
|
|
fquery = RecallQuery(
|
|
|
query_text=query.query_text,
|
|
query_text=query.query_text,
|
|
@@ -696,9 +713,10 @@ def recall_materials_for_video(
|
|
|
)
|
|
)
|
|
|
fmats = _merge_materials_by_policy([(fquery, fmats)])
|
|
fmats = _merge_materials_by_policy([(fquery, fmats)])
|
|
|
logger.info(
|
|
logger.info(
|
|
|
- "[material_recall] fallback=%s 返回 %d 条,⊘ 黑名单 %d,⊘ score<%.2f %d → 保留 %d(cost desc)",
|
|
|
|
|
|
|
+ "[material_recall] fallback=%s 返回 %d 条,⊘ 黑名单 %d,⊘ score<%.2f %d,⊘ cost<%.0f %d → 保留 %d(cost desc)",
|
|
|
fallback_cc, len(fallback_items), fstats["blacklist"],
|
|
fallback_cc, len(fallback_items), fstats["blacklist"],
|
|
|
RECALL_SIM_THRESHOLD, fstats["low_score"],
|
|
RECALL_SIM_THRESHOLD, fstats["low_score"],
|
|
|
|
|
+ min_cost, fstats["low_cost"],
|
|
|
len(fmats),
|
|
len(fmats),
|
|
|
)
|
|
)
|
|
|
if fmats:
|
|
if fmats:
|