发布日期:2024年2月5日
一、系统架构设计
本教程将实现一个完整的智能推荐电商系统,包含以下核心模块:
- 用户画像系统:基于行为的标签化用户建模
- 推荐引擎:协同过滤与内容推荐算法
- 实时计算:Redis+PHP实时数据处理
- AB测试框架:推荐策略效果对比
- 可视化看板:推荐效果监控
技术栈:ThinkPHP8.1 + Redis + Swoole + Python机器学习
二、环境准备与项目初始化
1. 基础环境配置
# 安装ThinkPHP8
composer create-project topthink/think recommend-system
cd recommend-system
# 安装扩展
composer require predis/predis guzzlehttp/guzzle
2. 目录结构设计
app/
├── algorithm/ # 推荐算法
├── service/ # 业务服务
├── controller/ # 控制器
├── model/ # 数据模型
├── job/ # 异步任务
├── middleware/ # 中间件
config/
├── recommend.php # 推荐配置
extend/
├── phpredis/ # Redis扩展
public/
├── py/ # Python脚本
runtime/
├── logs/ # 推荐日志
三、用户画像系统实现
1. 用户行为追踪
// 用户行为日志中间件
class UserBehavior
{
public function handle($request, Closure $next)
{
$response = $next($request);
if ($user = session('user')) {
$log = [
'user_id' => $user['id'],
'path' => $request->path(),
'item_id' => $request->param('item_id'),
'time' => time()
];
// 异步写入Redis
thinkQueue::push('appjobUserLog', $log);
}
return $response;
}
}
2. 标签计算服务
// 用户标签服务
class TagService
{
public function updateUserTags($userId)
{
// 获取最近30天行为数据
$logs = Redis::zRange("user:{$userId}:logs", 0, -1);
// 计算标签权重
$tags = [];
foreach ($logs as $log) {
$data = json_decode($log, true);
$itemTags = $this->getItemTags($data['item_id']);
foreach ($itemTags as $tag => $weight) {
$tags[$tag] = ($tags[$tag] ?? 0) + $weight;
}
}
// 存储到Redis
Redis::hMSet("user:{$userId}:tags", $tags);
}
protected function getItemTags($itemId)
{
// 从数据库获取商品标签
return Item::find($itemId)->tags;
}
}
四、推荐算法集成
1. 基于用户的协同过滤
class UserCF
{
public function recommend($userId, $size = 10)
{
// 获取相似用户
$similarUsers = $this->findSimilarUsers($userId);
// 合并推荐商品
$recommendations = [];
foreach ($similarUsers as $user => $score) {
$items = Redis::sMembers("user:{$user}:items");
foreach ($items as $item) {
if (!Redis::sIsMember("user:{$userId}:items", $item)) {
$recommendations[$item] = ($recommendations[$item] ?? 0) + $score;
}
}
}
// 按评分排序
arsort($recommendations);
return array_slice($recommendations, 0, $size, true);
}
protected function findSimilarUsers($userId)
{
// 使用Python计算相似度
$result = shell_exec("python3 extend/similarity.py user {$userId}");
return json_decode($result, true);
}
}
2. 实时推荐服务
class RecommendService
{
public function getRecommendations($userId)
{
// 检查缓存
if ($cache = Redis::get("user:{$userId}:recommend")) {
return json_decode($cache, true);
}
// 混合推荐策略
$results = [
'cf' => $this->userCF->recommend($userId, 20),
'content' => $this->contentBased->recommend($userId, 20),
'hot' => $this->hotItems->get(20)
];
// 合并结果
$recommendations = $this->mergeResults($results);
// 缓存1小时
Redis::setex("user:{$userId}:recommend", 3600, json_encode($recommendations));
return $recommendations;
}
}
五、高性能优化方案
1. Redis内存优化
// 使用Redis管道批量处理
public function batchUpdateUserTags($userIds)
{
$pipe = Redis::pipeline();
foreach ($userIds as $userId) {
$pipe->zUnionStore("temp:{$userId}", [
"user:{$userId}:view",
"user:{$userId}:cart",
"user:{$userId}:buy"
], ['WEIGHTS' => [1, 3, 5]]);
$pipe->expire("temp:{$userId}", 3600);
}
$pipe->execute();
}
// 使用Lua脚本原子操作
$lua = <<<LUA
local key = KEYS[1]
local item = ARGV[1]
local score = ARGV[2]
redis.call('ZADD', key, score, item)
redis.call('ZREMRANGEBYRANK', key, 0, -100)
return true
LUA;
Redis::eval($lua, 1, "hot:items", $itemId, time());
2. Swoole协程加速
// 并发获取推荐结果
public function parallelRecommend($userId)
{
$swoole = new SwooleCoroutineScheduler;
$results = [];
$swoole->add(function() use ($userId, &$results) {
$results['cf'] = Coroutine::exec("python3 cf.py {$userId}");
$results['cb'] = Coroutine::exec("python3 content_based.py {$userId}");
});
$swoole->start();
return $results;
}
六、AB测试框架实现
1. 实验分组服务
class ABTestService
{
public function getRecommendStrategy($userId)
{
// 使用一致性哈希分配实验组
$group = $this->hashGroup($userId);
$strategies = [
'A' => ['cf' => 0.7, 'content' => 0.3],
'B' => ['cf' => 0.5, 'content' => 0.5],
'C' => ['cf' => 0.3, 'content' => 0.7]
];
return $strategies[$group] ?? $strategies['A'];
}
protected function hashGroup($userId)
{
$hash = crc32($userId) % 100;
if ($hash < 30) return 'A';
if ($hash < 60) return 'B';
return 'C';
}
}
2. 效果追踪中间件
class TrackRecommend
{
public function handle($request, Closure $next)
{
$response = $next($request);
if ($request->param('rec_source')) {
$log = [
'user_id' => session('user.id'),
'item_id' => $request->param('item_id'),
'source' => $request->param('rec_source'),
'position' => $request->param('rec_pos'),
'click_time' => time()
];
Db::name('recommend_log')->insert($log);
}
return $response;
}
}
七、项目部署与监控
1. 生产环境部署
# 使用Supervisor管理进程
[program:recommend_worker]
command=php think queue:work --queue recommend
numprocs=4
autostart=true
autorestart=true
# Nginx配置
location ~ .php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location /py/ {
proxy_pass http://python-server;
}
2. 监控看板实现
class DashboardController
{
public function recommendMetrics()
{
// CTR计算
$ctr = Db::name('recommend_log')
->field('source, COUNT(*) as impressions,
SUM(IF(click_time>0,1,0)) as clicks')
->group('source')
->select();
// 转化率计算
$cvr = Db::name('recommend_log r')
->join('orders o', 'r.user_id=o.user_id AND r.item_id=o.item_id')
->field('r.source, COUNT(*) as clicks,
SUM(IF(o.id>0,1,0)) as conversions')
->group('r.source')
->select();
return json(['ctr' => $ctr, 'cvr' => $cvr]);
}
}
八、总结与扩展
通过本教程,我们完成了:
- 基于ThinkPHP8的推荐系统架构
- 用户画像与行为分析实现
- 多种推荐算法集成
- 高性能优化方案
- AB测试与效果监控
扩展方向:
- 深度学习推荐模型集成
- 实时流处理架构升级
- 跨平台用户行为收集
- 自动化策略调优系统