文章目录[隐藏]
实战教程:为WordPress网站集成智能化的用户行为分析与个性化推荐引擎
引言:智能化网站运营的必要性
在当今互联网竞争日益激烈的环境下,网站运营已从简单的信息发布转变为以用户体验为核心的智能化运营。据统计,采用个性化推荐系统的网站平均能提升30%的用户参与度和20%的转化率。然而,许多中小型网站由于技术门槛和成本限制,难以享受到智能化运营带来的红利。
本教程将详细指导您如何通过WordPress代码二次开发,为您的网站集成用户行为分析与个性化推荐引擎,实现常用互联网小工具功能。无论您是WordPress开发者、网站管理员还是对网站智能化感兴趣的技术爱好者,都能通过本教程掌握实用技能,将您的网站提升到新的智能化水平。
第一部分:系统架构设计与技术选型
1.1 整体架构设计
为WordPress网站集成智能化功能,我们需要设计一个模块化、可扩展的系统架构:
- 数据采集层:负责收集用户行为数据
- 数据处理层:清洗、存储和分析用户数据
- 推荐算法层:基于用户行为生成个性化推荐
- 前端展示层:将推荐结果以友好方式展示给用户
1.2 技术选型与工具准备
我们将使用以下技术和工具:
- WordPress:作为基础CMS平台
- PHP 7.4+:主要开发语言
- MySQL 5.7+:数据存储
- JavaScript/jQuery:前端交互与数据采集
- Redis:缓存与实时数据处理(可选)
- Python:复杂算法处理(可选,通过API集成)
1.3 开发环境搭建
在开始开发前,请确保您的环境满足以下要求:
- 本地或服务器安装WordPress 5.0+
- PHP环境支持mysqli扩展和JSON处理
- MySQL数据库已创建
- 代码编辑器(如VS Code、PHPStorm等)
- 浏览器开发者工具用于调试
第二部分:用户行为数据采集系统开发
2.1 设计用户行为数据模型
首先,我们需要设计合理的数据结构来存储用户行为数据。在WordPress数据库中创建自定义表:
CREATE TABLE wp_user_behavior (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
user_id BIGINT(20) UNSIGNED DEFAULT NULL,
session_id VARCHAR(64) NOT NULL,
post_id BIGINT(20) UNSIGNED DEFAULT NULL,
behavior_type ENUM('view', 'click', 'like', 'share', 'comment', 'purchase') NOT NULL,
behavior_data TEXT,
referrer VARCHAR(500),
user_agent TEXT,
ip_address VARCHAR(45),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
INDEX idx_user_id (user_id),
INDEX idx_post_id (post_id),
INDEX idx_behavior_type (behavior_type),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
2.2 创建数据采集插件
接下来,创建一个WordPress插件来采集用户行为数据:
<?php
/**
* Plugin Name: 智能用户行为分析系统
* Description: 采集和分析用户行为数据,为个性化推荐提供支持
* Version: 1.0.0
* Author: 您的名称
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
class Intelligent_Behavior_Analysis {
private static $instance = null;
private $table_name;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
global $wpdb;
$this->table_name = $wpdb->prefix . 'user_behavior';
// 初始化钩子
add_action('init', array($this, 'init_session'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
add_action('wp_footer', array($this, 'add_tracking_code'));
add_action('wp_ajax_track_behavior', array($this, 'track_behavior_ajax'));
add_action('wp_ajax_nopriv_track_behavior', array($this, 'track_behavior_ajax'));
// 文章浏览追踪
add_action('wp', array($this, 'track_post_view'));
}
// 初始化用户会话
public function init_session() {
if (!session_id() && !headers_sent()) {
session_start();
}
if (!isset($_SESSION['user_session_id'])) {
$_SESSION['user_session_id'] = $this->generate_session_id();
}
}
// 生成会话ID
private function generate_session_id() {
return md5(uniqid(mt_rand(), true) . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']);
}
// 加载前端脚本
public function enqueue_scripts() {
wp_enqueue_script(
'behavior-tracker',
plugin_dir_url(__FILE__) . 'js/behavior-tracker.js',
array('jquery'),
'1.0.0',
true
);
wp_localize_script('behavior-tracker', 'behaviorTracker', array(
'ajax_url' => admin_url('admin-ajax.php'),
'session_id' => isset($_SESSION['user_session_id']) ? $_SESSION['user_session_id'] : '',
'user_id' => is_user_logged_in() ? get_current_user_id() : 0
));
}
// 追踪文章浏览
public function track_post_view() {
if (is_single() || is_page()) {
global $post;
$user_id = is_user_logged_in() ? get_current_user_id() : 0;
$session_id = isset($_SESSION['user_session_id']) ? $_SESSION['user_session_id'] : '';
$this->save_behavior(array(
'user_id' => $user_id,
'session_id' => $session_id,
'post_id' => $post->ID,
'behavior_type' => 'view',
'referrer' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '',
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'ip_address' => $this->get_client_ip()
));
}
}
// AJAX处理行为追踪
public function track_behavior_ajax() {
check_ajax_referer('behavior_tracking_nonce', 'nonce');
$data = array(
'user_id' => intval($_POST['user_id']),
'session_id' => sanitize_text_field($_POST['session_id']),
'post_id' => isset($_POST['post_id']) ? intval($_POST['post_id']) : null,
'behavior_type' => sanitize_text_field($_POST['behavior_type']),
'behavior_data' => isset($_POST['behavior_data']) ? sanitize_textarea_field($_POST['behavior_data']) : '',
'referrer' => isset($_POST['referrer']) ? sanitize_text_field($_POST['referrer']) : '',
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '',
'ip_address' => $this->get_client_ip()
);
$result = $this->save_behavior($data);
if ($result) {
wp_send_json_success(array('message' => '行为记录成功'));
} else {
wp_send_json_error(array('message' => '行为记录失败'));
}
}
// 保存行为数据到数据库
private function save_behavior($data) {
global $wpdb;
// 防止过于频繁的记录(同一用户同一内容30秒内不重复记录)
$cache_key = 'behavior_' . md5(serialize($data));
if (get_transient($cache_key)) {
return false;
}
set_transient($cache_key, true, 30);
return $wpdb->insert(
$this->table_name,
$data,
array('%d', '%s', '%d', '%s', '%s', '%s', '%s', '%s')
);
}
// 获取客户端IP
private function get_client_ip() {
$ip_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR');
foreach ($ip_keys as $key) {
if (array_key_exists($key, $_SERVER) === true) {
foreach (explode(',', $_SERVER[$key]) as $ip) {
$ip = trim($ip);
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
return $ip;
}
}
}
}
return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
}
// 添加追踪代码到页脚
public function add_tracking_code() {
?>
<script type="text/javascript">
// 非敏感数据追踪代码
console.log('智能行为分析系统已加载');
</script>
<?php
}
}
// 初始化插件
Intelligent_Behavior_Analysis::get_instance();
2.3 前端行为追踪JavaScript
创建js/behavior-tracker.js文件:
(function($) {
'use strict';
// 全局配置
const BehaviorTracker = {
config: {
ajax_url: behaviorTracker.ajax_url,
session_id: behaviorTracker.session_id,
user_id: behaviorTracker.user_id,
nonce: behaviorTracker.nonce || ''
},
// 初始化
init: function() {
this.bindEvents();
this.trackPagePerformance();
},
// 绑定事件
bindEvents: function() {
// 链接点击追踪
$(document).on('click', 'a[href*=""]', function(e) {
const $link = $(this);
const href = $link.attr('href');
// 排除外部链接和特殊链接
if (href.startsWith('#') || href.startsWith('javascript:') ||
href.startsWith('mailto:') || href.startsWith('tel:')) {
return;
}
// 获取文章ID(如果链接指向站内文章)
let postId = null;
if (href.includes(window.location.origin)) {
const match = href.match(//?p=(d+)/) || href.match(//(d+)//);
if (match && match[1]) {
postId = match[1];
}
}
BehaviorTracker.track('click', {
element: $link.text().substring(0, 100),
url: href,
post_id: postId
});
});
// 按钮点击追踪
$(document).on('click', 'button, .btn, input[type="submit"]', function(e) {
const $btn = $(this);
const text = $btn.text() || $btn.val() || $btn.attr('aria-label') || '';
BehaviorTracker.track('click', {
element: 'button',
text: text.substring(0, 100),
class: $btn.attr('class') || ''
});
});
// 表单提交追踪
$(document).on('submit', 'form', function(e) {
const $form = $(this);
const formId = $form.attr('id') || $form.attr('name') || '';
BehaviorTracker.track('form_submit', {
form_id: formId,
action: $form.attr('action') || ''
});
});
// 滚动深度追踪
let scrollTracked = [25, 50, 75, 100];
$(window).on('scroll', $.throttle(250, function() {
const scrollPercent = BehaviorTracker.getScrollPercentage();
scrollTracked = scrollTracked.filter(percent => {
if (scrollPercent >= percent) {
BehaviorTracker.track('scroll', {
depth: percent,
current_position: scrollPercent
});
return false;
}
return true;
});
}));
// 视频播放追踪
$(document).on('play', 'video', function(e) {
const $video = $(this);
const src = $video.attr('src') || '';
BehaviorTracker.track('video_play', {
video_src: src.substring(src.lastIndexOf('/') + 1),
duration: $video.prop('duration') || 0
});
});
},
// 追踪行为
track: function(type, data = {}) {
const postId = $('article').data('post-id') ||
$('.post').data('post-id') ||
$('#post-id').val() ||
null;
$.ajax({
url: this.config.ajax_url,
type: 'POST',
data: {
action: 'track_behavior',
nonce: this.config.nonce,
user_id: this.config.user_id,
session_id: this.config.session_id,
post_id: postId,
behavior_type: type,
behavior_data: JSON.stringify(data),
referrer: document.referrer
},
success: function(response) {
if (!response.success) {
console.warn('行为追踪失败:', response.data);
}
},
error: function(xhr, status, error) {
console.error('行为追踪请求失败:', error);
}
});
},
// 获取滚动百分比
getScrollPercentage: function() {
const windowHeight = $(window).height();
const documentHeight = $(document).height();
const scrollTop = $(window).scrollTop();
return Math.round((scrollTop / (documentHeight - windowHeight)) * 100);
},
// 追踪页面性能
trackPagePerformance: function() {
if (window.performance && window.performance.timing) {
const perf = window.performance.timing;
const pageLoadTime = perf.loadEventEnd - perf.navigationStart;
const domReadyTime = perf.domContentLoadedEventEnd - perf.navigationStart;
if (pageLoadTime > 0) {
this.track('performance', {
page_load_time: pageLoadTime,
dom_ready_time: domReadyTime,
redirect_time: perf.redirectEnd - perf.redirectStart,
dns_time: perf.domainLookupEnd - perf.domainLookupStart,
tcp_time: perf.connectEnd - perf.connectStart,
request_time: perf.responseEnd - perf.requestStart,
dom_parsing_time: perf.domComplete - perf.domInteractive
});
}
}
}
};
// jQuery节流函数
$.throttle = function(delay, callback) {
let timeout = null;
let lastExec = 0;
return function() {
const context = this;
const args = arguments;
const elapsed = Date.now() - lastExec;
function exec() {
lastExec = Date.now();
callback.apply(context, args);
}
if (timeout) {
clearTimeout(timeout);
}
if (elapsed > delay) {
exec();
} else {
timeout = setTimeout(exec, delay - elapsed);
}
};
};
// 文档加载完成后初始化
$(document).ready(function() {
BehaviorTracker.init();
});
})(jQuery);
第三部分:用户行为数据分析与处理
3.1 创建数据分析类
<?php
/**
* 用户行为数据分析类
*/
class User_Behavior_Analyzer {
private $wpdb;
private $table_name;
public function __construct() {
global $wpdb;
$this->wpdb = $wpdb;
$this->table_name = $wpdb->prefix . 'user_behavior';
}
// 获取用户兴趣标签
public function get_user_interests($user_id, $limit = 10) {
$query = $this->wpdb->prepare(
"SELECT
p.ID as post_id,
p.post_title,
COUNT(ub.id) as view_count,
GROUP_CONCAT(DISTINCT t.name) as tags,
GROUP_CONCAT(DISTINCT c.name) as categories
FROM {$this->table_name} ub
LEFT JOIN {$this->wpdb->posts} p ON ub.post_id = p.ID
LEFT JOIN {$this->wpdb->term_relationships} tr ON p.ID = tr.object_id
LEFT JOIN {$this->wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN {$this->wpdb->terms} t ON tt.term_id = t.term_id AND tt.taxonomy = 'post_tag'
LEFT JOIN {$this->wpdb->terms} c ON tt.term_id = c.term_id AND tt.taxonomy = 'category'
WHERE ub.user_id = %d
AND ub.behavior_type IN ('view', 'click', 'like')
AND ub.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
AND p.post_status = 'publish'
GROUP BY p.ID
ORDER BY view_count DESC
LIMIT %d",
$user_id,
$limit
);
$results = $this->wpdb->get_results($query);
// 提取标签和分类作为兴趣点
$interests = array();
foreach ($results as $row) {
if ($row->tags) {
$tags = explode(',', $row->tags);
foreach ($tags as $tag) {
$tag = trim($tag);
if ($tag && !in_array($tag, $interests)) {
}
}
}
if ($row->categories) {
$categories = explode(',', $row->categories);
foreach ($categories as $category) {
$category = trim($category);
if ($category && !in_array($category, $interests)) {
$interests[] = $category;
}
}
}
}
return array_slice($interests, 0, $limit);
}
// 计算用户相似度(基于协同过滤)
public function find_similar_users($user_id, $limit = 5) {
// 获取目标用户浏览过的文章
$target_user_posts = $this->get_user_viewed_posts($user_id);
if (empty($target_user_posts)) {
return array();
}
// 查找浏览过相同文章的其他用户
$post_ids_str = implode(',', array_keys($target_user_posts));
$query = $this->wpdb->prepare(
"SELECT
ub.user_id,
COUNT(DISTINCT ub.post_id) as common_views,
GROUP_CONCAT(DISTINCT ub.post_id) as common_post_ids
FROM {$this->table_name} ub
WHERE ub.user_id != %d
AND ub.user_id > 0
AND ub.post_id IN ({$post_ids_str})
AND ub.behavior_type = 'view'
AND ub.created_at >= DATE_SUB(NOW(), INTERVAL 60 DAY)
GROUP BY ub.user_id
HAVING common_views >= 2
ORDER BY common_views DESC
LIMIT %d",
$user_id,
$limit
);
return $this->wpdb->get_results($query);
}
// 获取用户浏览过的文章
private function get_user_viewed_posts($user_id) {
$query = $this->wpdb->prepare(
"SELECT
post_id,
COUNT(*) as view_count,
MAX(created_at) as last_viewed
FROM {$this->table_name}
WHERE user_id = %d
AND behavior_type = 'view'
AND created_at >= DATE_SUB(NOW(), INTERVAL 60 DAY)
GROUP BY post_id
ORDER BY view_count DESC",
$user_id
);
$results = $this->wpdb->get_results($query);
$posts = array();
foreach ($results as $row) {
$posts[$row->post_id] = array(
'view_count' => $row->view_count,
'last_viewed' => $row->last_viewed
);
}
return $posts;
}
// 获取热门内容(基于浏览量和时间衰减)
public function get_popular_content($limit = 10, $days = 30) {
$query = $this->wpdb->prepare(
"SELECT
ub.post_id,
p.post_title,
p.post_type,
COUNT(ub.id) as total_views,
COUNT(DISTINCT ub.user_id) as unique_users,
MAX(ub.created_at) as last_viewed,
-- 时间衰减权重:最近7天的浏览量权重为1,8-30天的权重按线性衰减
SUM(
CASE
WHEN ub.created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY) THEN 1.0
WHEN ub.created_at >= DATE_SUB(NOW(), INTERVAL %d DAY) THEN
1.0 - (DATEDIFF(NOW(), ub.created_at) - 7) / (%d - 7) * 0.7
ELSE 0.3
END
) as weighted_score
FROM {$this->table_name} ub
INNER JOIN {$this->wpdb->posts} p ON ub.post_id = p.ID
WHERE ub.behavior_type = 'view'
AND ub.created_at >= DATE_SUB(NOW(), INTERVAL %d DAY)
AND p.post_status = 'publish'
GROUP BY ub.post_id
ORDER BY weighted_score DESC, total_views DESC
LIMIT %d",
$days,
$days,
$days,
$limit
);
return $this->wpdb->get_results($query);
}
// 获取用户行为统计报告
public function get_user_behavior_report($user_id = null, $days = 7) {
$where_clause = '';
$params = array($days);
if ($user_id) {
$where_clause = 'AND ub.user_id = %d';
$params[] = $user_id;
}
$query = $this->wpdb->prepare(
"SELECT
DATE(ub.created_at) as date,
COUNT(*) as total_actions,
SUM(CASE WHEN ub.behavior_type = 'view' THEN 1 ELSE 0 END) as views,
SUM(CASE WHEN ub.behavior_type = 'click' THEN 1 ELSE 0 END) as clicks,
SUM(CASE WHEN ub.behavior_type = 'like' THEN 1 ELSE 0 END) as likes,
SUM(CASE WHEN ub.behavior_type = 'comment' THEN 1 ELSE 0 END) as comments,
COUNT(DISTINCT ub.post_id) as unique_posts,
COUNT(DISTINCT ub.session_id) as sessions
FROM {$this->table_name} ub
WHERE ub.created_at >= DATE_SUB(NOW(), INTERVAL %d DAY)
{$where_clause}
GROUP BY DATE(ub.created_at)
ORDER BY date DESC",
...$params
);
return $this->wpdb->get_results($query);
}
// 获取内容关联性分析
public function get_content_relationships($post_id, $limit = 5) {
// 查找同时浏览过这篇文章和其他文章的用户
$query = $this->wpdb->prepare(
"SELECT
ub2.post_id as related_post_id,
p.post_title,
COUNT(DISTINCT ub1.user_id) as common_users,
COUNT(ub2.id) as total_views
FROM {$this->table_name} ub1
INNER JOIN {$this->table_name} ub2 ON ub1.user_id = ub2.user_id
AND ub1.session_id = ub2.session_id
AND ub1.post_id != ub2.post_id
INNER JOIN {$this->wpdb->posts} p ON ub2.post_id = p.ID
WHERE ub1.post_id = %d
AND ub1.behavior_type = 'view'
AND ub2.behavior_type = 'view'
AND ub1.created_at >= DATE_SUB(NOW(), INTERVAL 60 DAY)
AND ub2.created_at >= DATE_SUB(NOW(), INTERVAL 60 DAY)
AND p.post_status = 'publish'
GROUP BY ub2.post_id
ORDER BY common_users DESC, total_views DESC
LIMIT %d",
$post_id,
$limit
);
return $this->wpdb->get_results($query);
}
}
### 3.2 创建数据缓存与优化机制
为了提高系统性能,我们需要实现数据缓存机制:
<?php
/**
- 智能推荐缓存管理类
*/
class Recommendation_Cache_Manager {
private $cache_prefix = 'intelligent_rec_';
private $cache_expiration = 3600; // 1小时
// 获取缓存数据
public function get_cached_recommendations($key, $user_id = 0) {
$cache_key = $this->get_cache_key($key, $user_id);
$cached = get_transient($cache_key);
if ($cached !== false) {
return json_decode($cached, true);
}
return false;
}
// 设置缓存数据
public function set_cached_recommendations($key, $data, $user_id = 0) {
$cache_key = $this->get_cache_key($key, $user_id);
$cache_data = json_encode($data);
// 根据数据类型设置不同的过期时间
$expiration = $this->cache_expiration;
// 热门内容缓存时间较短(15分钟)
if (strpos($key, 'popular') !== false) {
$expiration = 900;
}
// 个性化推荐缓存时间较长(2小时)
if (strpos($key, 'personal') !== false && $user_id > 0) {
$expiration = 7200;
}
set_transient($cache_key, $cache_data, $expiration);
// 记录缓存统计
$this->record_cache_stat($key, $user_id);
return true;
}
// 删除缓存
public function delete_cached_recommendations($key, $user_id = 0) {
$cache_key = $this->get_cache_key($key, $user_id);
return delete_transient($cache_key);
}
// 生成缓存键
private function get_cache_key($key, $user_id) {
return $this->cache_prefix . $key . '_' . $user_id;
}
// 记录缓存统计
private function record_cache_stat($key, $user_id) {
$stats = get_option('rec_cache_stats', array());
$today = date('Y-m-d');
if (!isset($stats[$today])) {
$stats[$today] = array(
'total' => 0,
'hits' => 0,
'misses' => 0,
'by_type' => array()
);
}
$stats[$today]['total']++;
if (!isset($stats[$today]['by_type'][$key])) {
$stats[$today]['by_type'][$key] = 0;
}
$stats[$today]['by_type'][$key]++;
// 只保留最近30天的统计
if (count($stats) > 30) {
ksort($stats);
array_shift($stats);
}
update_option('rec_cache_stats', $stats, false);
}
// 获取缓存命中率
public function get_cache_hit_rate($days = 7) {
$stats = get_option('rec_cache_stats', array());
$recent_stats = array_slice($stats, -$days, $days, true);
$total_hits = 0;
$total_misses = 0;
foreach ($recent_stats as $day_stats) {
$total_hits += $day_stats['hits'];
$total_misses += $day_stats['misses'];
}
$total = $total_hits + $total_misses;
if ($total > 0) {
return array(
'hit_rate' => round($total_hits / $total * 100, 2),
'total_requests' => $total,
'hits' => $total_hits,
'misses' => $total_misses
);
}
return array('hit_rate' => 0, 'total_requests' => 0, 'hits' => 0, 'misses' => 0);
}
}
## 第四部分:个性化推荐引擎实现
### 4.1 核心推荐算法类
<?php
/**
- 个性化推荐引擎核心类
*/
class Personalized_Recommendation_Engine {
private $analyzer;
private $cache_manager;
public function __construct() {
$this->analyzer = new User_Behavior_Analyzer();
$this->cache_manager = new Recommendation_Cache_Manager();
}
// 获取个性化推荐(主入口方法)
public function get_recommendations($user_id = null, $limit = 10, $strategy = 'hybrid') {
$cache_key = 'rec_' . $strategy . '_' . $limit;
// 尝试从缓存获取
if ($user_id) {
$cached = $this->cache_manager->get_cached_recommendations($cache_key, $user_id);
if ($cached !== false) {
return $cached;
}
}
// 根据策略选择推荐算法
$recommendations = array();
switch ($strategy) {
case 'content_based':
$recommendations = $this->get_content_based_recommendations($user_id, $limit);
break;
case 'collaborative':
$recommendations = $this->get_collaborative_recommendations($user_id, $limit);
break;
case 'popular':
$recommendations = $this->get_popular_recommendations($limit);
break;
case 'hybrid':
default:
$recommendations = $this->get_hybrid_recommendations($user_id, $limit);
break;
}
// 过滤掉用户已经看过的内容
$recommendations = $this->filter_viewed_content($recommendations, $user_id);
// 缓存结果
if ($user_id) {
$this->cache_manager->set_cached_recommendations($cache_key, $recommendations, $user_id);
}
return $recommendations;
}
// 基于内容的推荐(根据用户兴趣标签)
private function get_content_based_recommendations($user_id, $limit) {
if (!$user_id) {
return $this->get_popular_recommendations($limit);
}
// 获取用户兴趣标签
$user_interests = $this->analyzer->get_user_interests($user_id, 5);
if (empty($user_interests)) {
return $this->get_popular_recommendations($limit);
}
global $wpdb;
// 构建标签查询条件
$tag_conditions = array();
$params = array();
foreach ($user_interests as $interest) {
$tag_conditions[] = "(t.name LIKE %s OR c.name LIKE %s)";
$params[] = '%' . $wpdb->esc_like($interest) . '%';
$params[] = '%' . $wpdb->esc_like($interest) . '%';
}
$tag_where = implode(' OR ', $tag_conditions);
$query = $wpdb->prepare(
"SELECT
p.ID,
p.post_title,
p.post_excerpt,
p.post_date,
(
-- 标签匹配度评分
SUM(
CASE
WHEN t.name IN (" . implode(',', array_fill(0, count($user_interests), '%s')) . ") THEN 3
WHEN c.name IN (" . implode(',', array_fill(0, count($user_interests), '%s')) . ") THEN 2
ELSE 0
END
) +
-- 时间衰减因子(最近发布的内容权重更高)
(DATEDIFF(NOW(), p.post_date) <= 7) * 2 +
(DATEDIFF(NOW(), p.post_date) <= 30) * 1
) as relevance_score
FROM {$wpdb->posts} p
LEFT JOIN {$wpdb->term_relationships} tr ON p.ID = tr.object_id
LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN {$wpdb->terms} t ON tt.term_id = t.term_id AND tt.taxonomy = 'post_tag'
LEFT JOIN {$wpdb->terms} c ON tt.term_id = c.term_id AND tt.taxonomy = 'category'
WHERE p.post_status = 'publish'
AND p.post_type = 'post'
AND p.ID NOT IN (
SELECT post_id FROM {$wpdb->prefix}user_behavior
WHERE user_id = %d AND behavior_type = 'view'
AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
)
AND ({$tag_where})
GROUP BY p.ID
HAVING relevance_score > 0
ORDER BY relevance_score DESC, p.post_date DESC
LIMIT %d",
...array_merge($user_interests, $user_interests, array($user_id, $limit * 2))
);
$results = $wpdb->get_results($query);
// 格式化结果
$recommendations = array();
foreach ($results as $post) {
$recommendations[] = array(
'id' => $post->ID,
'title' => $post->post_title,
'excerpt' => wp_trim_words($post->post_excerpt, 20),
'date' => $post->post_date,
'score' => $post->relevance_score,
'type' => 'content_based',
'reason' => '基于您的兴趣标签推荐'
);
}
return array_slice($recommendations, 0, $limit);
}
// 协同过滤推荐(基于相似用户)
private function get_collaborative_recommendations($user_id, $limit) {
if (!$user_id) {
return array();
}
// 查找相似用户
$similar_users = $this->analyzer->find_similar_users($user_id, 3);
if (empty($similar_users)) {
return array();
}
global $wpdb;
// 获取相似用户喜欢但目标用户没看过的内容
$similar_user_ids = array();
foreach ($similar_users as $user) {
$similar_user_ids[] = $user->user_id;
}
$similar_user_ids_str = implode(',', $similar_user_ids);
$query = $wpdb->prepare(
"SELECT
ub.post_id,
p.post_title,
p.post_excerpt,
p.post_date,
COUNT(DISTINCT ub.user_id) as liked_by_users,
SUM(
CASE
WHEN ub.behavior_type = 'like' THEN 2
WHEN ub.behavior_type = 'view' THEN 1
ELSE 0
END
) as engagement_score
FROM {$wpdb->prefix}user_behavior ub
INNER JOIN {$wpdb->posts} p
