本文目录导读:

我来详细解释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));
}
}
性能优化建议
- 使用批量处理:减少API调用次数
- 实现缓存策略:缓存常用嵌入结果
- 向量量化:降低维度以减少存储
- 近似最近邻搜索:使用Annoy、FAISS等库
- 分布式处理:对于大型语料库使用MapReduce
这些实现提供了PHP中处理向量和嵌入的完整解决方案,适用于文本相似度搜索、推荐系统、文档聚类等多种应用场景。