详细设计文档.md 17.6 KB

推荐系统离线任务详细设计文档

📋 文档说明

本文档是推荐系统离线任务的详细设计文档,包含系统架构、功能模块、实现细节和使用指南。

最后更新: 2024-10-17
版本: v1.1
状态: ✅ 已完成并可用


📦 项目概述

推荐系统离线任务负责生成各类推荐索引,包括商品相似度索引(i2i)和兴趣点聚合索引,为在线推荐系统提供数据支撑。

核心功能

  1. i2i相似度索引(4种算法)

    • Swing算法(C++高性能版 + Python版)
    • Session Word2Vec
    • DeepWalk
    • Content-based(内容相似度)
  2. 兴趣点聚合索引(11个维度)

    • 7个单维度:platform、client_platform、supplier、category_level1-4
    • 4个组合维度:platform_client、platform_category2、platform_category3、client_category2
    • 3种列表类型:hot(热门)、cart(加购)、new(新品)、global(全局)

技术特点

  • 完整性: 行为相似 + 内容相似,短期热门 + 长期稳定
  • 灵活性: 支持4级分类查询,支持多维度组合
  • 可扩展性: 易于添加新维度和新算法
  • 高性能: C++ Swing算法性能比Python快10-100倍

🏗️ 系统架构

目录结构

offline_tasks/
├── scripts/                          # Python脚本
│   ├── fetch_item_attributes.py      # 前置任务:获取商品属性
│   ├── generate_session.py           # 前置任务:生成session
│   ├── i2i_swing.py                  # Python Swing算法
│   ├── i2i_session_w2v.py            # Session W2V
│   ├── i2i_deepwalk.py               # DeepWalk
│   ├── i2i_content_similar.py        # 内容相似度
│   ├── interest_aggregation.py       # 兴趣聚合
│   ├── load_index_to_redis.py        # 加载到Redis
│   ├── add_names_to_swing.py         # 添加商品名
│   └── debug_utils.py                # Debug工具
├── collaboration/                     # C++ Swing算法
│   ├── src/                          # C++源码
│   ├── run.sh                        # 执行脚本
│   └── output/                       # 输出目录
├── config/
│   └── offline_config.py             # 配置文件
├── doc/                              # 文档目录
│   ├── 详细设计文档.md               # 本文档
│   ├── 离线索引数据规范.md           # 数据输出规范
│   └── Redis数据规范.md              # Redis存储规范
├── output/                           # 输出文件
├── logs/                             # 日志文件
├── run.sh                            # ⭐ 主执行脚本
├── run_all.py                        # Python版本执行脚本
└── README.md

执行流程

1. 环境准备
   └─ 清理旧进程、创建必要目录

2. 前置任务
   ├─ fetch_item_attributes.py    → 商品属性映射(避免重复查询数据库)
   ├─ generate_session.py          → 用户session文件
   └─ collaboration/run.sh         → C++ Swing (高性能版本)

3. i2i算法任务
   ├─ i2i_swing.py                → Python Swing (支持日期维度)
   ├─ i2i_session_w2v.py          → Session W2V
   ├─ i2i_deepwalk.py             → DeepWalk
   └─ i2i_content_similar.py      → 内容相似度

4. 兴趣聚合
   └─ interest_aggregation.py     → 多维度聚合

5. 加载Redis
   └─ load_index_to_redis.py      → 导入Redis

6. 完成
   └─ 输出结果文件列表

🎯 功能模块详解

1. i2i相似度索引

1.1 Swing算法

两个版本:

C++高性能版本

  • 文件位置: offline_tasks/collaboration/
  • 性能: 比Python快10-100倍
  • 适用场景: 生产环境,海量数据(>50,000商品)
  • 输出格式: item_id \t similar_id1:score1,similar_id2:score2,...
  • 分数特点: 原始Swing分数(未归一化)

Python标准版本

  • 文件: scripts/i2i_swing.py
  • 性能: 适中,易于调试
  • 适用场景: 开发测试,需要高级特性(时间衰减、日期维度)
  • 输出格式: item_id \t item_name \t similar_id1:score1,...
  • 分数特点: 归一化到0-1区间

参数配置:

# C++ Swing
ALPHA=0.7          # Swing alpha参数(0.5-1.0)
THRESHOLD1=1       # 交互强度阈值1
THRESHOLD2=3       # 交互强度阈值2
THREAD_NUM=4       # 线程数

# Python Swing
--lookback_days 730        # 回看天数
--use_daily_session        # 启用日期维度(同时考虑用户整体行为和单日行为)
--time_decay               # 启用时间衰减
--debug                    # Debug模式

1.2 Session Word2Vec

基于用户会话序列的商品相似度计算,捕捉用户浏览顺序关系。

特点:

  • 基于Word2Vec算法
  • 考虑商品在会话中的顺序
  • 适合"看了又看"场景

参数:

python3 scripts/i2i_session_w2v.py --lookback_days 730 --top_n 50 --save_model

1.3 DeepWalk

基于图随机游走的商品相似度计算,发现商品间的深层关系。

特点:

  • 构建商品关系图
  • 随机游走生成序列
  • 发现间接关联

参数:

python3 scripts/i2i_deepwalk.py --lookback_days 730 --top_n 50 --save_model --save_graph

1.4 Content-based 内容相似度

基于商品属性(分类、供应商等)计算相似度。

三种方法:

  • TF-IDF方法: 基于商品名称文本
  • 分类方法: 基于商品分类层级
  • 混合方法: 综合多种特征(推荐)

参数:

python3 scripts/i2i_content_similar.py --top_n 50 --method hybrid

2. 兴趣点聚合索引

根据不同维度聚合热门商品,支持个性化推荐。

支持的维度

单维度(7个):

  • platform: 业务平台(pc, h5, app等)
  • client_platform: 客户端平台(iOS, Android, Web等)
  • supplier: 供应商
  • category_level1: 一级分类
  • category_level2: 二级分类
  • category_level3: 三级分类
  • category_level4: 四级分类

组合维度(4个):

  • platform_client: 平台+客户端
  • platform_category2: 平台+二级分类
  • platform_category3: 平台+三级分类
  • client_category2: 客户端+二级分类

列表类型

  • hot: 热门商品(最近N天高交互)
  • cart: 加购商品(高加购率)
  • new: 新品(最近90天上架)
  • global: 全局热门

参数:

python3 scripts/interest_aggregation.py --lookback_days 730 --top_n 1000

3. 前置任务

3.1 商品属性获取

问题: 多个脚本需要商品名称,重复查询数据库效率低。

解决方案: 前置任务一次性获取,保存到本地文件。

python3 scripts/fetch_item_attributes.py

输出:

  • output/item_attributes_mappings.json: 商品ID->名称映射
  • output/item_attributes_stats.txt: 统计信息

效果: 减少80-90%的数据库查询次数

3.2 Session文件生成

从数据库提取用户行为数据,生成session文件供算法使用。

python3 scripts/generate_session.py --lookback_days 730 --format both

输出格式:

  • session.txt.YYYYMMDD: 标准格式(包含uid)
  • session.txt.YYYYMMDD.cpp: C++格式(纯json)

行为权重:

  • purchase: 10.0(购买)
  • contactFactory: 5.0(联系厂家)
  • addToCart: 3.0(加入购物车)
  • addToPool: 2.0(加入询价池)

🚀 使用指南

快速开始(3步)

步骤1: 安装依赖

cd /home/tw/recommendation/offline_tasks
bash install.sh

步骤2: 测试连接

python3 test_connection.py

步骤3: 运行任务

# 小数据量测试(30天数据)
python3 scripts/i2i_swing.py --lookback_days 30 --top_n 10

# 完整任务(推荐使用run.sh)
bash run.sh

运行完整流程

方式1: 使用run.sh(推荐)

cd /home/tw/recommendation/offline_tasks
bash run.sh

这将自动执行:

  • 前置任务(商品属性、session生成)
  • C++ Swing算法
  • Python算法(Swing、W2V、DeepWalk、内容相似度)
  • 兴趣聚合
  • Redis加载

方式2: 使用run_all.py(简化版)

python3 run_all.py --debug

不包括C++ Swing和Redis加载。

方式3: 单独运行任务

# 1. 前置任务
python3 scripts/fetch_item_attributes.py
python3 scripts/generate_session.py --lookback_days 730

# 2. C++ Swing
cd collaboration && bash run.sh && cd ..

# 3. Python算法
python3 scripts/i2i_swing.py --lookback_days 730 --use_daily_session --debug
python3 scripts/i2i_session_w2v.py --lookback_days 730 --top_n 50
python3 scripts/i2i_deepwalk.py --lookback_days 730 --top_n 50
python3 scripts/i2i_content_similar.py --top_n 50 --method hybrid

# 4. 兴趣聚合
python3 scripts/interest_aggregation.py --lookback_days 730 --top_n 1000

# 5. 加载到Redis
python3 scripts/load_index_to_redis.py --redis-host localhost

配置说明

主要配置在 config/offline_config.py

# 数据库配置
DB_CONFIG = {
    'host': 'your_db_host',
    'port': '9030',
    'database': 'datacenter',
    'username': 'readonly',
    'password': 'your_password'
}

# Redis配置
REDIS_CONFIG = {
    'host': 'your_redis_host',
    'port': 6379,
    'db': 0,
    'password': None
}

# 时间配置
LOOKBACK_DAYS = 730  # 2年数据

# 行为权重
behavior_weights = {
    'click': 1.0,
    'addToCart': 3.0,
    'contactFactory': 5.0,
    'purchase': 10.0
}

# 时间衰减
time_decay_factor = 0.95  # 每30天衰减5%

查看输出结果

所有输出文件在 output/ 目录:

cd /home/tw/recommendation/offline_tasks/output
ls -lh

# 查看i2i相似度
head -5 i2i_swing_20251016.txt

# 查看兴趣点聚合
head -5 interest_aggregation_hot_20251016.txt

查看日志

cd /home/tw/recommendation/offline_tasks/logs

# 主日志
tail -f run_all_20251016.log

# 内存监控日志
tail -f memory_monitor.log

# Debug日志
ls debug/

📊 输出数据示例

i2i相似度索引

C++ Swing(高性能版):

# 文件: collaboration/output/swing_similar.txt
3600052 2704531:0.00431593,2503886:0.00431593,3371410:0.00431593

# 可读版本: collaboration/output/swing_similar_readable.txt
3600052:商品A 2704531:商品B:0.00431593,2503886:商品C:0.00431593

Python Swing:

# 文件: output/i2i_swing_20251016.txt
12345   商品A 23456:0.8523,34567:0.7842,45678:0.7234

兴趣点聚合索引

# 文件: output/interest_aggregation_hot_20251016.txt
platform:pc 12345,23456,34567,45678,56789
category_level2:200 45678,56789,67890,78901,89012
platform_category2:pc_200   12345,23456,34567,45678

🎬 业务场景应用

场景1: 首页猜你喜欢

使用索引:

# 基于平台
interest:hot:platform:pc

# 基于分类偏好
interest:hot:category_level2:200

# 基于平台+分类
interest:hot:platform_category2:pc_200

场景2: 详情页相关推荐

使用索引:

# 行为相似(C++ Swing,生产推荐)
item:similar:swing_cpp:12345

# 行为相似(Python Swing)
item:similar:swing:12345

# 内容相似
item:similar:content_hybrid:12345

# 融合推荐(多算法)
swing_items = redis.get('item:similar:swing_cpp:12345')
w2v_items = redis.get('item:similar:w2v:12345')
content_items = redis.get('item:similar:content_hybrid:12345')
# 融合多个算法结果...

场景3: 搜索结果页推荐

使用索引:

# 全局热门
interest:global:platform:pc

# 分类相关
interest:global:category_level2:200

场景4: 供应商店铺页

使用索引:

# 供应商热门
interest:hot:supplier:10001

# 供应商新品
interest:new:supplier:10001

⚙️ 参数调优建议

Swing算法参数

alpha (0.5-1.0)

  • 越小:越关注用户共同行为的多样性
  • 越大:越容易忽略用户重叠度
  • B2B场景建议:0.5-0.7

threshold1/threshold2

  • threshold1: 筛选用户有效行为(建议1-3)
  • threshold2: 计算相似度阈值(建议3-5)
  • B2B低频场景可适当降低

thread_num

  • 根据CPU核心数设置
  • 建议:4-8(普通服务器)

数据范围参数

lookback_days

  • B2B低频场景:建议730天(2年)
  • B2C高频场景:建议30-90天
  • 数据量大时可适当减少

top_n

  • i2i相似度:建议10-50
  • 兴趣聚合:建议50-1000

🔧 故障排查

常见问题

Q1: 任务运行时间太长

  • 减少 --lookback_days 参数(如改为365天)
  • 减少 --top_n 参数
  • 在更强大的机器上运行
  • 使用C++ Swing代替Python Swing

Q2: 内存不足

  • Swing算法特别消耗内存,可以先跳过
  • 只运行DeepWalk或Session W2V
  • 对数据进行采样
  • 调整C++代码中的max_session_list_len和max_sim_list_len

Q3: 数据库连接超时

  • 检查数据库配置: config/offline_config.py
  • 测试连接: python3 test_connection.py
  • 检查网络和防火墙
  • 增加SQL查询超时时间

Q4: Session文件不存在

# 重新生成session文件
python3 scripts/generate_session.py --lookback_days 730

Q5: 编译失败(C++ Swing)

# 检查编译器
g++ --version

# 手动编译
cd collaboration
make clean
make

Q6: 结果为空

  • 降低threshold参数
  • 增加lookback_days
  • 检查数据量: wc -l output/session.txt.*

查看错误日志

# 查看最新日志
tail -100 logs/run_all_$(date +%Y%m%d).log

# 查看特定任务日志
tail -100 logs/debug/i2i_swing_*.log

# 搜索错误信息
grep -i "error" logs/run_all_*.log

📈 性能参考

在标准配置(730天数据,top_n=50)下的预估运行时间:

任务 数据量 预估时间 内存占用
C++ Swing 100万条行为 30-120分钟 4-8GB
Python Swing 100万条行为 2-4小时 4-8GB
Session W2V 100万条行为 30-60分钟 2-4GB
DeepWalk 100万条行为 1-2小时 2-4GB
内容相似度 5万商品 10-30分钟 1-2GB
兴趣点聚合 100万条行为 30-60分钟 2-4GB

总计: 约4-8小时(取决于数据量和机器配置)


🔄 定时任务设置

使用crontab

# 编辑crontab
crontab -e

# 每天凌晨2点运行(推荐)
0 2 * * * cd /home/tw/recommendation/offline_tasks && bash run.sh >> logs/cron_$(date +\%Y\%m\%d).log 2>&1

# 或者使用Python版本(不含C++ Swing和Redis加载)
0 2 * * * cd /home/tw/recommendation/offline_tasks && python3 run_all.py >> logs/cron_$(date +\%Y\%m\%d).log 2>&1

分任务调度

# 每天凌晨2点运行i2i算法
0 2 * * * cd /home/tw/recommendation/offline_tasks && python3 scripts/i2i_swing.py --lookback_days 730

# 每天凌晨4点运行兴趣聚合
0 4 * * * cd /home/tw/recommendation/offline_tasks && python3 scripts/interest_aggregation.py --lookback_days 730

# 每周日凌晨3点运行内容相似度(变化慢)
0 3 * * 0 cd /home/tw/recommendation/offline_tasks && python3 scripts/i2i_content_similar.py --top_n 50

📊 数据量统计

索引数量统计(基于400天数据)

索引类型 索引数量 单条平均大小 总大小 更新频率
i2i_deepwalk 48,376 ~780B 36MB 每天
i2i_session_w2v 50,990 ~840B 41MB 每天
i2i_content_name 127,720 ~830B 101MB 每周
i2i_content_pic 0 - 0 每周
i2i_item_behavior 178,775 ~750B 128MB 每天
interest_hot 14,001 ~520B 6.9MB 每天
interest_cart 15,563 ~670B 10MB 每天
interest_new 6,463 ~500B 3.1MB 每天
interest_global 17,533 ~660B 11MB 每天
tag_category_similar 708 ~930B 630KB 每周
总计 ~460,000 - ~338MB -

注:统计数据基于 2025-10-22 的实际输出文件

Redis内存占用

加载到Redis后的内存占用约 400MB(包含key开销和Redis数据结构开销)


💡 核心优势

1. 完整性

  • ✅ 行为相似 + 内容相似
  • ✅ 短期热门 + 长期稳定
  • ✅ 粗粒度 + 细粒度

2. 灵活性

  • ✅ 支持4级分类查询
  • ✅ 支持供应商维度
  • ✅ 支持多维度组合

3. 可扩展性

  • ✅ 易于添加新维度
  • ✅ 易于添加新算法
  • ✅ 配置化管理

4. 高性能

  • ✅ C++ Swing高性能实现
  • ✅ 前置任务减少数据库查询
  • ✅ 多线程并行处理

5. 实用性

  • ✅ 适配真实B2B数据
  • ✅ 文档完善
  • ✅ 易于维护

🎯 关键改进点总结

  1. ✅ 性能优化: 前置任务减少80-90%的数据库查询,C++ Swing提升10-100倍性能
  2. ✅ 架构优化: 前置任务解耦,数据准备与算法分离
  3. ✅ 功能增强: Swing算法支持日期维度,同时考虑用户整体和单日行为
  4. ✅ 集成优化: C++ Swing集成到统一流程,一键执行
  5. ✅ 文档规范: 统一管理,清晰索引
  6. ✅ 代码质量: 统一编码规范,完善错误处理

📝 相关文档

  1. 离线索引数据规范 (离线索引数据规范.md)

    • 任务输出数据的详细格式说明
    • 文件命名规范
    • 数据质量检查
  2. Redis数据规范 (Redis数据规范.md)

    • Redis Key规范
    • 数据加载流程
    • 查询示例
  3. 配置文件 (config/offline_config.py)

    • 数据库配置
    • Redis配置
    • 算法参数

📞 联系与支持

如有问题,请:

  1. 查看本文档的故障排查部分
  2. 查看日志文件: logs/
  3. 查看相关文档: doc/离线索引数据规范.mddoc/Redis数据规范.md
  4. 联系开发团队

文档版本: v1.1
最后更新: 2024-10-17