Python案例:量化主队球迷人数对比赛结果的影响
下面用一个完整的案例,演示如何用Python量化"主队球迷人数"对比赛结果(如主队胜率、净胜球)的影响。

问题定义
研究问题:主队球迷人数是否影响主队胜率/净胜球?
关键挑战:
- 球迷人数与球队实力相关(强队吸引更多球迷)→ 需要控制混淆变量
- 球迷人数本身是内生的 → 可用工具变量(如球场容量、天气)
数据构造(模拟示例)
import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
import seaborn as sns
np.random.seed(42)
n = 1000
# 模拟:球队实力(1-10)
team_strength = np.random.uniform(1, 10, n)
away_strength = np.random.uniform(1, 10, n)
# 球迷人数:受球队实力 + 对手吸引力 + 随机因素影响
attendance = (20000 + 3000 * team_strength
+ 1500 * away_strength
+ np.random.normal(0, 4000, n)).clip(5000, 80000)
# 净胜球:受双方实力差 + 球迷人数(主场优势)影响
goal_diff = (0.3 * (team_strength - away_strength)
+ 0.00002 * attendance # 球迷效应
+ np.random.normal(0, 1, n))
df = pd.DataFrame({
'attendance': attendance,
'team_strength': team_strength,
'away_strength': away_strength,
'goal_diff': goal_diff
})
df['win'] = (df['goal_diff'] > 0).astype(int)
df.head()
基础分析
相关性可视化
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
sns.regplot(data=df, x='attendance', y='goal_diff', ax=axes[0],
scatter_kws={'alpha':0.3})
axes[0].set_title('球迷人数 vs 净胜球')
sns.boxplot(data=df, x='win', y='attendance', ax=axes[1])
axes[1].set_title('胜/负场次的球迷人数分布')
plt.tight_layout()
plt.show()
简单回归(有偏)
model_simple = smf.ols('goal_diff ~ attendance', data=df).fit()
print(model_simple.summary().tables[1])
⚠️ 这个系数是有偏的,因为没控制球队实力。
控制混淆变量
# 加入双方实力作为控制变量
model_ctrl = smf.ols(
'goal_diff ~ attendance + team_strength + away_strength',
data=df
).fit()
print(model_ctrl.summary().tables[1])
# 球迷人数的边际效应
print(f"每增加1名球迷,净胜球变化: {model_ctrl.params['attendance']:.8f}")
print(f"每增加1万名球迷,净胜球变化: {model_ctrl.params['attendance']*10000:.4f}")
量化"效果大小"
# 用标准化系数比较不同变量影响
from scipy import stats
df_std = df[['goal_diff','attendance','team_strength','away_strength']].apply(
stats.zscore)
model_std = smf.ols(
'goal_diff ~ attendance + team_strength + away_strength',
data=df_std
).fit()
print(model_std.params)
解释:若 attendance 标准化系数为 0.15,意味着球迷人数每增加1个标准差,净胜球增加 0.15 个标准差。
进阶:工具变量法(IV / 2SLS)
因为球迷人数是内生的(可能反过来受球队表现影响),用球场容量作为工具变量:
from linearmodels.iv import IV2SLS
# 假设球场容量是外生的工具变量
df['stadium_capacity'] = (df['attendance'] +
np.random.normal(0, 3000, n)).clip(10000, 90000)
iv_model = IV2SLS.from_formula(
'goal_diff ~ 1 + team_strength + away_strength + [attendance ~ stadium_capacity]',
data=df
).fit()
print(iv_model.summary)
非线性/异质性分析
# 分位数回归:看球迷人数对不同水平比赛的影响
import statsmodels.quantreg as qr
for q in [0.25, 0.5, 0.75]:
mod = qr.QuantReg('goal_diff ~ attendance + team_strength + away_strength',
data=df).fit(q=q)
print(f"Q{q}: attendance coef = {mod.params['attendance']:.8f}")
# 分组:强弱队球迷效应是否不同?
df['strong_team'] = (df['team_strength'] > df['team_strength'].median()).astype(int)
for g in [0, 1]:
sub = df[df['strong_team'] == g]
m = smf.ols('goal_diff ~ attendance + away_strength', data=sub).fit()
print(f"强队={g}: 球迷系数={m.params['attendance']:.8f}, p={m.pvalues['attendance']:.4f}")
结果汇总表
def report(model, name):
return {
'模型': name,
'attendance系数': model.params['attendance'],
'标准误': model.bse['attendance'],
'p值': model.pvalues['attendance'],
'R²': model.rsquared
}
results = pd.DataFrame([
report(model_simple, '仅球迷人数'),
report(model_ctrl, '控制球队实力'),
])
print(results)
关键结论与注意事项
| 事项 | 说明 |
|---|---|
| 内生性 | 球迷人数与球队实力高度相关,必须控制 |
| 因果识别 | 建议用 IV(球场容量、天气)或断点回归 |
| 效应量级 | 通常很小,1万球迷 ≈ 0.05~0.2 净胜球 |
| 异质性 | 弱队/关键比赛的球迷效应可能更强 |
| 数据来源 | Kaggle 有 European Soccer Database 可直接练习 |
推荐真实数据集
# Kaggle 命令
# kaggle datasets download -d hugomathien/soccer
# 用欧洲足球数据库做同样的分析
import sqlite3
conn = sqlite3.connect('database.sqlite')
matches = pd.read_sql("SELECT * FROM Match WHERE attendance IS NOT NULL", conn)
核心思路总结:
- 📊 描述性统计 + 可视化
- 🔧 多元回归控制混淆变量
- 🎯 工具变量法处理内生性
- 🔍 异质性/分位数分析
- 📈 将系数翻译成业务可解释的效应量
需要我针对真实数据集或因果推断方法(DID、RDD)展开进一步代码吗?
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播