README.md 5.7 KB

BrandCultivation 卷烟品牌培育推荐系统

基于协同过滤、Item2Vec 和 GBDT-LR 的卷烟品牌培育商户推荐系统,提供品规-商户匹配推荐、投放量分配、效果验证等功能。

目录结构

BrandCultivation/
├── core/                    # 基础设施层(日志、配置、异常、中间件)
├── api/                     # FastAPI 路由层
├── database/                # 数据访问层(MySQL DAO + Redis)
├── models/                  # ML 模型(Item2Vec、ItemCF、GBDT-LR)
├── utils/                   # 工具类(文件上传、报告生成)
├── config/                  # 配置文件(YAML)
├── run_api.py               # API 服务入口
├── train.py                 # 模型训练入口
├── requirements.txt         # Python 依赖
└── .env.example             # 环境变量模板

环境要求

  • Python 3.10+
  • MySQL 5.7+
  • Redis 5.0+

安装

# 克隆项目
git clone <repo-url>
cd BrandCultivation

# 创建虚拟环境
conda create -n recommend python=3.10
conda activate recommend

# 安装依赖
pip install -r requirements.txt

配置

环境变量

复制 .env.example.env,填入实际值:

cp .env.example .env

必须配置的环境变量:

变量 说明 示例
MYSQL_HOST MySQL 主机地址 rm-xxx.mysql.rds.aliyuncs.com
MYSQL_PORT MySQL 端口 3036
MYSQL_USER MySQL 用户名 BrandCultivation
MYSQL_PASSWORD MySQL 密码 (必填)
MYSQL_DB 数据库名 brand_cultivation
REDIS_HOST Redis 主机地址 r-xxx.redis.rds.aliyuncs.com
REDIS_PORT Redis 端口 5000
REDIS_PASSWORD Redis 密码 (必填)
REDIS_DB Redis 数据库编号 10
LOG_LEVEL 日志级别 INFO(默认)
FILE_UPLOAD_URL 文件上传服务地址 http://file-center.jcpt:8080/file/fileUpload
FILE_DOWNLOAD_URL 文件下载服务地址 http://file-center.jcpt:8080/file/fileDownload

如果不使用 .env 文件,也可以直接 export 环境变量:

export MYSQL_PASSWORD='your_password'
export REDIS_PASSWORD='your_password'

YAML 配置

非敏感配置保留在 config/ 目录下的 YAML 文件中,环境变量优先级高于 YAML。

运行

启动 API 服务

python run_api.py

服务启动后监听 0.0.0.0:7960,可通过以下方式验证:

# 健康检查
curl http://localhost:7960/health

# 预期返回
# {"status":"healthy","mysql":"ok","redis":"ok"}

也可以使用 uvicorn 直接启动(支持热重载):

uvicorn run_api:app --host 0.0.0.0 --port 7960 --reload

模型训练

训练前确保 MySQL 和 Redis 均可连接。

# 完整训练(协同过滤 + 热度召回 + GBDT-LR)
python train.py --run_train --city_uuid 00000000000000000000000011445301

# 仅训练召回模型(协同过滤 + 热度召回)
python train.py --run_recall --city_uuid 00000000000000000000000011445301

# 仅训练排序模型(GBDT-LR)
python train.py --run_gbdtlr --city_uuid 00000000000000000000000011445301

训练参数:

参数 说明 默认值
--city_uuid 城市 UUID 00000000000000000000000011445301
--train_data_dir 训练数据保存目录 ./data/gbdt
--model_path 模型权重保存目录 ./models/rank/weights
--largest_n ItemCF 热度 Top N 300
--similarity_k ItemCF 相似商户数 100
--top_n ItemCF 推荐候选数 1500
--n_jobs 并行计算线程数 2

API 接口

基础路径:/brandcultivation/api/v1

POST /recommend

生成商户推荐列表并分配投放量。

请求体:

{
    "city_uuid": "00000000000000000000000011445301",
    "product_code": "440298",
    "recall_cust_count": 500,
    "delivery_count": 5000,
    "cultivacation_id": "10000001",
    "limit_cycle_name": "202505W1(05.05-05.11)"
}

响应:

{
    "code": 200,
    "msg": "success",
    "data": {
        "recommendationInfo": [
            {"id": 1, "cust_code": "445300108802", "recommend_score": 95.3, "delivery_count": 120}
        ]
    }
}

POST /report

获取推荐相关报告文件 ID。

请求体:

{
    "cultivacation_id": "10000001"
}

POST /eval_report

生成投放效果验证报告。

请求体:

{
    "city_uuid": "00000000000000000000000011445301",
    "product_code": "440298",
    "cultivacation_id": "10000001",
    "start_time": "2025/2/10",
    "end_time": "2025/2/16"
}

GET /health

健康检查,返回 MySQL 和 Redis 连接状态。

日志

系统使用 JSON 格式日志输出到 stdout,每条日志包含:

{
    "timestamp": "2026-05-21T03:35:48.869426+00:00",
    "level": "INFO",
    "module": "recommend",
    "function": "recommend",
    "line": 18,
    "message": "Recommend request: city=xxx, product=440298, recall=500",
    "request_id": "a1b2c3d4"
}

通过 LOG_LEVEL 环境变量控制日志级别(DEBUG / INFO / WARNING / ERROR)。

API 请求会自动生成 request_id,贯穿整个请求链路,方便问题追踪。响应头中也会返回 X-Request-ID

Docker 部署

FROM python:3.10-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

ENV MYSQL_PASSWORD=""
ENV REDIS_PASSWORD=""
ENV LOG_LEVEL=INFO

EXPOSE 7960
CMD ["python", "run_api.py"]
docker build -t brand-cultivation .
docker run -d \
    -p 7960:7960 \
    -e MYSQL_PASSWORD='your_password' \
    -e REDIS_PASSWORD='your_password' \
    brand-cultivation