python案例如何量化球员身价与表现关系?

wen python案例 4

本文目录导读:

python案例如何量化球员身价与表现关系?

  1. 完整案例:球员身价与表现量化分析
  2. 集成模块完整代码

我来给您提供一个完整的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案例展示了如何量化球员身价与表现的关系,包括:

  1. 数据处理和特征工程:创建多个表现指标
  2. 可视化分析:相关性热力图、分布图等
  3. 多模型对比:线性回归、随机森林等
  4. 特征重要性分析:找出关键影响因素
  5. 单变量回归分析:量化每个指标的影响

通过这个案例,可以清楚地了解哪些表现指标最能影响球员的身价,以及如何用机器学习模型进行身价预测。

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