本文目录导读:

我来给您提供一个完整的Python案例,量化球员身价与表现之间的关系,这个案例将包括数据准备、特征工程、相关性分析和回归建模。
完整案例:球员身价与表现量化分析
导入必要的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, r2_score
import warnings
warnings.filterwarnings('ignore')
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
生成模拟数据
# 由于真实数据需要爬取,这里生成模拟数据用于演示
np.random.seed(42)
# 生成500名球员的数据
n_players = 500
# 基本信息
data = {
'年龄': np.random.randint(18, 35, n_players),
'联赛级别': np.random.choice(['顶级', '次级', '三级'], n_players, p=[0.5, 0.3, 0.2]),
'出场次数': np.random.randint(10, 50, n_players),
'首发次数': np.random.randint(5, 45, n_players),
'进球数': np.random.randint(0, 30, n_players),
'助攻数': np.random.randint(0, 20, n_players),
'传球成功率': np.random.uniform(70, 95, n_players),
'抢断数': np.random.randint(0, 80, n_players),
'身价(万欧元)': np.random.uniform(100, 5000, n_players)
}
df = pd.DataFrame(data)
# 根据联赛级别添加权重
league_weight = {'顶级': 2.5, '次级': 1.5, '三级': 1.0}
df['联赛系数'] = df['联赛级别'].map(league_weight)
# 根据身价加入一些逻辑关系(使数据更真实)
df['身价(万欧元)'] = (
df['进球数'] * 50 * df['联赛系数'] +
df['助攻数'] * 35 * df['联赛系数'] +
df['首发次数'] * 20 +
df['传球成功率'] * 2 +
df['抢断数'] * 1.5 +
np.random.normal(0, 200, n_players) # 加入随机噪声
)
# 清理负值
df['身价(万欧元)'] = df['身价(万欧元)'].clip(lower=50)
数据探索与可视化
# 1. 相关性热力图
def plot_correlation(df):
"""绘制相关性热力图"""
plt.figure(figsize=(12, 10))
# 只选择数值型列
numeric_df = df.select_dtypes(include=[np.number])
# 计算相关系数
corr_matrix = numeric_df.corr()
# 绘制热力图
sns.heatmap(corr_matrix,
annot=True,
cmap='coolwarm',
center=0,
fmt='.2f',
square=True)
plt.title('球员各项指标相关性矩阵')
plt.xticks(rotation=45)
plt.yticks(rotation=0)
plt.tight_layout()
plt.savefig('correlation.png', dpi=300, bbox_inches='tight')
plt.show()
return corr_matrix
# 绘制相关性矩阵
corr_matrix = plot_correlation(df)
# 2. 身价分布图
def plot_value_distribution(df):
"""绘制身价分布图"""
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# 左图:直方图
axes[0].hist(df['身价(万欧元)'], bins=30, alpha=0.7, color='blue', edgecolor='black')
axes[0].set_title('球员身价分布')
axes[0].set_xlabel('身价(万欧元)')
axes[0].set_ylabel('人数')
# 右图:箱线图按联赛级别
df.boxplot(column='身价(万欧元)', by='联赛级别', ax=axes[1])
axes[1].set_title('不同级别联赛球员身价')
axes[1].set_xlabel('联赛级别')
axes[1].set_ylabel('身价(万欧元)')
plt.tight_layout()
plt.savefig('value_distribution.png', dpi=300, bbox_inches='tight')
plt.show()
plot_value_distribution(df)
特征工程
# 创建综合表现指标
def create_features(df):
"""创建更多特征"""
df_new = df.copy()
# 场均进球和助攻
df_new['场均进球'] = df_new['进球数'] / df_new['出场次数']
df_new['场均助攻'] = df_new['助攻数'] / df_new['出场次数']
# 进攻效率(进球+助攻)/场次
df_new['进攻效率'] = (df_new['进球数'] + df_new['助攻数']) / df_new['出场次数']
# 综合表现分(加权平均)
df_new['综合表现分'] = (
df_new['进球数'] * 0.4 +
df_new['助攻数'] * 0.3 +
df_new['传球成功率'] * 0.2 +
df_new['抢断数'] * 0.1
)
# 相对年龄优势(年龄越年轻越好)
df_new['年龄评分'] = 100 - (df_new['年龄'] - 18) * 3
# One-Hot编码联赛级别
df_new = pd.get_dummies(df_new, columns=['联赛级别'], prefix='联赛')
return df_new
df = create_features(df)
print("特征工程后的数据维度:", df.shape)
print("\n前5行数据:")
print(df.head())
数据标准化与建模
# 准备特征和目标变量
feature_columns = ['年龄', '出场次数', '首发次数', '进球数', '助攻数',
'传球成功率', '抢断数', '联赛系数', '场均进球', '场均助攻',
'进攻效率', '综合表现分', '年龄评分', '联赛_顶级', '联赛_次级', '联赛_三级']
X = df[feature_columns]
y = df['身价(万欧元)']
# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 标准化特征
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
print("训练集大小:", X_train.shape)
print("测试集大小:", X_test.shape)
模型训练与比较
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.svm import SVR
def train_models(X_train, X_test, y_train, y_test):
"""训练多个模型并比较性能"""
models = {
'线性回归': LinearRegression(),
'随机森林': RandomForestRegressor(n_estimators=100, random_state=42),
'梯度提升': GradientBoostingRegressor(n_estimators=100, random_state=42),
'SVR': SVR(kernel='rbf')
}
results = {}
predictions = {}
for name, model in models.items():
# 训练模型
model.fit(X_train, y_train)
# 预测
y_pred = model.predict(X_test)
predictions[name] = y_pred
# 评估
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
results[name] = {
'MAE': mae,
'R2': r2
}
print(f"{name}: MAE = {mae:.2f}, R² = {r2:.4f}")
return results, predictions, models
results, predictions, fitted_models = train_models(X_train_scaled, X_test_scaled, y_train, y_test)
特征重要性分析
def analyze_feature_importance(model, feature_names):
"""分析特征重要性"""
if hasattr(model, 'feature_importances_'):
importance = model.feature_importances_
importance_df = pd.DataFrame({
'特征': feature_names,
'重要性': importance
}).sort_values('重要性', ascending=False)
# 可视化
plt.figure(figsize=(12, 8))
sns.barplot(data=importance_df.head(10), x='重要性', y='特征')
plt.title('特征重要性排名 (Random Forest)')
plt.xlabel('重要性')
plt.tight_layout()
plt.show()
return importance_df
else:
print("该模型不提供特征重要性")
return None
# 分析随机森林的特征重要性
rf_model = fitted_models['随机森林']
importance_df = analyze_feature_importance(rf_model, feature_columns)
print("\n特征重要性排序:")
print(importance_df)
回归分析
from scipy import stats
def regression_analysis(df, predictor_col, target_col='身价(万欧元)'):
"""对每个特征进行单变量回归分析"""
# 去除异常值
df_clean = df[[predictor_col, target_col]].dropna()
# 简单线性回归
slope, intercept, r_value, p_value, std_err = stats.linregress(df_clean[predictor_col],
df_clean[target_col])
# 计算协方差和相关系数
covariance = np.cov(df_clean[predictor_col], df_clean[target_col])[0, 1]
correlation = df_clean[predictor_col].corr(df_clean[target_col])
print(f"\n{predictor_col} 对身价的回归分析:")
print(f"斜率 (slope): {slope:.3f}")
print(f"截距 (intercept): {intercept:.2f}")
print(f"相关系数 (r): {r_value:.3f}")
print(f"R²: {r_value**2:.3f}")
print(f"p值: {p_value:.4f}")
if p_value < 0.05:
print(f" 该特征对身价有{'显著' if p_value < 0.01 else ''}影响")
else:
print(" 该特征对身价影响不显著")
# 可视化
plt.figure(figsize=(8, 6))
plt.scatter(df_clean[predictor_col], df_clean[target_col], alpha=0.5)
# 添加趋势线
x_range = np.linspace(df_clean[predictor_col].min(), df_clean[predictor_col].max(), 100)
y_fit = slope * x_range + intercept
plt.plot(x_range, y_fit, 'r-', label=f'回归线 (R²={r_value**2:.3f})')
plt.xlabel(predictor_col)
plt.ylabel('身价(万欧元)')
plt.title(f'{predictor_col} 与身价的关系')
plt.legend()
plt.tight_layout()
plt.show()
return {
'slope': slope,
'intercept': intercept,
'r_squared': r_value**2,
'p_value': p_value
}
# 对几个关键指标进行回归分析
reg_results = {}
key_features = ['进球数', '助攻数', '综合表现分', '场均进球']
for feature in key_features:
reg_results[feature] = regression_analysis(df, feature, '身价(万欧元)')
预测个别球员身价
def predict_player_value(model, scaler, player_data, feature_columns):
"""预测单个球员的身价"""
# 创建球员数据框
if not isinstance(player_data, pd.DataFrame):
player_df = pd.DataFrame([player_data])
else:
player_df = player_data.copy()
# 创建相同特征
player_df['场均进球'] = player_df['进球数'] / player_df['出场次数']
player_df['场均助攻'] = player_df['助攻数'] / player_df['出场次数']
player_df['进攻效率'] = (player_df['进球数'] + player_df['助攻数']) / player_df['出场次数']
player_df['综合表现分'] = (
player_df['进球数'] * 0.4 +
player_df['助攻数'] * 0.3 +
player_df['传球成功率'] * 0.2 +
player_df['抢断数'] * 0.1
)
player_df['年龄评分'] = 100 - (player_df['年龄'] - 18) * 3
# 联赛系数字典
league_coef = {'顶级': 2.5, '次级': 1.5, '三级': 1.0}
player_df['联赛系数'] = player_df['联赛级别'].map(league_coef)
# One-Hot编码联赛级别
player_df = pd.get_dummies(player_df, columns=['联赛级别'], prefix='联赛')
# 确保有所有需要的列
for col in feature_columns:
if col not in player_df.columns:
player_df[col] = 0
# 选择特征
X_player = player_df[feature_columns].values
# 标准化
X_player_scaled = scaler.transform(X_player)
# 预测
predicted_value = model.predict(X_player_scaled)[0]
return predicted_value
# 示例:预测一个球员的身价
example_player = {
'年龄': 24,
'联赛级别': '顶级',
'出场次数': 35,
'首发次数': 30,
'进球数': 15,
'助攻数': 8,
'传球成功率': 88.5,
'抢断数': 20
}
predicted = predict_player_value(rf_model, scaler, example_player, feature_columns)
print(f"\n预测球员身价: {predicted:.0f} 万欧元")
综合评价与报告
def generate_report(df, reg_results, importance_df):
"""生成综合评估报告"""
print("="*60)
print("球员身价与表现量化分析报告")
print("="*60)
# 1. 数据概况
print("\n1. 数据概况")
print(f"球员总数: {len(df)}")
print(f"平均身价: {df['身价(万欧元)'].mean():.0f}万欧元")
print(f"身价中位数: {df['身价(万欧元)'].median():.0f}万欧元")
print(f"身价范围: {df['身价(万欧元)'].min():.0f} - {df['身价(万欧元)'].max():.0f}万欧元")
# 2. 关键影响因素
if importance_df is not None:
print("\n2. 影响身价的关键因素前5名")
for i, row in importance_df.head(5).iterrows():
print(f" - {row['特征']}: 重要性 {row['重要性']:.4f}")
# 3. 回归分析结论
print("\n3. 回归分析结论")
for feature, result in reg_results.items():
significance = "显著" if result['p_value'] < 0.05 else "不显著"
print(f" - {feature}: 相关系数 {np.sqrt(result['r_squared']):.3f}, {significance}")
# 4. 模型表现
print("\n4. 最佳模型建议")
print(" - 随机森林和梯度提升模型表现较好适合本数据分析")
print(" - 建议根据具体需求选择线性或非线性模型")
print("\n" + "="*60)
# 生成报告
generate_report(df, reg_results, importance_df)
可视化总结
def comprehensive_visualization(df, predictions, y_test):
"""完整的可视化总结"""
fig = plt.figure(figsize=(20, 15))
# 1. 身价按联赛分布
plt.subplot(2, 2, 1)
data_plot = df.copy()
league_map = {'联赛_顶级': '顶级', '联赛_次级': '次级', '联赛_三级': '三级'}
data_plot['联赛'] = data_plot['联赛_顶级'].apply(lambda x: '顶级' if x else '其他')
data_plot.loc[data_plot['联赛_次级']==1, '联赛'] = '次级'
data_plot.loc[data_plot['联赛_三级']==1, '联赛'] = '三级'
sns.violinplot(data=data_plot, x='联赛', y='身价(万欧元)')
plt.title('不同联赛球员身价对比')
# 2. 年龄与身价关系
plt.subplot(2, 2, 2)
plt.scatter(df['年龄'], df['身价(万欧元)'], alpha=0.5)
# 添加趋势线
z = np.polyfit(df['年龄'], df['身价(万欧元)'], 2)
x_line = np.arange(df['年龄'].min(), df['年龄'].max())
p = np.poly1d(z)
plt.plot(x_line, p(x_line), 'r-')
plt.xlabel('年龄')
plt.ylabel('身价(万欧元)')
plt.title('球员年龄与身价关系')
# 3. 进球数与身价关系
plt.subplot(2, 2, 3)
sns.regplot(data=df, x='进球数', y='身价(万欧元)',
scatter_kws={'alpha':0.3})
plt.xlabel('进球数')
plt.ylabel('身价(万欧元)')
plt.title('进球数与身价关系')
# 4. 模型预测vs实际
plt.subplot(2, 2, 4)
plt.scatter(y_test, predictions['随机森林'], alpha=0.6)
plt.plot([y_test.min(), y_test.max()],
[y_test.min(), y_test.max()], 'r--')
plt.xlabel('实际身价(万欧元)')
plt.ylabel('预测身价(万欧元)')
plt.title(f'模型预测准确度 (R²={r2_score(y_test, predictions["随机森林"]):.4f})')
plt.tight_layout()
plt.savefig('comprehensive_analysis.png', dpi=300, bbox_inches='tight')
plt.show()
# 执行完整可视化
comprehensive_visualization(df, predictions, y_test)
集成模块完整代码
def main():
"""主函数:执行完整的球员身价分析"""
# 1. 数据加载和准备
print("1. 开始数据分析...")
df = pd.DataFrame(data) # 使用前面生成的数据
df = create_features(df)
# 2. 相关性分析
print("2. 进行相关性分析...")
corr_matrix = plot_correlation(df)
# 3. 特征工程和建模
print("3. 开始建模...")
feature_columns = [...] # 完整的特征列表
X = df[feature_columns]
y = df['身价(万欧元)']
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.2,
random_state=42)
# 4. 训练和评估模型
results, predictions, models = train_models(X_train_scaled, X_test_scaled,
y_train, y_test)
# 5. 特征重要性和回归分析
importance_df = analyze_feature_importance(models['随机森林'], feature_columns)
reg_results = {}
for feature in ['进球数', '助攻数', '综合表现分', '场均进球']:
reg_results[feature] = regression_analysis(df, feature, '身价(万欧元)')
# 6. 生成报告和可视化
generate_report(df, reg_results, importance_df)
comprehensive_visualization(df, predictions, y_test)
print("分析完成!")
if __name__ == "__main__":
main()
这个完整的Python案例展示了如何量化球员身价与表现的关系,包括:
- 数据处理和特征工程:创建多个表现指标
- 可视化分析:相关性热力图、分布图等
- 多模型对比:线性回归、随机森林等
- 特征重要性分析:找出关键影响因素
- 单变量回归分析:量化每个指标的影响
通过这个案例,可以清楚地了解哪些表现指标最能影响球员的身价,以及如何用机器学习模型进行身价预测。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播