本文目录导读:

我来介绍用PHP实现用户流失预测的几种方法,从简单到复杂:
基于规则的基础方法
简单的流失评分系统
<?php
class ChurnPredictor {
private $threshold = 50; // 流失阈值
public function calculateChurnScore($userData) {
$score = 0;
// 登录频率检查
$score += $this->checkLoginFrequency($userData['last_login']);
// 订单数量检查
$score += $this->checkOrderCount($userData['order_count']);
// 用户活跃度检查
$score += $this->checkActivity($userData['last_activity']);
// 退订/取消数量
$score += $this->checkUnsubscribe($userData['unsubscribe_count']);
return [
'score' => $score,
'risk' => $score >= $this->threshold ? 'high' : 'low',
'is_churn_risk' => $score >= $this->threshold
];
}
private function checkLoginFrequency($lastLogin) {
$daysSince = (time() - strtotime($lastLogin)) / 86400;
if ($daysSince > 30) return 30;
if ($daysSince > 14) return 20;
if ($daysSince > 7) return 10;
return 0;
}
private function checkOrderCount($count) {
if ($count == 0) return 40;
if ($count <= 3) return 20;
if ($count <= 10) return 10;
return 0;
}
private function checkActivity($lastActivity) {
$daysSince = (time() - strtotime($lastActivity)) / 86400;
if ($daysSince > 60) return 30;
if ($daysSince > 30) return 20;
if ($daysSince > 14) return 10;
return 0;
}
private function checkUnsubscribe($count) {
return min($count * 10, 30);
}
}
// 使用示例
$predictor = new ChurnPredictor();
$userData = [
'last_login' => '2024-01-15',
'last_activity' => '2024-01-10',
'order_count' => 2,
'unsubscribe_count' => 1
];
$result = $predictor->calculateChurnScore($userData);
echo "流失风险: " . $result['risk'] . "\n";
echo "流失分数: " . $result['score'] . "\n";
?>
使用机器学习的进阶方法
集成PHP-ML库
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Phpml\Classification\SVC;
use Phpml\SupportVectorMachine\Kernel;
use Phpml\ModelManager;
class MLChurnPredictor {
private $classifier;
private $modelManager;
public function __construct() {
$this->classifier = new SVC(
Kernel::RBF, // 核函数
10000, // 惩罚参数
3, // 核函数参数
0.1, // 容忍度
true // 是否使用概率估计
);
$this->modelManager = new ModelManager();
}
// 训练模型
public function train($samples, $labels) {
// 样本格式: [[days_since_login, order_count, activity_score, ...]]
// 标签格式: [0, 1, 0, 1, ...] (0=不流失, 1=流失)
$this->classifier->train($samples, $labels);
// 保存模型
$this->modelManager->saveToFile(
$this->classifier,
'churn_model.phpml'
);
}
// 加载已有模型
public function loadModel() {
if (file_exists('churn_model.phpml')) {
$this->classifier = $this->modelManager->restoreFromFile(
'churn_model.phpml'
);
}
}
// 预测单个用户
public function predict($userFeatures) {
// 用户特征: [days_since_login, order_count, activity_score, ...]
return $this->classifier->predict($userFeatures);
}
// 预测概率
public function predictProbability($userFeatures) {
return $this->classifier->predictProbability($userFeatures);
}
}
// 使用示例
$predictor = new MLChurnPredictor();
// 准备训练数据
$samples = [
[30, 0, 10, 0], // 30天未登录,0订单,低活跃
[5, 15, 85, 12], // 5天未登录,15订单,高活跃
[45, 1, 20, 3], // 45天未登录,1订单,低活跃
[2, 30, 90, 25], // 2天未登录,30订单,高活跃
];
$labels = [1, 0, 1, 0]; // 流失=1,不流失=0
// 训练模型
$predictor->train($samples, $labels);
// 预测新用户
$newUser = [20, 3, 40, 5];
$prediction = $predictor->predict($newUser);
$probability = $predictor->predictProbability($newUser);
echo "预测结果: " . ($prediction ? '可能流失' : '可能留存') . "\n";
echo "流失概率: " . ($probability[1] * 100) . "%\n";
?>
完整系统实现
数据库模型
-- 用户行为表
CREATE TABLE user_behavior (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
days_since_login INT,
order_count_30d INT,
activity_score DECIMAL(5,2),
customer_service_calls INT,
payment_delays INT,
feature_usage_count INT,
churn_label BOOLEAN DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
-- 预测结果表
CREATE TABLE churn_predictions (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
prediction_score DECIMAL(5,2),
prediction_label BOOLEAN,
prediction_date DATE,
features_snapshot JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
完整预测系统
<?php
class ChurnPredictionSystem {
private $db;
private $predictor;
private $config;
public function __construct($dbConfig) {
$this->db = new PDO(
"mysql:host={$dbConfig['host']};dbname={$dbConfig['dbname']}",
$dbConfig['user'],
$dbConfig['password']
);
$this->predictor = new MLChurnPredictor();
$this->loadOrTrainModel();
$this->config = [
'prediction_threshold' => 0.6, // 流失阈值
'features' => [
'days_since_login',
'order_count_30d',
'activity_score',
'customer_service_calls'
]
];
}
// 批量预测
public function batchPredict($startDate = null, $endDate = null) {
$users = $this->getUsersForPrediction($startDate, $endDate);
$results = [];
foreach ($users as $user) {
$features = $this->extractFeatures($user);
$probability = $this->predictor->predictProbability($features);
$result = [
'user_id' => $user['id'],
'churn_probability' => $probability[1],
'is_at_risk' => $probability[1] > $this->config['prediction_threshold'],
'features' => $features
];
$this->savePrediction($result);
$results[] = $result;
}
return $results;
}
// 实时预测
public function predictForUser($userId) {
$user = $this->getUserData($userId);
if (!$user) {
throw new Exception("User not found");
}
$features = $this->extractFeatures($user);
$probability = $this->predictor->predictProbability($features);
return [
'user_id' => $userId,
'churn_probability' => $probability[1],
'is_at_risk' => $probability[1] > $this->config['prediction_threshold'],
'features' => $features,
'recommendations' => $this->generateRecommendations($features)
];
}
// 获取高风险用户
public function getHighRiskUsers($limit = 100) {
$stmt = $this->db->prepare("
SELECT user_id, prediction_score, features_snapshot
FROM churn_predictions
WHERE prediction_label = 1
AND prediction_date = CURDATE()
ORDER BY prediction_score DESC
LIMIT ?
");
$stmt->execute([$limit]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// 特征提取
private function extractFeatures($userData) {
$features = [
(int)$userData['days_since_login'],
(int)$userData['order_count_30d'],
(float)$userData['activity_score'],
(int)$userData['customer_service_calls']
];
return $features;
}
// 生成挽留建议
private function generateRecommendations($features) {
$recommendations = [];
if ($features[0] > 14) { // 超过14天未登录
$recommendations[] = "发送登录提醒邮件/推送";
}
if ($features[1] < 3) { // 订单数量少
$recommendations[] = "提供专属优惠券";
}
if ($features[2] < 50) { // 活跃度低
$recommendations[] = "推荐个性化内容";
}
if ($features[3] > 5) { // 客服投诉多
$recommendations[] = "客服回访,解决问题";
}
return $recommendations;
}
// 保存预测结果
private function savePrediction($result) {
$stmt = $this->db->prepare("
INSERT INTO churn_predictions
(user_id, prediction_score, prediction_label, prediction_date, features_snapshot)
VALUES (?, ?, ?, CURDATE(), ?)
ON DUPLICATE KEY UPDATE
prediction_score = VALUES(prediction_score),
prediction_label = VALUES(prediction_label),
features_snapshot = VALUES(features_snapshot)
");
$stmt->execute([
$result['user_id'],
$result['churn_probability'],
$result['is_at_risk'],
json_encode($result['features'])
]);
}
private function loadOrTrainModel() {
// 尝试加载已有模型
$this->predictor->loadModel();
// 如果没有模型,从数据库训练
if (!$this->hasModel()) {
$this->trainFromDatabase();
}
}
private function trainFromDatabase() {
$stmt = $this->db->query("
SELECT days_since_login, order_count_30d, activity_score,
customer_service_calls, churn_label
FROM user_behavior
WHERE churn_label IS NOT NULL
");
$data = $stmt->fetchAll(PDO::FETCH_NUM);
$samples = array_map(function($row) {
return array_slice($row, 0, 4);
}, $data);
$labels = array_map(function($row) {
return (int)$row[4];
}, $data);
if (!empty($samples)) {
$this->predictor->train($samples, $labels);
}
}
private function hasModel() {
return file_exists('churn_model.phpml');
}
}
// 系统使用示例
$config = [
'host' => 'localhost',
'dbname' => 'myapp',
'user' => 'root',
'password' => 'password'
];
$system = new ChurnPredictionSystem($config);
// 批量预测所有用户
$results = $system->batchPredict();
echo "已完成 " . count($results) . " 个用户的预测\n";
// 获取高风险用户
$highRiskUsers = $system->getHighRiskUsers(50);
echo "高风险用户数量: " . count($highRiskUsers) . "\n";
// 实时预测单个用户
$userPrediction = $system->predictForUser(123);
echo "用户123的流失概率: " . ($userPrediction['churn_probability'] * 100) . "%\n";
if ($userPrediction['is_at_risk']) {
echo "建议措施: " . implode(", ", $userPrediction['recommendations']) . "\n";
}
?>
API接口实现
<?php
// churn_api.php
header('Content-Type: application/json');
require_once 'ChurnPredictionSystem.php';
$system = new ChurnPredictionSystem($config);
$method = $_SERVER['REQUEST_METHOD'];
$action = $_GET['action'] ?? '';
switch ($action) {
case 'predict':
if ($method === 'POST') {
$userId = $_POST['user_id'] ?? 0;
try {
$result = $system->predictForUser($userId);
echo json_encode(['success' => true, 'data' => $result]);
} catch (Exception $e) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
}
break;
case 'high_risk':
if ($method === 'GET') {
$limit = $_GET['limit'] ?? 100;
$users = $system->getHighRiskUsers($limit);
echo json_encode(['success' => true, 'data' => $users]);
}
break;
case 'batch_predict':
if ($method === 'POST') {
$results = $system->batchPredict();
echo json_encode([
'success' => true,
'data' => $results,
'count' => count($results)
]);
}
break;
default:
http_response_code(404);
echo json_encode(['error' => 'Action not found']);
}
?>
注意事项
- 数据质量:确保训练数据质量高,标签准确
- 特征工程:选择合适的特征对预测结果影响很大
- 模型评估:定期评估模型性能,防止过拟合
- 实时性:对于实时预测,考虑使用缓存或异步处理
- 隐私保护:确保符合数据保护法规(如GDPR)
这个PHP实现可以根据你的具体需求进行扩展和优化。