本文目录导读:

PHP中实现文本聚类(Text Clustering)通常需要结合中文分词、TF-IDF向量化和聚类算法,虽然PHP本身没有像Python那样成熟的机器学习库,但可以通过以下方式实现:
使用PHP-ML库实现
PHP-ML是一个流行的PHP机器学习库,支持K-Means聚类算法。
安装
composer require php-ai/php-ml
实现代码
<?php
require_once 'vendor/autoload.php';
use Phpml\Clustering\KMeans;
use Phpml\FeatureExtraction\TfIdfTransformer;
use Phpml\Tokenization\WhitespaceTokenizer;
use Phpml\FeatureExtraction\TokenCountVectorizer;
class TextCluster {
private $stopWords;
public function __construct() {
// 中文停用词表
$this->stopWords = ['的', '了', '在', '是', '我', '有', '和', '就', '不', '人', '都', '一', '一个', '上', '也', '很', '到', '说', '要', '去', '你', '会', '着', '没有', '看', '好', '自己', '这'];
}
// 简单的分词函数(实际项目建议使用jieba-php)
public function segment($text) {
// 这里使用简单的中文分词,实际项目建议使用专门的PHP分词库
// jieba-php, phpanalysis等
$segmented = [];
$length = mb_strlen($text, 'UTF-8');
$current = '';
for ($i = 0; $i < $length; $i++) {
$char = mb_substr($text, $i, 1, 'UTF-8');
// 如果不是标点符号和空格
if (preg_match('/[\x{4e00}-\x{9fa5}a-zA-Z0-9]/u', $char)) {
$current .= $char;
} else {
if ($current !== '') {
// 简单地将连续的中文/英文作为词
if (mb_strlen($current) <= 4 && mb_strlen($current) >= 2) {
// 过滤停用词
if (!in_array($current, $this->stopWords)) {
$segmented[] = $current;
}
}
$current = '';
}
}
}
if ($current !== '' && !in_array($current, $this->stopWords)) {
$segmented[] = $current;
}
return $segmented;
}
// 文本聚类
public function cluster($documents, $k = 3) {
// 1. 分词
$tokenizedDocs = [];
foreach ($documents as $doc) {
$words = $this->segment($doc);
$tokenizedDocs[] = $words;
}
// 2. 创建词袋模型
$vectorizer = new TokenCountVectorizer(new WhitespaceTokenizer());
// 将分词结果用空格连接
$docsForVector = array_map(function($words) {
return implode(' ', $words);
}, $tokenizedDocs);
$vectorizer->fit($docsForVector);
$vectors = $vectorizer->transform($docsForVector);
// 3. TF-IDF转换
$transformer = new TfIdfTransformer();
$transformer->fit($vectors);
$vectors = $transformer->transform($vectors);
// 4. K-Means聚类
$kmeans = new KMeans($k);
$clusters = $kmeans->cluster($vectors);
// 5. 映射回原始文档
$result = [];
foreach ($clusters as $clusterIndex => $cluster) {
$result[$clusterIndex] = [];
foreach ($cluster as $docIndex) {
$result[$clusterIndex][] = $documents[$docIndex];
}
}
return $result;
}
}
// 使用示例
$cluster = new TextCluster();
$documents = [
'我喜欢吃苹果和香蕉',
'今天天气真不错适合出去运动',
'NBA篮球比赛非常精彩',
'苹果公司发布了新款iPhone',
'篮球运动对身体健康很有帮助',
'香蕉是一种营养丰富的水果',
'我每天都会去健身房锻炼',
'智能手机市场竞争非常激烈'
];
$result = $cluster->cluster($documents, 3);
echo "聚类结果:\n";
foreach ($result as $clusterIndex => $docs) {
echo "类别 " . ($clusterIndex + 1) . ":\n";
foreach ($docs as $doc) {
echo " - " . $doc . "\n";
}
echo "\n";
}
使用Scout + Elasticsearch实现
对于大规模文本聚类,推荐使用Elasticsearch的聚合功能:
<?php
// 使用Elasticsearch PHP客户端
require_once 'vendor/autoload.php';
use Elasticsearch\ClientBuilder;
class ElasticsearchTextCluster {
private $client;
public function __construct($hosts = ['localhost:9200']) {
$this->client = ClientBuilder::create()
->setHosts($hosts)
->build();
}
// 创建索引并导入文档
public function indexDocuments($documents) {
$params = [
'index' => 'text_cluster',
'body' => [
'mappings' => [
'properties' => [
'content' => [
'type' => 'text',
'analyzer' => 'standard'
],
'vector' => [
'type' => 'dense_vector',
'dims' => 128 // 向量维度
]
]
]
]
];
// 创建索引
$this->client->indices()->create($params);
// 导入文档
foreach ($documents as $id => $content) {
$params = [
'index' => 'text_cluster',
'id' => $id,
'body' => [
'content' => $content,
'vector' => $this->textToVector($content) // 转为向量
]
];
$this->client->index($params);
}
}
// 使用K-Means聚类
public function performClustering($k = 3) {
// Elasticsearch 7.10+ 支持K-Means聚类
// 这里需要使用Elasticsearch的机器学习API
}
}
使用外部API服务
调用云端API实现文本聚类:
<?php
class ApiTextCluster {
public function clusterWithTensorFlow($documents) {
$apiKey = 'YOUR_API_KEY';
$url = 'https://api.tensorflow.org/v1/models/text_cluster';
$data = [
'instances' => $documents
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
}
推荐方案
对于生产环境,建议:
- 小规模数据:使用PHP-ML库,配合jieba-php进行中文分词
- 中大规模数据:使用Elasticsearch + 自定义PHP脚本
- 最佳实践:使用Python实现聚类服务,通过PHP调用微服务API
完整示例(使用jieba-php分词)
<?php
require_once 'vendor/autoload.php';
use Phpml\Clustering\KMeans;
use Fukuball\Jieba\Jieba;
use Fukuball\Jieba\Finalseg;
// 初始化jieba
Jieba::init();
Finalseg::init();
class AdvancedTextCluster {
public function segment($text) {
// 使用jieba分词
$words = Jieba::cut($text);
$stopWords = ['的', '了', '在', '是', '我', '有', '和', '就'];
return array_values(array_filter($words, function($word) use ($stopWords) {
return !in_array($word, $stopWords) && mb_strlen($word, 'UTF-8') > 1;
}));
}
public function cluster($documents, $k = 3) {
// 实现同上,但使用jieba进行分词
// ...
}
}
这个方法可以实现基本的文本聚类功能,对于更复杂的场景,建议将聚类任务交给专门的机器学习服务处理。