1. 体育商城推荐系统架构设计
在体育用品电商平台中,商品推荐系统是提升用户体验和转化率的核心组件。我们基于PHP生态的ThinkPHP和Laravel框架,实现了两种不同风格的协同过滤推荐方案。整个系统采用典型的三层架构:
- 表现层:Vue.js构建的响应式前端界面,处理用户交互和推荐结果展示
- 业务逻辑层:PHP实现的推荐算法核心,包括用户行为分析、相似度计算和推荐生成
- 数据访问层:MySQL存储用户行为数据和商品信息,Redis缓存相似度矩阵
提示:体育商品具有明显的季节性和运动场景特征,在数据收集阶段需要特别关注用户行为的时间戳和商品属性关联。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 协同过滤算法深度解析
2.1 用户行为数据建模
体育商城用户行为数据通常包括:
php复制// 典型用户-商品交互数据结构
$userBehavior = [
'user_id' => 1001,
'actions' => [
[
'item_id' => 'SP001', // 商品ID
'type' => 'view', // 行为类型:view/purchase/cart
'score' => 1, // 隐式评分
'timestamp' => 1640995200
],
// 其他行为记录...
]
];
行为权重分配建议:
- 购买:5分
- 加入购物车:3分
- 收藏:2分
- 浏览:1分
2.2 相似度计算优化
原始皮尔逊相关系数在体育商品场景下需要加入时间衰减因子:
php复制// 带时间衰减的相似度计算
public function timeWeightedSimilarity($user1, $user2) {
$commonItems = $this->getCommonItems($user1, $user2);
$numerator = $denominator1 = $denominator2 = 0;
foreach ($commonItems as $item) {
$timeDiff = abs($user1->actions[$item]['time'] - $user2->actions[$item]['time']);
$timeWeight = exp(-0.0005 * $timeDiff); // λ=0.0005
$diff1 = $user1->ratings[$item] - $user1->avgRating;
$diff2 = $user2->ratings[$item] - $user2->avgRating;
$numerator += $timeWeight * $diff1 * $diff2;
$denominator1 += $timeWeight * pow($diff1, 2);
$denominator2 += $timeWeight * pow($diff2, 2);
}
return $denominator1 * $denominator2 > 0
? $numerator / (sqrt($denominator1) * sqrt($denominator2))
: 0;
}
3. ThinkPHP实现方案
3.1 数据层设计
php复制// 用户模型定义
class User extends Model
{
protected $table = 'sports_users';
// 用户行为关联
public function behaviors()
{
return $this->hasMany('Behavior', 'user_id');
}
// 获取相似用户
public function similarUsers($limit = 5)
{
$similarityService = new SimilarityService();
return $similarityService->calculateForUser($this->id, $limit);
}
}
3.2 推荐生成策略
ThinkPHP推荐服务核心逻辑:
php复制class RecommendationService
{
protected $redis;
public function __construct() {
$this->redis = new \Redis();
$this->redis->connect('127.0.0.1', 6379);
}
public function generateForUser($userId, $size = 10) {
// 从Redis获取相似用户列表
$similarUsers = json_decode($this->redis->get("user:similar:$userId"), true);
$recommendations = [];
foreach ($similarUsers as $similar) {
$neighborId = $similar['user_id'];
$similarity = $similar['score'];
// 获取邻居用户的高分商品
$neighborItems = $this->getTopRatedItems($neighborId);
foreach ($neighborItems as $item) {
if (!$this->hasInteracted($userId, $item['id'])) {
$weightedScore = $similarity * ($item['rating'] - $similar['avg_rating']);
$recommendations[$item['id']] += $weightedScore;
}
}
}
arsort($recommendations);
return array_slice($recommendations, 0, $size, true);
}
}
4. Laravel实现方案
4.1 队列异步处理
在Laravel中,我们使用队列系统处理耗时的相似度计算:
php复制// 计算任务分发
class SimilarityController extends Controller
{
public function updateSimilarities()
{
$userIds = User::pluck('id');
foreach ($userIds as $userId) {
CalculateUserSimilarity::dispatch($userId)
->onQueue('recommendation');
}
}
}
// 队列任务处理
class CalculateUserSimilarity implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $userId;
public function __construct($userId) {
$this->userId = $userId;
}
public function handle() {
$targetUser = User::with('behaviors')->find($this->userId);
$allUsers = User::where('id', '!=', $this->userId)->get();
$similarities = [];
foreach ($allUsers as $user) {
$similarity = $this->calculator->calculate($targetUser, $user);
$similarities[] = [
'user_id' => $user->id,
'score' => $similarity
];
}
usort($similarities, function($a, $b) {
return $b['score'] <=> $a['score'];
});
Cache::put("user:similar:{$this->userId}",
json_encode(array_slice($similarities, 0, 50)),
now()->addHours(6));
}
}
4.2 混合推荐策略
当协同过滤数据不足时,切换到基于内容的推荐:
php复制class HybridRecommender
{
public function recommend($userId, $size = 10) {
try {
// 尝试协同过滤推荐
$cfRecommendations = $this->cfService->generateForUser($userId, $size);
if (count($cfRecommendations) >= $size) {
return $cfRecommendations;
}
// 不足时补充内容推荐
$contentBased = $this->contentService->recommend($userId, $size - count($cfRecommendations));
return array_merge($cfRecommendations, $contentBased);
} catch (RecommendationException $e) {
// 降级到热门商品推荐
return $this->fallbackService->hotItems($size);
}
}
}
5. 性能优化实战
5.1 相似度矩阵缓存
采用Redis存储用户相似度关系:
- 使用有序集合(zset)存储每个用户的相似用户列表
- 设置6小时自动过期,平衡实时性和性能
- 内存优化策略:
php复制// 压缩存储相似度数据
$compressed = gzcompress(json_encode($similarities));
$this->redis->setex("user:similar:$userI
