本文目录导读:

在PHP项目中实现交叉验证(Cross-Validation),通常需要结合机器学习库或手动实现,以下是几种常见方法:
使用 PHP-ML 库
PHP-ML 是一个流行的机器学习库,内置了交叉验证功能。
use Phpml\CrossValidation\RandomSplit; use Phpml\Classification\KNearestNeighbors; use Phpml\Metric\Accuracy; // 准备数据 $samples = [[1, 2], [3, 4], [5, 6], [7, 8]]; $labels = ['a', 'a', 'b', 'b']; // 随机分割数据为训练集和测试集(80/20) $dataset = new RandomSplit($samples, $labels, 0.2); // 训练模型 $classifier = new KNearestNeighbors(); $classifier->train($dataset->getTrainSamples(), $dataset->getTrainLabels()); // 预测 $predicted = $classifier->predict($dataset->getTestSamples()); // 计算准确率 $accuracy = Accuracy::score($dataset->getTestLabels(), $predicted); echo "Accuracy: " . $accuracy;
K-Fold 交叉验证
use Phpml\CrossValidation\KFold;
// 5折交叉验证
$kFold = new KFold($samples, $labels, 5, true);
foreach ($kFold as $index => $dataset) {
$classifier = new KNearestNeighbors();
$classifier->train($dataset->getTrainSamples(), $dataset->getTrainLabels());
$predicted = $classifier->predict($dataset->getTestSamples());
$accuracy = Accuracy::score($dataset->getTestLabels(), $predicted);
echo "Fold $index accuracy: $accuracy\n";
}
手动实现交叉验证
function crossValidation($data, $labels, $folds = 5) {
// 打乱数据
$indices = range(0, count($data) - 1);
shuffle($indices);
$dataShuffled = array_map(function($i) use ($data) {
return $data[$i];
}, $indices);
$labelsShuffled = array_map(function($i) use ($labels) {
return $labels[$i];
}, $indices);
// 分割数据为folds份
$foldSize = intval(count($data) / $folds);
$scores = [];
for ($i = 0; $i < $folds; $i++) {
$testStart = $i * $foldSize;
$testEnd = ($i + 1) * $foldSize;
// 训练集
$trainData = [];
$trainLabels = [];
// 测试集
$testData = array_slice($dataShuffled, $testStart, $foldSize);
$testLabels = array_slice($labelsShuffled, $testStart, $foldSize);
// 构建训练集
for ($j = 0; $j < count($dataShuffled); $j++) {
if ($j < $testStart || $j >= $testEnd) {
$trainData[] = $dataShuffled[$j];
$trainLabels[] = $labelsShuffled[$j];
}
}
// 训练和评估模型(这里使用简单的KNN)
$predicted = knnPredict($testData, $trainData, $trainLabels, 3);
$accuracy = calculateAccuracy($testLabels, $predicted);
$scores[] = $accuracy;
}
return [
'scores' => $scores,
'mean_score' => array_sum($scores) / count($scores)
];
}
function knnPredict($testSamples, $trainData, $trainLabels, $k = 3) {
$predictions = [];
foreach ($testSamples as $testSample) {
$distances = [];
foreach ($trainData as $index => $trainSample) {
$distances[] = [
'distance' => euclideanDistance($testSample, $trainSample),
'label' => $trainLabels[$index]
];
}
usort($distances, function($a, $b) {
return $a['distance'] <=> $b['distance'];
});
$nearestLabels = array_slice(array_column($distances, 'label'), 0, $k);
$predictions[] = array_search(max(array_count_values($nearestLabels)), array_count_values($nearestLabels));
}
return $predictions;
}
function euclideanDistance($a, $b) {
$sum = 0;
foreach ($a as $index => $value) {
$sum += pow($value - $b[$index], 2);
}
return sqrt($sum);
}
function calculateAccuracy($actual, $predicted) {
$correct = 0;
foreach ($actual as $index => $label) {
if ($label == $predicted[$index]) {
$correct++;
}
}
return $correct / count($actual);
}
// 使用示例
$data = [
[1.5, 2.0], [3.2, 4.1], [5.0, 5.5], [7.1, 8.0],
[2.0, 1.5], [4.5, 3.8], [6.0, 6.5], [8.2, 7.5]
];
$labels = ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'];
$result = crossValidation($data, $labels, 4);
print_r($result);
分层交叉验证
function stratifiedKFold($data, $labels, $folds = 5) {
// 按类别分组
$groups = [];
foreach ($labels as $index => $label) {
$groups[$label][] = $index;
}
// 每个类别内部分割
$foldsData = array_fill(0, $folds, ['data' => [], 'labels' => []]);
foreach ($groups as $label => $indices) {
shuffle($indices);
$foldSize = intval(count($indices) / $folds);
for ($i = 0; $i < $folds; $i++) {
$start = $i * $foldSize;
$end = ($i == $folds - 1) ? count($indices) : ($i + 1) * $foldSize;
for ($j = $start; $j < $end; $j++) {
$idx = $indices[$j];
$foldsData[$i]['data'][] = $data[$idx];
$foldsData[$i]['labels'][] = $labels[$idx];
}
}
}
return $foldsData;
}
实际项目集成建议
class CrossValidator {
private $model;
private $samples;
private $labels;
public function __construct($model, $samples, $labels) {
$this->model = $model;
$this->samples = $samples;
$this->labels = $labels;
}
public function evaluate($folds = 10) {
$results = [];
// 使用PHP-ML的KFold
$kFold = new KFold($this->samples, $this->labels, $folds);
foreach ($kFold as $fold) {
$this->model->train(
$fold->getTrainSamples(),
$fold->getTrainLabels()
);
$predicted = $this->model->predict($fold->getTestSamples());
$results[] = [
'accuracy' => Accuracy::score($fold->getTestLabels(), $predicted),
'confusion_matrix' => $this->getConfusionMatrix(
$fold->getTestLabels(),
$predicted
)
];
}
return [
'folds' => $results,
'mean_accuracy' => array_sum(array_column($results, 'accuracy')) / count($results),
'std_accuracy' => $this->calculateStd(array_column($results, 'accuracy'))
];
}
private function getConfusionMatrix($actual, $predicted) {
$labels = array_unique(array_merge($actual, $predicted));
$matrix = [];
foreach ($labels as $actualLabel) {
foreach ($labels as $predictedLabel) {
$matrix[$actualLabel][$predictedLabel] = 0;
}
}
foreach ($actual as $i => $a) {
$matrix[$a][$predicted[$i]]++;
}
return $matrix;
}
private function calculateStd($values) {
$mean = array_sum($values) / count($values);
$variance = 0;
foreach ($values as $value) {
$variance += pow($value - $mean, 2);
}
return sqrt($variance / count($values));
}
}
// 使用示例
$validator = new CrossValidator(
new KNearestNeighbors(),
$samples,
$labels
);
$results = $validator->evaluate(5);
echo "Mean Accuracy: " . $results['mean_accuracy'];
echo "Std Accuracy: " . $results['std_accuracy'];
注意事项
- 数据预处理:确保数据格式正确,特征归一化
- 随机种子:设置随机种子以确保结果可重复
- 性能优化:大数据集时考虑使用缓存或分批处理
- 结果分析:不仅要看平均准确率,还要检查每折的方差
建议在小型项目中使用 PHP-ML 库,大型项目中考虑使用更专业的工具(如 Python 的 scikit-learn)进行模型评估,然后将结果集成到 PHP 应用中。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播