acd9b679
tangwang
doc
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
|
# 在线召回Redis Key完整清单
## 📊 Redis数据统计
- **总Key数量**: 211,232 个
- **数据库**: Redis DB 3 (port: 6479)
---
## 🔑 一、商品相似度索引(I2I Recall)
用于"相似推荐"场景,根据用户点击的商品召回相似商品。
### 1. C++ Swing算法(高性能版本)
**Key模式**: `item:similar:swing_cpp:{item_id}`
**数量**: 15,310 个
**示例**:
```redis
Key: item:similar:swing_cpp:3562865
Value: "3605981:0.0209644,2526246:0.0209644,2348869:0.0209644"
```
**格式**: JSON字符串,`similar_id:score` 格式
**用途**:
- 详情页"相似推荐"
- 基于用户点击历史的个性化推荐
- 高性能生产环境推荐
---
### 2. Python Swing算法(标准版本)
**Key模式**: `item:similar:swing:{item_id}`
**数量**: 169,409 个
**示例**:
```redis
Key: item:similar:swing:3141390
Value: "3264320:1.2656,3264284:1.2656,3562128:0.4000,..."
```
**格式**: JSON字符串,`similar_id:score` 格式
**用途**:
- 详情页"看了又看"
- 购物车"相关推荐"
- 需要归一化分数的场景
---
### 3. Session W2V算法
**Key模式**: `item:similar:session_w2v:{item_id}`
**数量**: 26,503 个
**示例**:
```redis
Key: item:similar:session_w2v:3402580
Value: "商品序列相似度数据"
```
**用途**:
- 基于用户会话序列的推荐
- 捕捉用户的浏览路径
- 补充Swing算法的不足
---
## 🎯 二、兴趣聚合索引(Interest Recall)
用于"热门推荐"场景,根据用户兴趣维度召回相关商品。
### 当前存在的兴趣聚合Key:
#### 1. 平台维度
```redis
Key: interest:hot:platform:essaone
Value: [3582462, 3582428, 3582384, ...] # 1000个商品
```
#### 2. 客户端平台维度
```redis
Key: interest:hot:client_platform:pc
Value: [3582462, 3582428, 3582384, ...] # 1000个商品
```
#### 3. 平台+客户端组合维度
```redis
Key: interest:hot:platform_client:essaone_pc
Value: [平台+客户端的组合热门商品]
```
#### 4. 一级分类维度
```redis
Key: interest:hot:category_level1:1
Value: [一级分类的热门商品]
```
#### 5. 二级分类维度
```redis
Key: interest:hot:category_level2:29
Value: [3482467, 2708138, 1008982, ...] # 1000个商品
```
#### 6. 三级分类维度
```redis
Key: interest:hot:category_level3:2040
Value: [三级分类的热门商品]
```
#### 7. 四级分类维度
```redis
Key: interest:hot:category_level4:2040
Value: [四级分类的热门商品]
```
#### 8. 平台+二级分类组合维度
```redis
Key: interest:hot:platform_category2:essaone_29
Value: [260个商品]
```
#### 9. 平台+三级分类组合维度
```redis
Key: interest:hot:platform_category3:essaone_2040
Value: [231个商品]
```
#### 10. 供应商维度
```redis
Key: interest:hot:supplier:24947
Value: [1566197] # 1个商品
```
---
## 📋 在线召回使用策略
### 场景1: 详情页相似推荐
**召回Key**:
```python
# 根据当前浏览的商品ID
item_id = request.sku_id
recall_keys = [
f"item:similar:swing_cpp:{item_id}", # 优先使用高性能版本
f"item:similar:swing:{item_id}", # 降级使用
f"item:similar:session_w2v:{item_id}", # 补充推荐
]
```
**召回流程**:
1. 优先查询 `swing_cpp`(C++高性能版本)
2. 如果没有结果,查询 `swing`(Python标准版本)
3. 如果还没结果,查询 `session_w2v`(会话序列版本)
4. 最终结果融合多个算法的相似商品
---
### 场景2: 首页热门推荐
**召回Key**:
```python
# 根据用户特征和上下文
user_profile = get_user_profile(user_id)
context = request.context # {platform, client, category, ...}
recall_keys = []
# 1. 组合维度推荐(最精准)
if context.get('platform') and context.get('category_level2'):
recall_keys.append(
f"interest:hot:platform_category2:{context['platform']}_{context['category_level2']}"
)
# 2. 单一分类维度
if context.get('category_level2'):
recall_keys.append(f"interest:hot:category_level2:{context['category_level2']}")
# 3. 平台维度
if context.get('platform'):
recall_keys.append(f"interest:hot:platform:{context['platform']}")
# 4. 客户端平台维度
if context.get('client'):
recall_keys.append(f"interest:hot:client_platform:{context['client']}")
# 5. 全局热门(兜底)
recall_keys.append("interest:hot:platform:essaone") # 全局热门
```
**召回优先级**:
1. 组合维度(如 platform_category2) - 最精准
2. 分类维度(category_level2/3/4)
3. 平台维度(platform)
4. 全局热门 - 兜底策略
---
### 场景3: 用户点击历史推荐
**召回Key**:
```python
# 根据用户点击的商品列表
clicked_items = [3141390, 3141390, 3606104, 3606102, ...]
all_recalled_items = []
for item_id in clicked_items:
# 查询相似商品
similar_items = redis.get(f"item:similar:swing_cpp:{item_id}")
if not similar_items:
similar_items = redis.get(f"item:similar:swing:{item_id}")
all_recalled_items.extend(similar_items)
# 去重并排序
final_items = deduplicate_and_rank(all_recalled_items)
```
---
### 场景4: 类别偏好推荐
**召回Key**:
```python
# 根据用户收藏的类别
collected_categories = [1541, 137, 153, 1561, 1689, 1691]
recall_keys = []
for cat_id in collected_categories:
# 查询该类别的热门商品
category_key = f"interest:hot:category_level2:{cat_id}"
recall_keys.append(category_key)
# 批量查询
hot_items = redis.mget(recall_keys)
```
---
## ⚠️ 注意事项
### 1. Key存在性检查
```python
def safe_get_recall(key):
"""安全获取召回数据,带降级策略"""
result = redis.get(key)
if not result:
# 降级策略:使用更通用的key
if ":category_level2:" in key:
# 尝试用更高级别的分类
fallback_key = key.replace("category_level2", "category_level1")
result = redis.get(fallback_key)
elif "platform_category" in key:
# 尝试单独的平台或分类
result = redis.get(key.replace("platform_category2:", "category_level2:"))
return result or []
```
### 2. 数据格式
- **I2I数据**: JSON字符串,格式为 `"item_id1:score1,item_id2:score2"`
- **Interest数据**: JSON数组,格式为 `[item_id1, item_id2, ...]`
### 3. 解析方法
```python
import json
# I2I数据解析
def parse_i2i_data(value):
items = []
for pair in value.split(','):
if ':' in pair:
item_id, score = pair.split(':')
items.append([int(item_id), float(score)])
return items
# Interest数据解析
def parse_interest_data(value):
return json.loads(value)
```
### 4. 推荐数量
- 每个相似推荐key通常包含10-50个商品
- 每个兴趣聚合key通常包含100-1000个商品
- 最终推荐数量建议:取Top 20-50个商品
---
## 📊 Key覆盖率统计
| Key类型 | 数量 | 覆盖率 | 使用优先级 |
|---------|------|--------|-----------|
| item:similar:swing | 170,116 | ~80% | ⭐⭐⭐⭐⭐ |
| item:similar:content_name | 129,103 | ~70% | ⭐⭐⭐⭐ |
| item:similar:session_w2v | 52,339 | ~30% | ⭐⭐⭐ |
| item:similar:deepwalk | 49,052 | ~30% | ⭐⭐⭐ |
| item:similar:swing_cpp | 15,310 | ~10% | ⭐⭐⭐⭐⭐ |
| item:similar:content_pic | 12,118 | ~7% | ⭐⭐ |
| interest:hot:* | 10 | ~5% | ⭐⭐ |
**说明**:
- Swing覆盖商品约10万+,应优先使用
- 兴趣聚合数据较少,建议作为补充召回策略
---
## 🔧 修复建议
### 缺失的关键数据:
1. **DeepWalk索引**: `item:similar:deepwalk:{item_id}` - 缺失
2. **内容相似度**: `item:similar:content_name:{item_id}` - 缺失
3. **图片相似度**: `item:similar:content_pic:{item_id}` - 缺失
4. **更多兴趣聚合维度**:
- `interest:hot:category_level2:{id}` - 缺失(1541, 137, 153等)
- `interest:cart:*` - 缺失
- `interest:new:*` - 缺失
- `interest:global:*` - 缺失
### 建议操作:
```bash
# 1. 运行兴趣聚合任务生成更多维度数据
cd /home/tw/recommendation/offline_tasks
python3 scripts/interest_aggregation.py
# 2. 加载更多兴趣聚合数据到Redis
python3 scripts/load_index_to_redis.py --load-interest
# 3. 定期更新数据(每天)
crontab -e
# 添加: 0 3 * * * /home/tw/recommendation/offline_tasks/update_indices.sh
```
---
## 📞 使用示例
### Python召回示例
```python
import redis
import json
redis_client = redis.Redis(
host='localhost',
port=6479,
db=3,
password='BMfv5aI31kgHWtlx',
decode_responses=True
)
def recall_similar_items(item_id):
"""召回相似商品"""
# 按优先级查询
keys = [
f"item:similar:swing_cpp:{item_id}",
f"item:similar:swing:{item_id}",
f"item:similar:session_w2v:{item_id}"
]
for key in keys:
value = redis_client.get(key)
if value:
# 解析数据
items = []
for pair in value.split(','):
if ':' in pair:
similar_id, score = pair.split(':')
items.append([int(similar_id), float(score)])
return items
return []
def recall_hot_items(platform, category_level2):
"""召回热门商品"""
key = f"interest:hot:platform_category2:{platform}_{category_level2}"
value = redis_client.get(key)
if value:
return json.loads(value)
# 降级策略
category_key = f"interest:hot:category_level2:{category_level2}"
value = redis_client.get(category_key)
if value:
return json.loads(value)
# 最终降级:全局热门
global_key = f"interest:hot:platform:{platform}"
value = redis_client.get(global_key)
if value:
return json.loads(value)
return []
```
---
## 🎯 总结
**当前Redis中有数据的Key类型**:
1. ✅ `item:similar:swing:{item_id}` - 170,116个
2. ✅ `item:similar:content_name:{item_id}` - 129,103个
3. ✅ `item:similar:session_w2v:{item_id}` - 52,339个
4. ✅ `item:similar:deepwalk:{item_id}` - 49,052个
5. ✅ `item:similar:swing_cpp:{item_id}` - 15,310个
6. ✅ `item:similar:content_pic:{item_id}` - 12,118个
7. ✅ `interest:hot:platform:{platform}` - 1个
8. ✅ `interest:hot:client_platform:{client}` - 1个
9. ✅ `interest:hot:platform_client:{platform}_{client}` - 1个
10. ✅ `interest:hot:category_level1:{id}` - 1个
11. ✅ `interest:hot:category_level2:{id}` - 1个
12. ✅ `interest:hot:category_level3:{id}` - 1个
13. ✅ `interest:hot:category_level4:{id}` - 1个
14. ✅ `interest:hot:platform_category2:{platform}_{id}` - 1个
15. ✅ `interest:hot:platform_category3:{platform}_{id}` - 1个
16. ✅ `interest:hot:supplier:{id}` - 1个
**缺失但应该有的Key**:
- ❌ 更多类别的 `interest:hot:category_level2:{id}`
- ❌ `interest:cart:*` (加购热门)
- ❌ `interest:new:*` (新品)
- ❌ `interest:global:*` (全局热门)
**建议**: 优先使用现有的高质量数据,同时尽快补充缺失的兴趣聚合数据。
|