本文目录导读:

在足球数据分析领域,量化“进攻三区效率”通常不是指单一的PHP函数,而是指一套数据模型和计算逻辑,你需要结合事件数据(传球、跑动、对抗)和期望进球(xG)模型。
以下是一个从基础到进阶的PHP实现方案,包含计算公式和代码示例。
第一步:定义核心指标(KPI)
在写代码前,先确定你要计算哪几个“效率”维度,常见的有:
- 传球成功率(Pass Completion):在进攻三区内,成功传球/总传球。
- 推进效率(Progression):将球从进攻三区外推进到三区内的有效传球/带球次数。
- 射门转化率(Conversion Rate):进攻三区内的射门数 / 进球数。
- 综合进攻威胁值(Threat Value):结合位置、角度和防守压力的加权评分。
第二步:基础版 PHP 实现(基于简单规则)
假设你有一个简单的比赛事件数组,你可以通过计算传入和传出进攻三区的球权来量化。
<?php
class AttackThirdZoneAnalyzer
{
private array $events;
private int $fieldLength = 105; // 标准场地长度(米)
private int $attackThirdStartX = 70; // 进攻三区起始X坐标(从本方底线算起)
public function __construct(array $events)
{
$this->events = $events;
}
/**
* 计算进攻三区传球成功率
*/
public function passSuccessRate(): array
{
$total = 0;
$success = 0;
foreach ($this->events as $event) {
// 假设事件坐标在进攻三区内
if ($event['type'] === 'pass' && $event['x'] >= $this->attackThirdStartX) {
$total++;
if ($event['outcome'] === 'successful') {
$success++;
}
}
}
return [
'attempts' => $total,
'successful' => $success,
'rate' => $total > 0 ? round($success / $total, 2) : 0,
];
}
/**
* 计算进攻三区“触球权”效率(进入三区后的处理效率)
* 公式:(射门/关键传球) / 总触球次数
*/
public function threatIndex(): float
{
$touches = 0;
$dangerousActions = 0;
foreach ($this->events as $event) {
if ($event['x'] < $this->attackThirdStartX) {
continue; // 跳过非三区事件
}
// 任何在三区的触球
if (in_array($event['type'], ['pass', 'shot', 'dribble', 'receive'])) {
$touches++;
}
// 关键传球或射正算作威胁动作
if ($event['type'] === 'shot') {
$dangerousActions++;
} elseif ($event['type'] === 'pass' && $event['isKeyPass'] === true) {
$dangerousActions++;
}
}
if ($touches === 0) {
return 0.0;
}
// 效率值 = 威胁动作次数 / 触球次数
return round($dangerousActions / $touches, 3);
}
/**
* 计算“推进效率”(从X=50推进到X=70的成功率)
*/
public function progressionEfficiency(): float
{
$attempts = 0;
$success = 0;
foreach ($this->events as $event) {
if ($event['type'] === 'pass' && $event['x'] < $this->attackThirdStartX && $event['endX'] >= $this->attackThirdStartX) {
$attempts++;
if ($event['outcome'] === 'successful') {
$success++;
}
}
}
return $attempts > 0 ? round($success / $attempts, 2) : 0;
}
}
// --- 使用示例 ---
$sampleEvents = [
// 坐标 x 为距离本方底线的距离(米)
['type' => 'pass', 'x' => 75, 'endX' => 80, 'outcome' => 'successful', 'isKeyPass' => false],
['type' => 'pass', 'x' => 80, 'endX' => 85, 'outcome' => 'failed', 'isKeyPass' => false],
['type' => 'shot', 'x' => 78, 'outcome' => 'goal', 'isKeyPass' => false],
['type' => 'receive', 'x' => 72, 'outcome' => 'successful', 'isKeyPass' => false],
['type' => 'pass', 'x' => 45, 'endX' => 72, 'outcome' => 'successful', 'isKeyPass' => false], // 推进
['type' => 'pass', 'x' => 60, 'endX' => 69, 'outcome' => 'failed', 'isKeyPass' => false], // 推进失败
];
$analyzer = new AttackThirdZoneAnalyzer($sampleEvents);
echo "传球成功率: " . json_encode($analyzer->passSuccessRate()) . PHP_EOL;
echo "威胁指数: " . $analyzer->threatIndex() . PHP_EOL;
echo "推进效率: " . $analyzer->progressionEfficiency() . PHP_EOL;
第三步:进阶版(引入权重与 xG)
如果静态指标太“扁平”,你可能需要量化“得分概率权重”,这需要结合场地位置赋予权重值(因为靠近底线的传球比中路的传球更具威胁)。
这里提供一个加权评分模型:
/**
* 计算综合威胁评分(基于位置和动作类型)
*/
public function weightedThreatScore(): float
{
$totalScore = 0;
$totalActions = 0;
foreach ($this->events as $event) {
if ($event['x'] < $this->attackThirdStartX) {
continue;
}
$baseWeight = 1.0;
$actionMultiplier = 1.0;
// 1. 位置权重(越靠近底线和球门,权重越高)
$proximityToGoal = 105 - $event['x']; // 距离球门的距离
if ($proximityToGoal < 20) {
$baseWeight = 3.0; // 极危险区域
} elseif ($proximityToGoal < 30) {
$baseWeight = 2.0;
} elseif ($proximityToGoal < 40) {
$baseWeight = 1.5;
}
// 2. 动作类型权重(射门 > 关键传球 > 普通传球)
switch ($event['type']) {
case 'shot':
$actionMultiplier = 4.0;
break;
case 'pass':
if ($event['isKeyPass']) {
$actionMultiplier = 2.5;
} else {
$actionMultiplier = 1.0;
}
break;
case 'dribble':
$actionMultiplier = 1.8;
break;
case 'receive':
$actionMultiplier = 0.8; // 纯控制球权
break;
default:
$actionMultiplier = 0.5;
}
// 3. 结果修正(失败的动作扣分,成功的动作加分)
if ($event['outcome'] === 'failed') {
$actionMultiplier *= 0.2; // 失败大幅降低效率
}
$totalScore += ($baseWeight * $actionMultiplier);
$totalActions++;
}
// 效率值 = 加权总分 / 动作次数(归一化)
return $totalActions > 0 ? round($totalScore / $totalActions, 2) : 0;
}
关键点: 如果你的数据源是 SportVU 或 StatsBomb,你需要将 x 坐标归一化(0-1),并可能需要引入“包抄点”或“传球角度”来进一步细化权重。
第四步:架构建议(面向复杂项目)
如果项目较大,建议使用策略模式来隔离算法。
<?php
interface EfficiencyCalculator
{
public function calculate(array $events): float;
}
class PassSuccessEfficiency implements EfficiencyCalculator
{
public function calculate(array $events): float
{
// 实现逻辑
}
}
class WeightedThreatEfficiency implements EfficiencyCalculator
{
public function calculate(array $events): float
{
// 实现逻辑
}
}
class EfficiencyContext
{
private EfficiencyCalculator $calculator;
public function __construct(EfficiencyCalculator $calculator)
{
$this->calculator = $calculator;
}
public function analyze(array $events): float
{
return $this->calculator->calculate($events);
}
}
第五步:数据清洗与优化
- 坐标系归一化:建议把X坐标转换为 0-100 或 0-1,方便不同球场尺寸的比较。
- 防守压力(可选):如果有对抗数据,可以给受压迫的传球乘以一个 7 的系数(更难所以更值钱)。
- 缓存机制:对于复杂计算(如动态加权),使用 Redis 缓存按
match_id + team_id存储结果,避免每次请求都全量遍历。
总结公式
最实用的“进攻三区效率值”公式通常是:
Efficiency = (成功传球数 + 射门数 + 关键传球数) / (总触球次数 + 预期失误次数) * 位置权重修正
这样既考虑了数量(多少球传进去了),也考虑了质量(传进去之后做了什么)。
选择哪种方式取决于你的数据颗粒度,如果只有基础坐标,用基础版即可;如果有全量事件流,推荐使用加权评分模型。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播