fix:句子問卷個性化推薦規則、

This commit is contained in:
雷汀岚
2026-01-30 18:02:46 +08:00
parent 192008986a
commit 3868bf53d1
6 changed files with 1002 additions and 0 deletions

View File

@@ -0,0 +1,319 @@
# 正念 APP三種分發場景推薦算法方案Feed / Push / Widget · V1
> **目標**
> 針對三種分發方式Feed、App Push、Widget 每日一句)制定一套一致但可調參的推薦流程。
>
> **共用基礎**
>
> * 用戶畫像Umom_stage one-hot、emotion_score、context one-hot、need one-hot
> * 文案畫像Cᵢstage、emotion_score、context/need suitability、personalization_power、risk_flags建議含 content_id/author_id/template_id/review_confidence
> * 推薦骨架Hard Filter → Soft Scoring → Rerank多樣性/新鮮度/疲勞)
---
## 一、先說整體流程與思路(適用三種場景)
### 1) 核心理念:同一個用戶同一天需要「不同強度」的個性化
* **Push**:最容易翻車 → **高精準 + 低風險**Precision-first
* **Widget**:每天唯一一句 → **穩定、代表性、可長期持續**Consistency-first
* **Feed**:可上下滑探索 → **可試探、可擴展、多樣性**Exploration-first
### 2) 共用三段式 Pipeline
1. **Candidate Generation候選集生成**
* 依 U 取一個「候選池」:匹配 need/context/stage 的內容 + 一部分通用內容
2. **Hard Filter硬性過濾**
* 依 risk_flags 與產品規則剔除高風險內容
3. **Soft Scoring軟性打分**
* 用加權模型計算核心匹配分
4. **Rerank重排**
* 去重、作者/模板多樣性、頻控、時間衰減
5. **Serve分發**
* 依場景不同策略選 TopK 或組成序列
### 3) 工程必備:候選不足回退策略 + 可觀測指標V1.1
#### 3.1 候選不足回退Fallback Ladder
> 目的:避免「過濾/頻控後候選為空」導致體驗斷崖;同時在回退時**自動降個性化與降風險**(尤其 Push
共用定義:
* `fallback_level`:從 0 開始遞增0=不回退)
* 回退原則:**先放寬匹配,再放寬探索,再回退到通用安全池**;同時限制 `personalization_power` 上限
建議梯度(可按場景調整):
* **L0正常**:按原候選配比取候選
* **L1放寬匹配**`need/context``1 → ≥0.5``personalization_power` 上限降為 `≤0.5`
* **L2回退通用池**:加入更多 `general`/低風險句;`personalization_power` 上限降為 `0`
* **L3兜底**:僅從「通用安全句庫」抽取(需單獨維護白名單/安全池)
每次請求需輸出最終使用的 `fallback_level`(用於分析覆蓋率與風險)。
#### 3.2 可觀測指標(必打點)
每次生成推薦Feed Session / 每次 Push / 每日 Widget至少打點
* `candidate_pool_size_raw`:初始候選池大小
* `candidate_pool_size_after_hard_filter`
* `candidate_pool_size_after_dedup`
* `candidate_pool_size_after_freqcap`
* `fallback_level_final`
* `served_k`:實際下發條數
* `empty_reason`:若 served_k=0記錄原因如 hard_filter_all / freqcap_all / pool_empty / unknown
核心監控衍生指標(報表層計算):
* **覆蓋率**`served_k > 0` 的比例(按場景分開)
* **回退率**`fallback_level_final > 0` 的比例
* **頻控後候選數分布**`candidate_pool_size_after_freqcap` 的 P50/P90/P99
---
## 二、總分結構Score Decomposition
對任意文案 Cᵢ
[
\textbf{final_score}(U,Cᵢ) = \mathbb{I}[\text{pass filters}] \times \Big(
S_{core} + S_{personal} + S_{fresh} - P_{fatigue} - P_{repeat} - P_{risk} - P_{uncertainty}
\Big)
]
其中
[
S_{core} = w_{need}S_{need} + w_{emotion}S_{emotion} + w_{stage}S_{stage} + w_{context}S_{context}
]
* `S_need = Cᵢ.need_suitability[U.need]`
* `S_context = Cᵢ.context_suitability[U.context]`
* `S_stage`general=1命中=1unknown對非unknown=0.7;其餘=0
* `S_emotion`:若文案 general→0.8;否則 `1-|U.emotion_score-Cᵢ.emotion_score|`
個性化加成:
[
S_{personal} = \alpha \cdot Cᵢ.personalization_power \cdot \max(S_{need}, S_{context})
]
不確定性懲罰Push 建議啟用):
[
P_{uncertainty} = \beta \cdot (1-\text{conf}_U) \cdot (1-\text{conf}_{Cᵢ}) \cdot Cᵢ.personalization\_power
]
> 說明:
>
> * `conf_U`:用戶畫像置信度(建議由問卷生成後隨時間衰減;見「用戶畫像」文件 V1.1
> * `conf_{Cᵢ}`:內容標註置信度(`Cᵢ.review_confidence`;缺省可給 0.7
> * `P_{uncertainty}` 可併入 `P_risk`(工程上更簡單),但需保留獨立打點便於調參
---
## 三、Hard Filter共用禁推規則
### 3.1 risk_flags內容自帶
> V1.1 起risk_flags 命名/語義以「句子文案打分規則」為準(`unsafe_for_*` / `block_*` / `soft_*`)。
* `U.stage.unknown=1` → 禁推 `unsafe_for_stage_unknown`
* `U.stage.parenting=1` → 禁推 `unsafe_for_stage_parenting`
* `U.emotion_score≤0.2` → 禁推 `unsafe_for_emotion_low`
* `U.context.health=1` → 禁推 `block_health_medical`(僅擋「醫療/診斷/嚴重暗示」)
> `soft_health_sensitive` 不做 Hard Filter改由 Soft Penalty見 Push 的 P_risk
### 3.2 產品規則(跨維度)
* `U.stage.unknown=1``Cᵢ.need_suitability[parenting_pressure]=1``Cᵢ.personalization_power=1` → 禁推
---
# 四、Feed 模式App 內上下滑)— Exploration-first
## 4.1 目標
* 讓用戶快速感到「被理解」
* 同時探索更多題材,避免內容疲乏
* 允許一定程度的試探(比 Push 寬鬆)
## 4.2 流程Feed Session
1. **建候選池**(大)
* 60%:匹配 need/context 的內容(含 personalization_power=0.5/1
* 30%通用內容general
* 10%:探索內容(與 context/need 邊緣相關)
2. Hard Filter仍嚴格
3. Soft Scoring偏多樣性
4. Rerank用 MMR 做序列
## 4.3 Feed 打分權重(建議)
* `w_need=0.35, w_emotion=0.20, w_stage=0.15, w_context=0.30`
> Feed 更重視「語境共鳴」與內容多樣性,所以 context 權重上調。
## 4.4 Feed 序列重排MMR
* Top1最高分確保第一眼命中
* 後續:在高分候選中,最大化與已選內容的差異(作者/模板/need/context
### 4.5 Feed 的 MMR 定義工程側定義V1.1
選擇第 t 個內容:
[
\text{MMR}(c)=\lambda \cdot \text{Rel}(c) - (1-\lambda)\cdot \max_{s \in S_{t-1}} \text{Sim}(c,s)
]
建議預設:`λ = 0.7`(更偏相關性,仍保留多樣性)
* `Rel(c)`:使用 `final_score(U,c)`(或 Soft Scoring 後的分數)
* `Sim(c,s)`:相似度定義(無 embedding 也可落地)
相似度(離散特徵版,推薦 V1 上線):
*`content_id` 相同 → `Sim=1`
*`template_id` 相同且非空 → `Sim += 0.6`
*`author_id` 相同且非空 → `Sim += 0.3`
* `need/context/stage` 標籤重合Jaccard`Sim += 0.1 * Jaccard(tags_c, tags_s)`
* 最終 `Sim` clamp 到 `[0,1]`
字段依賴與回退:
*`template_id/author_id` 時,只用 tags 相似度Sim 仍可算)
* 若後續引入文本 embedding可將 embedding cosine 加權合併V2
---
# 五、App Push可設定 05 次)— Precision & Safety-first
## 5.1 目標
* Push 是「打擾」:錯一次就掉留存
* 追求「準、溫柔、少翻車」
## 5.2 流程(每次 Push
1. **候選池**(小而精)
* 70%need 命中S_need=1的內容
* 20%emotion 命中(距離小)的內容
* 10%通用安全句general + 低風險)
2. Hard Filter最嚴格
3. Soft Scoring偏 need + emotion
4. 冷卻與頻控(必做)
* 同一句/同作者/同模板至少 X 天不重複
5. 發送
> Push 追加規則V1.1):若 `fallback_level_final > 0` 或 `conf_U` 偏低,需自動「降個性化」:
>
> * `personalization_power` 上限降為 `≤0.5`L1或 `0`L2/L3
> * 若候選不足,優先回退到「通用安全句庫」,而不是擴大高個性化內容
## 5.3 Push 打分權重(建議)
* `w_need=0.45, w_emotion=0.35, w_stage=0.15, w_context=0.05`
> Push 更在乎「此刻需要」與「語氣安全」。context 權重降低。
## 5.4 Push 風險懲罰P_risk
*`Cᵢ.personalization_power=1``S_need<1``S_context<1` → 額外扣分
* 若 content 涉及健康敏感(`soft_health_sensitive`)→ 扣分Soft Penalty不做禁推
* 不確定性懲罰:`P_uncertainty`(或併入 `P_risk`),用於在 `conf_U/conf_C` 偏低時自動降權高個性化內容
## 5.5 05 次推送的排程策略
* 使用者設定次數 N
* 第 1 條need 命中 + 安全
* 第 2 條emotion 修復
* 第 3 條self-worth / rest_balance視 need 而定)
* 第 45 條:通用句補位,避免疲勞
---
# 六、Widget每日一句— Consistency & Brand-first
## 6.1 目標
* Widget 是「代表你這個 App 的一句話」
* 需要:穩定、可持續、低風險、避免太私密
## 6.2 流程(每日生成)
1. 候選池:以 **general + personalization_power≤0.5** 為主
2. Hard Filter嚴格
3. Soft Scoring偏 stage 安全 + emotion 中性/平靜
4. 跨日多樣性7 日內不重複作者/模板/同一句
> 若候選不足:同樣走回退梯度(優先增加 general 安全句;不提高個性化力度)。
## 6.3 Widget 打分權重(建議)
* `w_need=0.25, w_emotion=0.25, w_stage=0.30, w_context=0.20`
> Widget 需要「身份語境安全」與「普適」stage 權重更高。
## 6.4 Widget 的情緒區間約束
* 建議限制 `Cᵢ.emotion_score`**0.40.8**tired→calm
* 避免太低(沉重)
* 避免太高(過嗨)
---
## 七、場景差異總結(快速對照)
| 場景 | 目標 | 候選池 | 風險容忍 | 權重重點 | 序列策略 |
| ------ | ----- | --- | ---- | ------------------- | ------ |
| Feed | 探索+共鳴 | 大 | 中 | context↑、diversity↑ | MMR 序列 |
| Push | 準+安全 | 小 | 低 | need↑、emotion↑ | 頻控+冷卻 |
| Widget | 穩+代表性 | 中小 | 低 | stage↑、emotion中性 | 跨日多樣性 |
---
## 八、(後段解釋預告)提及的算法/概念
* Candidate Generation混合召回命中 + 通用 + 探索)
* Hard Filter規則引擎
* Linear Weighted Scoring加權線性模型
* MMRMaximal Marginal Relevance多樣性重排
* Time Decay時間衰減
* Frequency Capping頻控
* Cooldown Keys去重鍵句子/作者/模板)
> 工程側去重鍵定義V1.1
>
> * `sentence_key = content_id`(若無 content_id需生成 stable hash但建議補 content_id
> * `author_key = author_id`(可空)
> * `template_key = template_id`(可空)
>
> 冷卻/頻控同時支持三層 key避免只靠單一 key 造成過度重複或過度稀釋。
---
## 九、V1 可直接上線的預設參數
* FeedTop1 命中 + MMR 序列 30 條
* Push每次 Top1冷卻 7 天不重複作者14 天不重複同句
* Widgetemotion_score 限制 0.40.87 日不重複作者/模板
V1.1 補充(工程預設):
* FeedMMR `λ=0.7`
* Push啟用 `P_uncertainty`(或併入 `P_risk``fallback_level>=1``personalization_power` 上限降為 `≤0.5`
* HealthHard Filter 僅擋 `block_health_medical``soft_health_sensitive` 走 Soft Penalty
> 一句話:
> **同一套 U×Cᵢ 打分,按場景調候選池、權重與重排約束。**