PHP项目向量与嵌入

wen PHP项目 3

本文目录导读:

PHP项目向量与嵌入

  1. 向量基础概念
  2. 文本嵌入实现
  3. 向量运算工具类
  4. 使用外部嵌入API
  5. 向量数据库集成
  6. 实际应用示例
  7. 优化与最佳实践

我来详细解释PHP项目中的向量与嵌入概念及其应用。

向量基础概念

什么是向量

向量是数学中表示方向和大小的一组有序数字,在PHP中,向量通常表示为数组或对象。

// 基本向量表示
$vector1 = [0.5, 0.8, 0.1, 0.3];
$vector2 = [0.2, 0.6, 0.9, 0.4];
// 或使用对象
class Vector {
    public array $components;
    public function __construct(array $components) {
        $this->components = $components;
    }
}

文本嵌入实现

简单词嵌入类

class WordEmbedding {
    private array $vocabulary = [];
    private array $vectors = [];
    private int $dimension;
    public function __construct(int $dimension = 100) {
        $this->dimension = $dimension;
    }
    // 训练简单嵌入
    public function train(array $documents): void {
        $words = $this->tokenize($documents);
        $vocab = array_unique($words);
        foreach ($vocab as $word) {
            $this->vectors[$word] = $this->randomVector();
            $this->vocabulary[] = $word;
        }
    }
    // 获取词向量
    public function getVector(string $word): ?array {
        return $this->vectors[$word] ?? null;
    }
    // 句子嵌入(平均词向量)
    public function sentenceEmbedding(string $sentence): array {
        $words = str_word_count($sentence, 1);
        $vectors = [];
        foreach ($words as $word) {
            if (isset($this->vectors[$word])) {
                $vectors[] = $this->vectors[$word];
            }
        }
        if (empty($vectors)) {
            return $this->zeroVector();
        }
        return $this->averageVectors($vectors);
    }
    private function randomVector(): array {
        $vector = [];
        for ($i = 0; $i < $this->dimension; $i++) {
            $vector[] = mt_rand(-1000, 1000) / 1000;
        }
        return $vector;
    }
    private function zeroVector(): array {
        return array_fill(0, $this->dimension, 0);
    }
    private function averageVectors(array $vectors): array {
        $avg = $this->zeroVector();
        $count = count($vectors);
        foreach ($vectors as $vector) {
            for ($i = 0; $i < $this->dimension; $i++) {
                $avg[$i] += $vector[$i];
            }
        }
        return array_map(function($v) use ($count) {
            return $v / $count;
        }, $avg);
    }
    private function tokenize(array $documents): array {
        $words = [];
        foreach ($documents as $doc) {
            $words = array_merge($words, str_word_count(strtolower($doc), 1));
        }
        return $words;
    }
}

向量运算工具类

class VectorOperations {
    // 计算余弦相似度
    public static function cosineSimilarity(array $vec1, array $vec2): float {
        $dotProduct = 0;
        $norm1 = 0;
        $norm2 = 0;
        for ($i = 0; $i < count($vec1); $i++) {
            $dotProduct += $vec1[$i] * $vec2[$i];
            $norm1 += $vec1[$i] ** 2;
            $norm2 += $vec2[$i] ** 2;
        }
        if ($norm1 == 0 || $norm2 == 0) {
            return 0;
        }
        return $dotProduct / (sqrt($norm1) * sqrt($norm2));
    }
    // 计算欧几里得距离
    public static function euclideanDistance(array $vec1, array $vec2): float {
        $sum = 0;
        for ($i = 0; $i < count($vec1); $i++) {
            $sum += ($vec1[$i] - $vec2[$i]) ** 2;
        }
        return sqrt($sum);
    }
    // 向量加法
    public static function add(array $vec1, array $vec2): array {
        $result = [];
        for ($i = 0; $i < count($vec1); $i++) {
            $result[$i] = $vec1[$i] + $vec2[$i];
        }
        return $result;
    }
    // 标量乘法
    public static function scalarMultiply(array $vector, float $scalar): array {
        return array_map(function($v) use ($scalar) {
            return $v * $scalar;
        }, $vector);
    }
    // 向量归一化
    public static function normalize(array $vector): array {
        $norm = sqrt(array_sum(array_map(function($v) {
            return $v ** 2;
        }, $vector)));
        if ($norm == 0) return $vector;
        return array_map(function($v) use ($norm) {
            return $v / $norm;
        }, $vector);
    }
}

使用外部嵌入API

class ExternalEmbeddingAPI {
    private string $apiUrl;
    private string $apiKey;
    public function __construct(string $apiUrl, string $apiKey) {
        $this->apiUrl = $apiUrl;
        $this->apiKey = $apiKey;
    }
    // OpenAI嵌入
    public function getOpenAIEmbedding(string $text): array {
        $ch = curl_init($this->apiUrl . '/v1/embeddings');
        $data = [
            'input' => $text,
            'model' => 'text-embedding-ada-002'
        ];
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                'Authorization: Bearer ' . $this->apiKey,
                'Content-Type: application/json'
            ]
        ]);
        $response = curl_exec($ch);
        curl_close($ch);
        $result = json_decode($response, true);
        return $result['data'][0]['embedding'] ?? [];
    }
    // 批量嵌入
    public function batchEmbeddings(array $texts): array {
        $embeddings = [];
        foreach ($texts as $text) {
            $embeddings[$text] = $this->getOpenAIEmbedding($text);
        }
        return $embeddings;
    }
}

向量数据库集成

class VectorDatabase {
    private PDO $pdo;
    public function __construct(PDO $pdo) {
        $this->pdo = $pdo;
    }
    // 存储向量
    public function storeVector(string $id, array $vector, array $metadata = []): void {
        $sql = "INSERT INTO vectors (id, vector, metadata) VALUES (?, ?, ?)";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute([
            $id,
            json_encode($vector),
            json_encode($metadata)
        ]);
    }
    // 搜索相似向量
    public function searchSimilar(array $queryVector, int $k = 10): array {
        $sql = "SELECT id, vector, metadata FROM vectors";
        $stmt = $this->pdo->query($sql);
        $results = [];
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $storedVector = json_decode($row['vector'], true);
            $similarity = VectorOperations::cosineSimilarity($queryVector, $storedVector);
            $results[] = [
                'id' => $row['id'],
                'similarity' => $similarity,
                'metadata' => json_decode($row['metadata'], true)
            ];
        }
        // 按相似度排序
        usort($results, function($a, $b) {
            return $b['similarity'] <=> $a['similarity'];
        });
        return array_slice($results, 0, $k);
    }
}
// 数据库表结构
// CREATE TABLE vectors (
//     id VARCHAR(255) PRIMARY KEY,
//     vector TEXT NOT NULL,
//     metadata TEXT,
//     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
// );

实际应用示例

// 文档搜索系统
class DocumentSearch {
    private WordEmbedding $embedding;
    private VectorDatabase $db;
    public function __construct() {
        $this->embedding = new WordEmbedding(100);
        $this->db = new VectorDatabase(new PDO('mysql:host=localhost;dbname=test', 'user', 'pass'));
    }
    // 索引文档
    public function indexDocument(string $docId, string $content): void {
        $embedding = $this->embedding->sentenceEmbedding($content);
        $this->db->storeVector($docId, $embedding, [
            'content' => $content,
            'length' => strlen($content)
        ]);
    }
    // 搜索文档
    public function search(string $query, int $limit = 10): array {
        $queryEmbedding = $this->embedding->sentenceEmbedding($query);
        return $this->db->searchSimilar($queryEmbedding, $limit);
    }
}
// 使用示例
$search = new DocumentSearch();
// 索引文档
$search->indexDocument('doc1', 'PHP是一种流行的服务器端脚本语言');
$search->indexDocument('doc2', 'Python是一种广泛使用的高级编程语言');
// 搜索
$results = $search->search('编程语言');
foreach ($results as $result) {
    echo "文档ID: " . $result['id'] . "\n";
    echo "相似度: " . $result['similarity'] . "\n";
}

优化与最佳实践

缓存机制

class VectorCache {
    private Redis $redis;
    private int $ttl;
    public function __construct(Redis $redis, int $ttl = 3600) {
        $this->redis = $redis;
        $this->ttl = $ttl;
    }
    public function getEmbedding(string $text): ?array {
        $key = 'embedding:' . md5($text);
        $cached = $this->redis->get($key);
        return $cached ? json_decode($cached, true) : null;
    }
    public function setEmbedding(string $text, array $embedding): void {
        $key = 'embedding:' . md5($text);
        $this->redis->setex($key, $this->ttl, json_encode($embedding));
    }
}

性能优化建议

  1. 使用批量处理:减少API调用次数
  2. 实现缓存策略:缓存常用嵌入结果
  3. 向量量化:降低维度以减少存储
  4. 近似最近邻搜索:使用Annoy、FAISS等库
  5. 分布式处理:对于大型语料库使用MapReduce

这些实现提供了PHP中处理向量和嵌入的完整解决方案,适用于文本相似度搜索、推荐系统、文档聚类等多种应用场景。

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