本文目录导读:

我来介绍几种PHP推荐算法的简单实现方案:
基于用户行为的协同过滤(最简单)
<?php
class SimpleRecommend {
private $userActions = [];
// 记录用户行为
public function recordAction($userId, $itemId, $action = 'view') {
$this->userActions[$userId][$itemId] = ($this->userActions[$userId][$itemId] ?? 0) + 1;
}
// 获取协同推荐
public function getRecommendations($userId, $limit = 5) {
$similarUsers = $this->findSimilarUsers($userId);
$recommendations = [];
foreach ($similarUsers as $similarUserId => $similarity) {
foreach ($this->userActions[$similarUserId] ?? [] as $itemId => $count) {
// 排除用户已交互过的项目
if (!isset($this->userActions[$userId][$itemId])) {
$recommendations[$itemId] = ($recommendations[$itemId] ?? 0) + $count * $similarity;
}
}
}
arsort($recommendations);
return array_slice(array_keys($recommendations), 0, $limit);
}
// 查找相似用户(基于共同行为)
private function findSimilarUsers($userId) {
$userItems = $this->userActions[$userId] ?? [];
$similarities = [];
foreach ($this->userActions as $otherUserId => $items) {
if ($otherUserId === $userId) continue;
$common = array_intersect_key($userItems, $items);
$similarity = count($common) / max(count($userItems), count($items), 1);
if ($similarity > 0) {
$similarities[$otherUserId] = $similarity;
}
}
arsort($similarities);
return $similarities;
}
}
// 使用示例
$recommender = new SimpleRecommend();
$recommender->recordAction(1, 'article_1', 'like');
$recommender->recordAction(1, 'article_2', 'view');
$recommender->recordAction(2, 'article_1', 'like');
$recommender->recordAction(2, 'article_3', 'view');
$recommendations = $recommender->getRecommendations(1);
print_r($recommendations);
?>
的推荐(基于标签)
<?php
class ContentBasedRecommend {
private $items = [];
private $userPreferences = [];
// 添加项目与标签
public function addItem($itemId, $tags) {
$this->items[$itemId] = $tags;
}
// 记录用户偏好
public function recordPreference($userId, $itemId, $rating = 1) {
$itemTags = $this->items[$itemId] ?? [];
foreach ($itemTags as $tag) {
$this->userPreferences[$userId][$tag] =
($this->userPreferences[$userId][$tag] ?? 0) + $rating;
}
}
// 获取内容推荐
public function getRecommendations($userId, $limit = 5) {
$preferences = $this->userPreferences[$userId] ?? [];
$scores = [];
foreach ($this->items as $itemId => $tags) {
$score = 0;
foreach ($tags as $tag) {
$score += $preferences[$tag] ?? 0;
}
if ($score > 0) {
$scores[$itemId] = $score / count($tags); // 归一化
}
}
arsort($scores);
return array_slice(array_keys($scores), 0, $limit);
}
}
// 使用示例
$recommender = new ContentBasedRecommend();
$recommender->addItem('news_1', ['technology', 'ai', 'programming']);
$recommender->addItem('news_2', ['sports', 'football']);
$recommender->addItem('news_3', ['technology', 'startup']);
$recommender->recordPreference(1, 'news_1', 5);
$recommender->recordPreference(1, 'news_3', 3);
$recommendations = $recommender->getRecommendations(1);
print_r($recommendations);
?>
简单的热门推荐
<?php
class PopularRecommend {
private $itemScores = [];
private $userHistory = [];
// 记录交互
public function recordInteraction($userId, $itemId, $weight = 1) {
$this->itemScores[$itemId] = ($this->itemScores[$itemId] ?? 0) + $weight;
$this->userHistory[$userId][$itemId] = true;
}
// 带时间衰减的热门推荐
public function getHotRecommendations($userId, $limit = 10, $days = 7) {
$recommendations = [];
$now = time();
foreach ($this->itemScores as $itemId => $score) {
// 排除用户已看过的
if (isset($this->userHistory[$userId][$itemId])) {
continue;
}
// 时间衰减
$timeDecay = exp(-($now - $this->getItemTime($itemId)) / (86400 * $days));
$recommendations[$itemId] = $score * $timeDecay;
}
arsort($recommendations);
return array_slice(array_keys($recommendations), 0, $limit);
}
private function getItemTime($itemId) {
// 实际项目中从数据库获取
return time();
}
}
// 使用示例
$recommender = new PopularRecommend();
$recommender->recordInteraction(1, 'video_1', 10);
$recommender->recordInteraction(1, 'video_2', 5);
$recommender->recordInteraction(2, 'video_1', 8);
$recommendations = $recommender->getHotRecommendations(1);
print_r($recommendations);
?>
组合推荐(混合推荐)
<?php
class HybridRecommend {
private $contentBased;
private $collaborative;
private $popular;
public function __construct() {
$this->contentBased = new ContentBasedRecommend();
$this->collaborative = new SimpleRecommend();
$this->popular = new PopularRecommend();
}
// 组合推荐结果
public function getHybridRecommendations($userId, $limit = 10) {
$weights = [
'content_based' => 0.4,
'collaborative' => 0.3,
'popular' => 0.3
];
$scores = [];
// 内容推荐
$contentRecs = $this->contentBased->getRecommendations($userId, $limit * 2);
foreach ($contentRecs as $index => $itemId) {
$scores[$itemId] = ($scores[$itemId] ?? 0) + $weights['content_based'] * ($limit - $index);
}
// 协同推荐
$collabRecs = $this->collaborative->getRecommendations($userId, $limit * 2);
foreach ($collabRecs as $index => $itemId) {
$scores[$itemId] = ($scores[$itemId] ?? 0) + $weights['collaborative'] * ($limit - $index);
}
// 热门推荐
$popularRecs = $this->popular->getHotRecommendations($userId, $limit * 2);
foreach ($popularRecs as $index => $itemId) {
$scores[$itemId] = ($scores[$itemId] ?? 0) + $weights['popular'] * ($limit - $index);
}
arsort($scores);
return array_slice(array_keys($scores), 0, $limit);
}
}
?>
使用Redis实现实时推荐
<?php
class RedisRecommend {
private $redis;
public function __construct() {
$this->redis = new Redis();
$this->redis->connect('127.0.0.1', 6379);
}
// 使用Redis的Sorted Set实现
public function recordAction($userId, $itemId, $score = 1) {
$this->redis->zIncrBy("user:{$userId}:actions", $score, $itemId);
$this->redis->zIncrBy("global:popular", $score, $itemId);
}
// 获取推荐
public function getRecommendations($userId, $limit = 5) {
// 获取用户行为历史
$userActions = $this->redis->zRevRange("user:{$userId}:actions", 0, -1, true);
// 获取全局热门
$popular = $this->redis->zRevRange("global:popular", 0, $limit * 2, true);
$recommendations = [];
foreach ($popular as $itemId => $score) {
if (!isset($userActions[$itemId])) {
$recommendations[$itemId] = $score;
}
if (count($recommendations) >= $limit) break;
}
return array_keys($recommendations);
}
}
?>
数据库存储示例(MySQL)
-- 用户行为表
CREATE TABLE user_actions (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
item_id VARCHAR(50) NOT NULL,
action_type VARCHAR(20) NOT NULL, -- view, like, purchase
weight DECIMAL(5,2) DEFAULT 1.00,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_item (user_id, item_id)
);
-- 项目标签表
CREATE TABLE item_tags (
id INT AUTO_INCREMENT PRIMARY KEY,
item_id VARCHAR(50) NOT NULL,
tag VARCHAR(50) NOT NULL,
weight DECIMAL(3,2) DEFAULT 1.00,
INDEX idx_item (item_id)
);
-- 计算用户相似度查询
SELECT
ua2.user_id as similar_user,
COUNT(*) as common_items,
SUM(ua1.weight * ua2.weight) as score
FROM user_actions ua1
JOIN user_actions ua2 ON ua1.item_id = ua2.item_id AND ua1.user_id != ua2.user_id
WHERE ua1.user_id = 1
GROUP BY ua2.user_id
ORDER BY score DESC
LIMIT 5;
这些简单的实现适合小型项目快速上手,对于生产环境,建议考虑使用专门的推荐系统框架或使用MySQL+Redis的混合存储方案。