Python案例:统计射正数能说明进攻质量吗?
问题的本质
射正数(Shots on Target)≠ 进攻质量,它只是一个过程指标,需要结合其他数据才能推断进攻质量,下面用Python模拟/分析来演示这个结论。

为什么射正数不能单独说明进攻质量
| 问题 | 说明 |
|---|---|
| 射正 ≠ 进球 | 射正可能被门将扑出、被门线解围 |
| 射正 ≠ 威胁 | 30米外软绵绵的射门也算"射正" |
| 忽略射门位置 | 禁区内1次射正 > 禁区外5次射正 |
| 忽略xG(预期进球) | 现代足球的核心指标 |
| 忽略控球/推进 | 可能只是防守反击中的零星射门 |
更合理的进攻质量指标组合:
- xG(Expected Goals,预期进球)
- xT(Expected Threat)
- 射门位置分布(禁区内/外)
- 大机会(Big Chances)创造数
- 进攻三区传球成功率
Python 演示案例
案例1:用模拟数据说明"射正数会骗人"
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import pearsonr
np.random.seed(42)
# 模拟10支球队一个赛季的数据
n_teams = 10
teams = [f"Team_{i+1}" for i in range(n_teams)]
# 假设"真实进攻质量"是一个隐藏变量
true_quality = np.random.uniform(0.3, 1.0, n_teams)
# 射正数:受质量影响 + 噪声(有些队靠远射刷数据)
shots_on_target = (true_quality * 80 + np.random.normal(0, 25, n_teams)).clip(20, 150)
# 进球数:更接近真实质量(但仍受运气影响)
goals = (true_quality * 50 + np.random.normal(0, 8, n_teams)).clip(10, 90)
# xG:最接近真实质量的指标
xg = (true_quality * 55 + np.random.normal(0, 5, n_teams)).clip(10, 95)
df = pd.DataFrame({
"球队": teams,
"射正数": shots_on_target.round(0),
"进球": goals.round(0),
"xG": xg.round(1),
"真实质量": true_quality.round(2)
})
print(df.to_string(index=False))
# 相关性分析
r_sot_goals, _ = pearsonr(df["射正数"], df["进球"])
r_xg_goals, _ = pearsonr(df["xG"], df["进球"])
r_sot_quality, _ = pearsonr(df["射正数"], df["真实质量"])
r_xg_quality, _ = pearsonr(df["xG"], df["真实质量"])
print(f"\n射正数 vs 进球 相关系数: {r_sot_goals:.3f}")
print(f"xG vs 进球 相关系数: {r_xg_goals:.3f}")
print(f"射正数 vs 真实质量 相关系数: {r_sot_quality:.3f}")
print(f"xG vs 真实质量 相关系数: {r_xg_quality:.3f}")
典型输出(可能):
射正数 vs 进球 相关系数: 0.72
xG vs 进球 相关系数: 0.95
射正数 vs 真实质量 相关系数: 0.68
xG vs 真实质量 相关系数: 0.93
xG 与真实进攻质量的相关性远高于射正数。
案例2:可视化对比
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
axes[0].scatter(df["射正数"], df["进球"], color="steelblue", s=80)
axes[0].set_xlabel("射正数"); axes[0].set_ylabel("进球")
axes[0].set_title(f"射正 vs 进球 (r={r_sot_goals:.2f})")
axes[1].scatter(df["xG"], df["进球"], color="seagreen", s=80)
axes[1].set_xlabel("xG"); axes[1].set_ylabel("进球")
axes[1].set_title(f"xG vs 进球 (r={r_xg_goals:.2f})")
axes[2].scatter(df["射正数"], df["xG"], color="coral", s=80)
axes[2].set_xlabel("射正数"); axes[2].set_ylabel("xG")
axes[2].set_title("射正 vs xG(散乱=射正不代表质量)")
plt.tight_layout()
plt.show()
案例3:用真实数据(伪代码 / 说明思路)
真实场景可以用 statsbombpy(开源免费的世界杯数据):
# pip install statsbombpy
from statsbombpy import sb
# 取2022世界杯决赛的所有射门事件
events = sb.events(match_id=3869685) # 阿根廷 vs 法国
shots = events[events["type"] == "Shot"].copy()
# 关键字段
# shot_outcome: Goal / Saved / Off T / Blocked / Post / Wayward
# shot_statsbomb_xg: 预期进球
# location: 射门坐标
# 统计射正数
on_target = shots[shots["shot_outcome"].isin(["Goal", "Saved"])]
print(f"总射门: {len(shots)}")
print(f"射正数: {len(on_target)}")
print(f"xG总和: {shots['shot_statsbomb_xg'].sum():.2f}")
# 分组:射正 vs 非射正 的平均 xG
print("\n平均 xG 对比:")
print(shots.groupby(shots["shot_outcome"].isin(["Goal","Saved"]))["shot_statsbomb_xg"].mean())
更严谨的分析方法
多变量回归:预测"进球/胜率"时,射正数贡献多少?
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
X = df[["射正数", "xG"]].values
y = df["进球"].values
model = LinearRegression().fit(X, y)
print("系数(射正, xG):", model.coef_)
print("R²:", r2_score(y, model.predict(X)))
# 如果只放射正数
model_sot = LinearRegression().fit(df[["射正数"]], y)
print("只用射正数的 R²:", r2_score(y, model_sot.predict(df[["射正数"]])))
# 如果只放 xG
model_xg = LinearRegression().fit(df[["xG"]], y)
print("只用 xG 的 R²:", r2_score(y, model_xg.predict(df[["xG"]])))
预期结果:xG 单独解释的方差远大于 射正数。
控制射门位置后,射正数的边际贡献
# 特征工程:区分禁区内/外射正
df["禁区内射正"] = (df["射正数"] * np.random.uniform(0.4, 0.8, n_teams)).round()
df["禁区外射正"] = df["射正数"] - df["禁区内射正"]
X2 = df[["禁区内射正", "禁区外射正", "xG"]]
model2 = LinearRegression().fit(X2, y)
for name, coef in zip(X2.columns, model2.coef_):
print(f"{name}: {coef:.3f}")
通常发现:禁区内射正系数高、禁区外射正系数接近0,说明位置比"是否射正"更重要。
- 射正数与进球有正相关,但相关性低于 xG。
- 射正数是"过程指标",不能直接等同于进攻质量:它忽略了射门位置、机会质量、对手强度。
- 正确的做法:用 xG / xT / Big Chances 等能反映"机会质量"的指标,并将射正数作为辅助参考。
- 足球分析黄金原则:
"射正多不代表进攻强,可能只是浪射多;射正少不代表进攻弱,可能是效率高。"
用一句话总结:射正数只能说明"打到了门框范围内",不能说明"这次进攻是好机会"。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播