本文目录导读:

我来给你介绍几种PHP实现简单决策树的方法:
使用数组结构(最简单)
<?php
// 基于数组的简单决策树
function decisionTree($data) {
// 决策规则
$rules = [
'age' => [
'young' => [
'student' => 'yes',
'not_student' => 'no'
],
'middle' => 'yes',
'old' => [
'credit' => [
'excellent' => 'yes',
'fair' => 'no'
]
]
]
];
// 实际决策
if ($data['age'] === 'young') {
if ($data['student'] === true) {
return 'yes';
} else {
return 'no';
}
} elseif ($data['age'] === 'middle') {
return 'yes';
} elseif ($data['age'] === 'old') {
if ($data['credit'] === 'excellent') {
return 'yes';
} else {
return 'no';
}
}
return 'unknown';
}
// 使用示例
$data = ['age' => 'young', 'student' => true];
echo decisionTree($data); // 输出: yes
?>
面向对象方式
<?php
class DecisionNode {
public $attribute;
public $children = [];
public $decision;
public function __construct($attribute = null, $decision = null) {
$this->attribute = $attribute;
$this->decision = $decision;
}
public function addChild($value, $node) {
$this->children[$value] = $node;
}
public function predict($data) {
if ($this->decision !== null) {
return $this->decision;
}
$value = $data[$this->attribute] ?? null;
if ($value !== null && isset($this->children[$value])) {
return $this->children[$value]->predict($data);
}
return 'unknown';
}
}
class DecisionTree {
private $root;
public function build($samples, $features) {
$this->root = $this->buildTree($samples, $features);
}
private function buildTree($samples, $features) {
// 如果所有样本分类相同
$classes = array_column($samples, 'label');
if (count(array_unique($classes)) === 1) {
return new DecisionNode(null, $classes[0]);
}
// 如果没有特征可用
if (empty($features)) {
$counts = array_count_values($classes);
$mostCommon = array_search(max($counts), $counts);
return new DecisionNode(null, $mostCommon);
}
// 选择最优特征(这里简化为第一个特征)
$bestFeature = array_shift($features);
$root = new DecisionNode($bestFeature);
// 根据特征值分割数据
$groups = [];
foreach ($samples as $sample) {
$value = $sample[$bestFeature];
$groups[$value][] = $sample;
}
// 递归构建子树
foreach ($groups as $value => $group) {
$child = $this->buildTree($group, $features);
$root->addChild($value, $child);
}
return $root;
}
public function predict($data) {
return $this->root->predict($data);
}
}
// 使用示例
$samples = [
['age' => 'young', 'income' => 'high', 'label' => 'yes'],
['age' => 'young', 'income' => 'low', 'label' => 'no'],
['age' => 'middle', 'income' => 'high', 'label' => 'yes'],
['age' => 'old', 'income' => 'low', 'label' => 'no'],
];
$tree = new DecisionTree();
$tree->build($samples, ['age', 'income']);
$prediction = $tree->predict(['age' => 'young', 'income' => 'high']);
echo "预测结果: " . $prediction; // 输出: yes
?>
关联数组的递归查找
<?php
class SimpleDecisionTree {
private $tree;
public function __construct() {
// 构建决策树结构
$this->tree = [
'weather' => [
'sunny' => [
'humidity' => [
'high' => 'no',
'normal' => 'yes'
]
],
'rainy' => [
'wind' => [
'strong' => 'no',
'weak' => 'yes'
]
],
'overcast' => 'yes'
]
];
}
public function predict($features) {
return $this->traverse($this->tree, $features);
}
private function traverse($node, $features) {
// 如果是最后一个节点(决策结果)
if (!is_array($node)) {
return $node;
}
// 获取当前特征
$feature = key($node);
$value = $features[$feature] ?? null;
if ($value === null) {
return 'unknown';
}
// 继续递归
if (isset($node[$feature][$value])) {
return $this->traverse($node[$feature][$value], $features);
}
return 'unknown';
}
}
// 使用示例
$tree = new SimpleDecisionTree();
$result = $tree->predict([
'weather' => 'sunny',
'humidity' => 'normal'
]);
echo "是否去户外: " . $result; // 输出: yes
?>
更完整的实现(含ID3算法简化版)
<?php
class ID3DecisionTree {
private $root;
public function build($samples, $features) {
$this->root = $this->buildNode($samples, $features);
}
private function buildNode($samples, $features) {
$labels = array_column($samples, 'label');
// 终止条件
if (count(array_unique($labels)) === 1) {
return new LeafNode($labels[0]);
}
if (empty($features)) {
$counts = array_count_values($labels);
$majority = array_search(max($counts), $counts);
return new LeafNode($majority);
}
// 选择最优特征(简化的信息增益)
$bestFeature = $this->selectBestFeature($samples, $features);
$remainingFeatures = array_diff($features, [$bestFeature]);
$node = new InternalNode($bestFeature);
// 分割数据
$values = array_unique(array_column($samples, $bestFeature));
foreach ($values as $value) {
$subset = array_filter($samples, function($s) use ($bestFeature, $value) {
return $s[$bestFeature] === $value;
});
if (empty($subset)) {
$counts = array_count_values($labels);
$majority = array_search(max($counts), $counts);
$node->addChild($value, new LeafNode($majority));
} else {
$node->addChild($value, $this->buildNode($subset, $remainingFeatures));
}
}
return $node;
}
private function selectBestFeature($samples, $features) {
// 简化版:返回第一个特征
return $features[0];
}
public function predict($data) {
return $this->root->predict($data);
}
}
class InternalNode {
public $feature;
public $children = [];
public function __construct($feature) {
$this->feature = $feature;
}
public function addChild($value, $node) {
$this->children[$value] = $node;
}
public function predict($data) {
$value = $data[$this->feature] ?? null;
if ($value !== null && isset($this->children[$value])) {
return $this->children[$value]->predict($data);
}
return 'unknown';
}
}
class LeafNode {
public $prediction;
public function __construct($prediction) {
$this->prediction = $prediction;
}
public function predict($data) {
return $this->prediction;
}
}
// 使用示例
$samples = [
['outlook' => 'sunny', 'humidity' => 'high', 'label' => 'no'],
['outlook' => 'sunny', 'humidity' => 'normal', 'label' => 'yes'],
['outlook' => 'rainy', 'humidity' => 'high', 'label' => 'no'],
['outlook' => 'rainy', 'humidity' => 'normal', 'label' => 'yes'],
];
$tree = new ID3DecisionTree();
$tree->build($samples, ['outlook', 'humidity']);
echo $tree->predict(['outlook' => 'sunny', 'humidity' => 'normal']); // yes
?>
推荐选择
- 方法一:适合简单的固定规则判断
- 方法二:适合需要动态构建和扩展的场景
- 方法三:适合配置驱动的决策逻辑
- 方法四:适合需要机器学习训练的场景
根据你的具体需求选择合适的方法,如果是简单的业务规则判断,方法一就够了;如果需要更复杂的机器学习功能,建议研究专门的库如php-ml。