本文目录导读:

在PHP项目中实现用户偏好学习,可以从简单的规则引擎开始,逐步过渡到更复杂的机器学习方案,以下是几种实用且可落地的实现路径:
基于规则的偏好记录(初级方案)
数据层设计
// 用户偏好表结构
CREATE TABLE user_preferences (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
preference_key VARCHAR(50) NOT NULL,
preference_value TEXT,
weight DECIMAL(5,2) DEFAULT 1.0, // 权重
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY unique_user_pref (user_id, preference_key)
);
// 用户行为日志表
CREATE TABLE user_behavior_logs (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
action_type VARCHAR(50) NOT NULL, // view, click, purchase, etc.
target_type VARCHAR(50) NOT NULL, // article, product, category
target_id INT NOT NULL,
duration_seconds INT DEFAULT 0,
score DECIMAL(5,2) DEFAULT 1.0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_action (user_id, action_type)
);
基础偏好收集器
class PreferenceCollector {
private $db;
public function collectPreference($userId, $actionType, $targetType, $targetId, $score = 1.0) {
// 记录行为日志
$this->db->insert('user_behavior_logs', [
'user_id' => $userId,
'action_type' => $actionType,
'target_type' => $targetType,
'target_id' => $targetId,
'score' => $score
]);
// 更新偏好权重
$preferenceKey = "pref_{$targetType}_{$targetId}";
$currentWeight = $this->getCurrentWeight($userId, $preferenceKey);
$newWeight = $this->calculateNewWeight($currentWeight, $score);
$this->db->onDuplicateKeyUpdate('user_preferences', [
'user_id' => $userId,
'preference_key' => $preferenceKey,
'preference_value' => $targetId,
'weight' => $newWeight
]);
}
private function calculateNewWeight($currentWeight, $score) {
// 指数衰减算法
$learningRate = 0.1; // 学习率
return $currentWeight + $learningRate * ($score - $currentWeight);
}
}
协同过滤推荐(中级方案)
基于物品的协同过滤
class CollaborativeFiltering {
private $db;
public function getRecommendations($userId, $limit = 10) {
// 获取用户已交互的物品
$userItems = $this->getUserItems($userId);
// 计算物品相似度矩阵(可缓存在Redis)
$itemSimilarities = $this->getItemSimilarities();
// 生成推荐
$scores = [];
foreach ($userItems as $itemId => $rating) {
if (isset($itemSimilarities[$itemId])) {
foreach ($itemSimilarities[$itemId] as $similarItem => $similarity) {
if (!isset($userItems[$similarItem])) {
$scores[$similarItem] = ($scores[$similarItem] ?? 0)
+ $rating * $similarity;
}
}
}
}
// 排序并返回
arsort($scores);
return array_slice(array_keys($scores), 0, $limit);
}
private function getItemSimilarities() {
// 从缓存或数据库中获取物品相似度矩阵
// 可以使用Jaccard相似度或余弦相似度
$cache = new RedisCache();
$matrix = $cache->get('item_similarity_matrix');
if (!$matrix) {
$matrix = $this->calculateItemSimilarities();
$cache->set('item_similarity_matrix', $matrix, 3600); // 缓存1小时
}
return json_decode($matrix, true);
}
}
使用PHP-ML库实现机器学习(高级方案)
安装PHP-ML
composer require php-ai/php-ml
朴素贝叶斯分类器实现内容推荐
use Phpml\Classification\NaiveBayes;
use Phpml\FeatureExtraction\TfIdfTransformer;
use Phpml\Tokenization\WhitespaceTokenizer;
class ContentPreferenceLearner {
private $classifier;
private $tokenizer;
private $transformer;
public function __construct() {
$this->classifier = new NaiveBayes();
$this->tokenizer = new WhitespaceTokenizer();
$this->transformer = new TfIdfTransformer();
}
public function train(array $trainingData) {
// $trainingData = ['user_id' => ['preferred_contents' => [...], 'non_preferred' => [...]]]
$samples = [];
$labels = [];
foreach ($trainingData as $userId => $data) {
foreach ($data as $category => $contents) {
foreach ($contents as $content) {
$samples[] = $this->preprocessText($content);
$labels[] = $category;
}
}
}
$this->classifier->train($samples, $labels);
}
public function predictPreference($content) {
$processed = $this->preprocessText($content);
return $this->classifier->predict([$processed])[0];
}
private function preprocessText($text) {
// 简单的文本预处理
$tokens = $this->tokenizer->tokenize($text);
// 可以添加停用词过滤、词干提取等
return implode(' ', array_slice($tokens, 0, 100)); // 取前100个词
}
}
实时偏好调整与反馈循环
动态权重调整系统
class AdaptivePreferenceSystem {
private $collector;
private $feedbackLoop;
public function adjustPreferences($userId, $recommendationId, $userAction) {
// 用户反馈(点击/忽略/负面反馈)
$feedbackScore = match($userAction) {
'click' => 1.0,
'purchase' => 2.0,
'like' => 1.5,
'dismiss' => -0.5,
'report_irrelevant' => -2.0,
default => 0
};
// 更新用户偏好
$this->collector->collectPreference(
$userId,
$userAction,
'recommendation',
$recommendationId,
$feedbackScore
);
// 检查是否需要重新训练模型
$this->checkRetrainThreshold($userId);
}
private function checkRetrainThreshold($userId) {
$recentActions = $this->collector->getRecentActionCount($userId, 3600); // 1小时内
if ($recentActions >= 10) { // 每10个新动作重新训练
$this->retrainUserModel($userId);
}
}
}
生产环境最佳实践
缓存策略
class PreferenceCache {
private $redis;
public function getCachedRecommendations($userId) {
$cacheKey = "recommendations:{$userId}";
$cached = $this->redis->get($cacheKey);
if ($cached && !$this->isExpired($cached)) {
return json_decode($cached, true);
}
// 异步重新计算
$this->queueRecalculation($userId);
return $cached ? json_decode($cached, true) : [];
}
private function isExpired($cached) {
$data = json_decode($cached, true);
return time() - ($data['generated_at'] ?? 0) > 3600; // 1小时过期
}
}
混合推荐策略
class HybridRecommender {
private $contentBased;
private $collaborative;
private $popularity;
public function getHybridRecommendations($userId, $limit = 20) {
$contentBased = $this->contentBased->getRecommendations($userId, $limit);
$collaborative = $this->collaborative->getRecommendations($userId, $limit);
$popular = $this->popularity->getTrending($limit);
// 加权融合
$weights = [
'content_based' => 0.4,
'collaborative' => 0.4,
'popularity' => 0.2
];
$scored = [];
foreach ([$contentBased, $collaborative, $popular] as $idx => $items) {
foreach ($items as $item) {
$scored[$item['id']] = ($scored[$item['id']] ?? 0) + $weights[$idx];
}
}
arsort($scored);
return array_slice(array_keys($scored), 0, $limit);
}
}
性能优化建议
- 异步处理:将偏好计算放入消息队列(RabbitMQ/Redis Queue)
- 批量更新:聚合用户行为后批量更新数据库
- 预计算:定期离线计算推荐结果
- 分层存储:热数据存Redis,冷数据存MySQL
- A/B测试:预留对比实验接口
注意事项
- 冷启动问题:对新用户使用热门推荐或引导式偏好选择
- 隐私保护:遵守GDPR等法规,提供偏好退出的选项
- 可解释性:提供推荐原因(如“因为您喜欢XX”)
- 反馈循环:监控推荐效果指标(点击率、转化率)
这个方案可以根据你的项目规模和资源逐步实施,从最简单的规则系统开始,不断迭代优化。