如何用PHP项目实现用户流失预测?

wen java案例 2

本文目录导读:

如何用PHP项目实现用户流失预测?

  1. 基于规则的基础方法
  2. 使用机器学习的进阶方法
  3. 完整系统实现
  4. API接口实现
  5. 注意事项

我来介绍用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']);
}
?>

注意事项

  1. 数据质量:确保训练数据质量高,标签准确
  2. 特征工程:选择合适的特征对预测结果影响很大
  3. 模型评估:定期评估模型性能,防止过拟合
  4. 实时性:对于实时预测,考虑使用缓存或异步处理
  5. 隐私保护:确保符合数据保护法规(如GDPR)

这个PHP实现可以根据你的具体需求进行扩展和优化。

抱歉,评论功能暂时关闭!