php项目如何量化进攻三区效率值?

wen PHP项目 4

本文目录导读:

php项目如何量化进攻三区效率值?

  1. 核心概念定义
  2. 可量化的指标体系
  3. PHP 实现
  4. 进阶优化方向
  5. 返回给前端的结构建议

在足球数据分析中,进攻三区通常指距对方球门约30米区域的球场前沿地带,量化“进攻三区效率值”的核心思路是:衡量球队/球员进入该区域后,转化为实质性威胁或进球的效率。

下面从指标定义、计算模型、代码实现三个层面,给出一个可在 PHP 项目中落地的方案。


核心概念定义

术语 含义
进攻三区 距对方球门 30m 内区域(可配置)
进入次数 球队/球员把球带入或传入该区域的次数
有效进攻 进入后形成射门、关键传球、角球、点球等
效率值 有效产出 / 进入次数,可加权

可量化的指标体系

建议采用加权效率模型,而不是单一比率,因为不同结果价值不同。

基础事件(来自事件数据)

  • entry:进入进攻三区(传球或带球)
  • shot:射门
  • shot_on_target:射正
  • goal:进球
  • key_pass:关键传球(导致射门)
  • assist:助攻
  • corner:角球
  • foul_won:在进攻三区被犯规

权重设计(示例,可调)

$weights = [
    'entry'         => 1,    // 基准
    'shot'          => 3,
    'shot_on_target'=> 5,
    'key_pass'      => 4,
    'corner'        => 2,
    'foul_won'      => 2,
    'assist'        => 8,
    'goal'          => 10,
];

效率值公式

效率值 = Σ(事件次数 × 权重) / 进入进攻三区次数

再乘以 100 归一化,便于横向比较:

效率值 = (Σ(事件 × 权重) / entries) × 100

PHP 实现

数据表设计(MySQL 示例)

CREATE TABLE attacking_third_events (
    id INT AUTO_INCREMENT PRIMARY KEY,
    match_id INT NOT NULL,
    player_id INT NOT NULL,
    team_id INT NOT NULL,
    event_type VARCHAR(30) NOT NULL, -- entry/shot/goal/...
    minute INT,
    x_coord FLOAT,  -- 0~100,越大越靠近对方球门
    y_coord FLOAT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX(match_id, player_id),
    INDEX(event_type)
);

核心计算类

<?php
class AttackingThirdEfficiency
{
    // 权重配置
    private array $weights = [
        'entry'          => 1,
        'shot'           => 3,
        'shot_on_target' => 5,
        'key_pass'       => 4,
        'corner'         => 2,
        'foul_won'       => 2,
        'assist'         => 8,
        'goal'           => 10,
    ];
    public function __construct(private PDO $pdo) {}
    /**
     * 计算某球员在某场比赛的进攻三区效率值
     */
    public function calcForPlayer(int $playerId, int $matchId): array
    {
        $sql = "SELECT event_type, COUNT(*) AS cnt
                FROM attacking_third_events
                WHERE player_id = :pid AND match_id = :mid
                GROUP BY event_type";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(['pid' => $playerId, 'mid' => $matchId]);
        $rows = $stmt->fetchAll(PDO::FETCH_KEY_PAIR); // ['entry'=>10, 'shot'=>4, ...]
        return $this->compute($rows);
    }
    /**
     * 计算某球队在某场比赛的效率值
     */
    public function calcForTeam(int $teamId, int $matchId): array
    {
        $sql = "SELECT event_type, COUNT(*) AS cnt
                FROM attacking_third_events
                WHERE team_id = :tid AND match_id = :mid
                GROUP BY event_type";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(['tid' => $teamId, 'mid' => $matchId]);
        $rows = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
        return $this->compute($rows);
    }
    /**
     * 通用计算
     */
    private function compute(array $counters): array
    {
        $entries = (int)($counters['entry'] ?? 0);
        if ($entries === 0) {
            return [
                'entries'    => 0,
                'weighted'   => 0,
                'efficiency' => 0.0,
                'detail'     => $counters,
            ];
        }
        $weighted = 0;
        foreach ($this->weights as $type => $w) {
            $weighted += ($counters[$type] ?? 0) * $w;
        }
        // entry 自身已计入基础,但避免重复权重,可减去一次
        $weighted -= $entries * $this->weights['entry'];
        $efficiency = round($weighted / $entries * 100, 2);
        return [
            'entries'    => $entries,
            'weighted'   => $weighted,
            'efficiency' => $efficiency,
            'detail'     => $counters,
        ];
    }
}

使用示例

$pdo = new PDO('mysql:host=localhost;dbname=football', 'root', '');
$calc = new AttackingThirdEfficiency($pdo);
$result = $calc->calcForPlayer(1001, 2024);
print_r($result);
/*
[
  'entries'    => 12,
  'weighted'   => 45,
  'efficiency' => 375.0,
  'detail'     => ['entry'=>12, 'shot'=>3, 'goal'=>1, 'key_pass'=>2, ...]
]
*/

进阶优化方向

使用 xG / xT 替代固定权重

用预期进球(xG)或威胁值(xT)作为权重,比固定权重更科学:

$weighted += ($counters[$type] ?? 0) * $this->xTMap[$type];

引入对手强度修正

面对强队时效率值含金量更高,可加系数:

$efficiency *= $this->opponentStrengthFactor($matchId);

时间衰减

越靠近比赛末段的进球价值更高,可对 minute 加权。

位置精度

用 x 坐标进一步细分:

  • 30–25m:一级三区
  • 25–18m:二级三区
  • 18m 以内:禁区

分区权重递增,能做到位置敏感的效率评估。

归一化与排名

对同一联赛所有球员做 z-score 或百分位归一化,输出 0–100 的“效率指数”:

$percentile = $this->percentileRank($efficiency, $leagueData);

返回给前端的结构建议

{
  "player_id": 1001,
  "match_id": 2024,
  "entries": 12,
  "weighted_score": 45,
  "efficiency": 375.0,
  "percentile": 87,
  "detail": {
    "shot": 3,
    "goal": 1,
    "key_pass": 2,
    "corner": 1
  }
}

层面 做法
定义 进入三区次数 + 有效产出事件
公式 Σ(事件 × 权重) / entries × 100
实现 PDO 聚合查询 + PHP 计算类
优化 xT/xG 权重、对手强度、位置细分、百分位归一化
输出 效率值 + 明细 + 排名,便于前端可视化

如果你能提供你的数据源结构(比如是否用 StatsBomb、Opta、还是自采集),我可以帮你把权重表和 SQL 进一步定制成贴合你项目的版本。

抱歉,评论功能暂时关闭!