广东烟草项目

Sherlock bdac27e161 增加上传文件流的相关配置 1 tuần trước cách đây
api 75642c90ce refactor(api): add logging and error handling to all endpoints 3 tuần trước cách đây
config a35bba88b6 refactor: add logging to utils/train, secure config, create .env.example 3 tuần trước cách đây
core bdac27e161 增加上传文件流的相关配置 1 tuần trước cách đây
data 7de36e222d 过滤订单表中已经歇业的商户数据 1 năm trước cách đây
database b92be3efd9 refactor: improve DAO logging, rewrite run_api with middleware and health check 3 tuần trước cách đây
docs 89ebb90f13 docs: 添加项目重构实现计划 3 tuần trước cách đây
models bdac27e161 增加上传文件流的相关配置 1 tuần trước cách đây
utils bdac27e161 增加上传文件流的相关配置 1 tuần trước cách đây
.env.example bdac27e161 增加上传文件流的相关配置 1 tuần trước cách đây
.gitignore a35bba88b6 refactor: add logging to utils/train, secure config, create .env.example 3 tuần trước cách đây
Dockerfile 920579945f 根据新数据修改gbdt-lr流程 1 năm trước cách đây
README.md 2f0a0a565a docs: 添加 README.md 说明环境配置和功能启动 3 tuần trước cách đây
Readme.md bdac27e161 增加上传文件流的相关配置 1 tuần trước cách đây
api_test.py bdac27e161 增加上传文件流的相关配置 1 tuần trước cách đây
crontab 920579945f 根据新数据修改gbdt-lr流程 1 năm trước cách đây
report.py 79970d27ad 将报告生成功能添加的后台服务中 1 năm trước cách đây
requirements.txt 0ba77eb49f 更新环境安装包 1 năm trước cách đây
run_api.py b92be3efd9 refactor: improve DAO logging, rewrite run_api with middleware and health check 3 tuần trước cách đây
test.py a1451c087b 封装一体化部署流程 1 năm trước cách đây
train.py a35bba88b6 refactor: add logging to utils/train, secure config, create .env.example 3 tuần trước cách đây
烟草模型部署文档.md 920579945f 根据新数据修改gbdt-lr流程 1 năm trước cách đây

README.md

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