PHP项目聊天机器人NLP集成

wen PHP项目 3

本文目录导读:

PHP项目聊天机器人NLP集成

  1. 选择合适的NLP方案
  2. 完整聊天机器人系统实现
  3. 前端聊天界面
  4. 高级功能集成
  5. 性能优化建议
  6. 推荐方案

我来为您详细介绍如何在PHP项目中集成聊天机器人的自然语言处理(NLP)功能。

选择合适的NLP方案

选项A:使用云服务API(推荐)

// 腾讯云NLP示例
require_once './vendor/autoload.php';
use TencentCloud\Common\Credential;
use TencentCloud\Common\Profile\ClientProfile;
use TencentCloud\Common\Profile\HttpProfile;
use TencentCloud\Nlp\V20190408\NlpClient;
use TencentCloud\Nlp\V20190408\Models\ChatBotRequest;
$cred = new Credential("你的SecretId", "你的SecretKey");
$httpProfile = new HttpProfile();
$httpProfile->setEndpoint("nlp.tencentcloudapi.com");
$clientProfile = new ClientProfile();
$clientProfile->setHttpProfile($httpProfile);
$client = new NlpClient($cred, "ap-guangzhou", $clientProfile);
$req = new ChatBotRequest();
$req->setQuery("今天天气怎么样?");
$resp = $client->ChatBot($req);
print_r($resp->toJsonString());

选项B:使用开源NLP库

// 使用PHP NLP工具(php-nlp-tools)
use NlpTools\Tokenizers\WhitespaceAndPunctuationTokenizer;
use NlpTools\Similarity\CosineSimilarity;
class BasicNLPChatbot {
    private $tokenizer;
    private $responses;
    public function __construct() {
        $this->tokenizer = new WhitespaceAndPunctuationTokenizer();
        $this->responses = [
            'hello' => '你好!有什么可以帮助您的吗?',
            '你好' => '您好!很高兴为您服务!',
            '天气' => '我暂时无法查询天气,建议查看天气预报应用。'
        ];
    }
    public function getResponse($input) {
        $tokens = $this->tokenizer->tokenize($input);
        $bestMatch = '';
        $bestScore = 0;
        foreach ($this->responses as $keyword => $response) {
            $keywordTokens = $this->tokenizer->tokenize($keyword);
            $cosine = new CosineSimilarity();
            $score = $cosine->similarity(
                array_count_values($tokens),
                array_count_values($keywordTokens)
            );
            if ($score > $bestScore) {
                $bestScore = $score;
                $bestMatch = $response;
            }
        }
        return $bestScore > 0.3 ? $bestMatch : '抱歉,我不太理解您的问题。';
    }
}

完整聊天机器人系统实现

数据库设计

CREATE TABLE chatbot_responses (
    id INT AUTO_INCREMENT PRIMARY KEY,
    intent VARCHAR(100) NOT NULL,
    pattern TEXT NOT NULL,
    response TEXT NOT NULL,
    context VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE chatbot_conversations (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT,
    session_id VARCHAR(100),
    message TEXT,
    response TEXT,
    intent VARCHAR(100),
    confidence DECIMAL(5,2),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE chatbot_context (
    id INT AUTO_INCREMENT PRIMARY KEY,
    session_id VARCHAR(100),
    context_data JSON,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

主聊天机器人类

<?php
class ChatbotNLP {
    private $db;
    private $sessionId;
    private $context;
    public function __construct($db) {
        $this->db = $db;
        $this->sessionId = session_id();
        $this->loadContext();
    }
    // 处理用户输入
    public function processMessage($message) {
        // 1. 预处理
        $processedMessage = $this->preprocess($message);
        // 2. 意图识别
        $intent = $this->recognizeIntent($processedMessage);
        // 3. 实体提取
        $entities = $this->extractEntities($processedMessage, $intent);
        // 4. 上下文管理
        $this->updateContext($intent, $entities);
        // 5. 生成响应
        $response = $this->generateResponse($intent, $entities);
        // 6. 保存对话记录
        $this->saveConversation($message, $response, $intent);
        return $response;
    }
    // 文本预处理
    private function preprocess($text) {
        // 去除标点符号
        $text = preg_replace('/[^\p{L}\p{N}\s]/u', '', $text);
        // 转为小写
        $text = mb_strtolower($text, 'UTF-8');
        // 分词
        $words = $this->segmentChinese($text);
        return $words;
    }
    // 中文分词
    private function segmentChinese($text) {
        // 使用jieba分词(需安装jieba-php)
        // 或使用简单分词
        $segments = [];
        $length = mb_strlen($text, 'UTF-8');
        for ($i = 0; $i < $length; $i++) {
            $char = mb_substr($text, $i, 1, 'UTF-8');
            // 检查双字词
            if ($i + 1 < $length) {
                $twoChar = $char . mb_substr($text, $i + 1, 1, 'UTF-8');
                if ($this->isWord($twoChar)) {
                    $segments[] = $twoChar;
                    $i++;
                    continue;
                }
            }
            // 检查三字词
            if ($i + 2 < $length) {
                $threeChar = $char . 
                             mb_substr($text, $i + 1, 1, 'UTF-8') . 
                             mb_substr($text, $i + 2, 1, 'UTF-8');
                if ($this->isWord($threeChar)) {
                    $segments[] = $threeChar;
                    $i += 2;
                    continue;
                }
            }
            // 单字
            if (!empty(trim($char))) {
                $segments[] = $char;
            }
        }
        return $segments;
    }
    // 意图识别
    private function recognizeIntent($words) {
        $patterns = $this->getPatterns();
        $maxScore = 0;
        $bestIntent = 'unknown';
        foreach ($patterns as $intent => $pattern) {
            $score = $this->calculateSimilarity($words, explode(' ', $pattern));
            if ($score > $maxScore) {
                $maxScore = $score;
                $bestIntent = $intent;
            }
        }
        // 考虑上下文
        if ($maxScore < 0.3 && $this->context) {
            $contextIntent = $this->getContextIntent();
            if ($contextIntent) {
                $bestIntent = $contextIntent;
            }
        }
        return [
            'intent' => $bestIntent,
            'confidence' => $maxScore
        ];
    }
    // 计算相似度
    private function calculateSimilarity($words1, $words2) {
        $count1 = array_count_values($words1);
        $count2 = array_count_values($words2);
        $intersection = array_intersect_key($count1, $count2);
        $union = $count1 + $count2;
        $dotProduct = array_sum(array_intersect_key($count1, $count2));
        $magnitude1 = sqrt(array_sum(array_map(function($x) { return $x * $x; }, $count1)));
        $magnitude2 = sqrt(array_sum(array_map(function($x) { return $x * $x; }, $count2)));
        if ($magnitude1 * $magnitude2 == 0) return 0;
        return $dotProduct / ($magnitude1 * $magnitude2);
    }
    // 生成响应
    private function generateResponse($intent, $entities) {
        $intent = $intent['intent'];
        switch ($intent) {
            case 'greeting':
                return $this->getRandomResponse('greeting');
            case 'weather':
                return $this->handleWeatherQuery($entities);
            case 'product_info':
                return $this->handleProductQuery($entities);
            case 'order_status':
                return $this->handleOrderStatus($entities);
            case 'faq':
                return $this->handleFAQ($entities);
            default:
                return '抱歉,我暂时无法回答这个问题,请换个方式提问或联系人工客服。';
        }
    }
    // 获取随机响应
    private function getRandomResponse($category) {
        $sql = "SELECT response FROM chatbot_responses WHERE intent = ? ORDER BY RAND() LIMIT 1";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$category]);
        $result = $stmt->fetchColumn();
        return $result ?: '您好!有什么可以帮助您的?';
    }
    // 实体提取
    private function extractEntities($words, $intent) {
        $entities = [];
        // 提取时间实体
        $entities['time'] = $this->extractTimeEntities($words);
        // 提取产品名称
        $entities['product'] = $this->extractProductEntities($words);
        // 提取地点
        $entities['location'] = $this->extractLocationEntities($words);
        return $entities;
    }
    // 上下文管理
    private function loadContext() {
        $sql = "SELECT context_data FROM chatbot_context WHERE session_id = ?";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$this->sessionId]);
        $data = $stmt->fetchColumn();
        $this->context = $data ? json_decode($data, true) : [];
    }
    private function updateContext($intent, $entities) {
        $this->context['last_intent'] = $intent;
        $this->context['entities'] = $entities;
        $this->context['timestamp'] = time();
        // 清理旧上下文(保留最近5个)
        if (count($this->context) > 5) {
            array_shift($this->context);
        }
        $sql = "INSERT INTO chatbot_context (session_id, context_data) 
                VALUES (?, ?) 
                ON DUPLICATE KEY UPDATE context_data = ?";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([
            $this->sessionId,
            json_encode($this->context),
            json_encode($this->context)
        ]);
    }
    // 保存对话记录
    private function saveConversation($message, $response, $intent) {
        $sql = "INSERT INTO chatbot_conversations (user_id, session_id, message, response, intent, confidence) 
                VALUES (?, ?, ?, ?, ?, ?)";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([
            $_SESSION['user_id'] ?? null,
            $this->sessionId,
            $message,
            $response,
            $intent['intent'],
            $intent['confidence']
        ]);
    }
}

前端聊天界面

HTML示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">智能聊天机器人</title>
    <style>
        .chat-container {
            max-width: 400px;
            margin: 20px auto;
            border: 1px solid #ccc;
            border-radius: 8px;
            overflow: hidden;
        }
        .chat-header {
            background: #007bff;
            color: white;
            padding: 15px;
            text-align: center;
        }
        .chat-messages {
            height: 400px;
            overflow-y: auto;
            padding: 15px;
            background: #f8f9fa;
        }
        .message {
            margin: 10px 0;
            display: flex;
        }
        .user-message {
            justify-content: flex-end;
        }
        .bot-message {
            justify-content: flex-start;
        }
        .message-content {
            max-width: 70%;
            padding: 10px;
            border-radius: 10px;
            background: white;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }
        .user-message .message-content {
            background: #007bff;
            color: white;
        }
        .chat-input {
            display: flex;
            padding: 15px;
            background: white;
            border-top: 1px solid #ccc;
        }
        .chat-input input {
            flex: 1;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
            margin-right: 10px;
        }
        .chat-input button {
            padding: 10px 20px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div class="chat-container">
        <div class="chat-header">
            <h3>智能客服</h3>
        </div>
        <div class="chat-messages" id="chatMessages">
            <div class="message bot-message">
                <div class="message-content">
                    您好!我是智能客服,请问有什么可以帮助您的?
                </div>
            </div>
        </div>
        <div class="chat-input">
            <input type="text" id="userInput" placeholder="请输入您的问题..." 
                   onkeypress="if(event.keyCode==13) sendMessage()">
            <button onclick="sendMessage()">发送</button>
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
        function sendMessage() {
            var message = $('#userInput').val().trim();
            if (message === '') return;
            // 显示用户消息
            addMessage(message, 'user');
            // 发送到后端
            $.ajax({
                url: 'chatbot-api.php',
                method: 'POST',
                data: {message: message},
                dataType: 'json',
                success: function(response) {
                    addMessage(response.message, 'bot');
                    // 如果有建议按钮
                    if (response.suggestions) {
                        addSuggestions(response.suggestions);
                    }
                },
                error: function() {
                    addMessage('抱歉,服务器出现错误,请稍后再试。', 'bot');
                }
            });
            $('#userInput').val('');
        }
        function addMessage(text, sender) {
            var messageHtml = '<div class="message ' + sender + '-message">' +
                              '<div class="message-content">' + text + '</div>' +
                              '</div>';
            $('#chatMessages').append(messageHtml);
            $('#chatMessages').scrollTop($('#chatMessages')[0].scrollHeight);
        }
        function addSuggestions(suggestions) {
            var html = '<div class="message bot-message">' +
                       '<div class="message-content">';
            suggestions.forEach(function(suggestion) {
                html += '<button onclick="quickReply(\'' + suggestion + '\')" ' +
                        'style="margin:3px;padding:5px 10px;border:1px solid #007bff;' +
                        'border-radius:15px;background:white;color:#007bff;cursor:pointer;">' +
                        suggestion + '</button>';
            });
            html += '</div></div>';
            $('#chatMessages').append(html);
        }
        function quickReply(text) {
            $('#userInput').val(text);
            sendMessage();
        }
    </script>
</body>
</html>

PHP API端点

<?php
// chatbot-api.php
header('Content-Type: application/json');
session_start();
require_once 'ChatbotNLP.php';
require_once 'db_connection.php';
try {
    $message = $_POST['message'] ?? '';
    if (empty($message)) {
        throw new Exception('消息不能为空');
    }
    $db = getDBConnection();
    $chatbot = new ChatbotNLP($db);
    $response = $chatbot->processMessage($message);
    echo json_encode([
        'success' => true,
        'message' => $response,
        'suggestions' => getSuggestions($response)
    ]);
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'message' => '处理消息时出错:' . $e->getMessage()
    ]);
}
function getSuggestions($response) {
    // 根据响应内容返回建议问题
    $suggestions = [
        '产品咨询' => ['产品价格', '产品功能', '售后服务'],
        '订单问题' => ['查询订单', '修改订单', '取消订单'],
        '常见问题' => ['退款流程', '配送时间', '支付方式']
    ];
    // 简单匹配规则
    foreach ($suggestions as $category => $qs) {
        if (strpos($response, $category) !== false) {
            return $qs;
        }
    }
    return [];
}

高级功能集成

情感分析

class SentimentAnalyzer {
    private $positiveWords = ['好', '棒', '赞', '喜欢', '满意', '感谢'];
    private $negativeWords = ['差', '坏', '烂', '垃圾', '投诉', '退款'];
    public function analyze($text) {
        $words = $this->segmentChinese($text);
        $score = 0;
        foreach ($words as $word) {
            if (in_array($word, $this->positiveWords)) {
                $score++;
            } elseif (in_array($word, $this->negativeWords)) {
                $score--;
            }
        }
        if ($score > 0) return 'positive';
        if ($score < 0) return 'negative';
        return 'neutral';
    }
}

机器学习集成(使用PHP-ML)

use Phpml\Classification\NaiveBayes;
class IntentClassifier {
    private $classifier;
    public function train($trainingData) {
        $this->classifier = new NaiveBayes();
        $samples = [];
        $labels = [];
        foreach ($trainingData as $data) {
            $samples[] = $this->vectorize($data['text']);
            $labels[] = $data['intent'];
        }
        $this->classifier->train($samples, $labels);
    }
    public function predict($text) {
        $vector = $this->vectorize($text);
        return $this->classifier->predict($vector);
    }
    private function vectorize($text) {
        // 文本向量化实现
        $words = $this->segmentChinese($text);
        $vocabulary = $this->getVocabulary();
        $vector = [];
        foreach ($vocabulary as $word) {
            $vector[] = in_array($word, $words) ? 1 : 0;
        }
        return $vector;
    }
}

性能优化建议

  1. 缓存机制:使用Redis缓存常用响应
  2. 异步处理:长时间处理的任务使用消息队列
  3. 数据库优化:为常用查询建立索引
  4. CDN加速:静态资源使用CDN
  5. 负载均衡:高并发情况下使用负载均衡

推荐方案

对于PHP项目,建议:

  • 小项目:使用云服务API + 简单规则引擎
  • 中项目:集成开源NLP库 + 自定义模型
  • 大型项目:使用专门的NLP服务(如Dialogflow、Rasa)并通过API集成

这个系统可以根据您的具体需求进行扩展和定制,如需更详细的特定功能实现,请告诉我您的具体需求。

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