美文网首页
决策树-网球运动员排名分析

决策树-网球运动员排名分析

作者: 熊定坤 | 来源:发表于2019-01-09 12:04 被阅读0次

    1.案例说明

    数据来源狗熊会,数据完整,无缺失值,错误值
    通过网球运动的技术指标探究运动员的技术水平对世界排名的影响

    2.变量修改及探索性分析

    读取数据

    os.chdir(r'C:\Users\Administrator\Desktop\狗熊会数据\5.5 网球运动员战绩分析')
    data_f = pd.read_csv('世界前100名女性网球运动员信息.csv',encoding='GBK')
    data_m = pd.read_csv('世界前100名男性网球运动员信息.csv',encoding='GBK')
    data_m.head()
    

    男性运动员数据


    女性运动员数据

    男性运动员费德勒和纳达尔的技术水平指标类比
    col_a = ['ACES', '双误']
    col_fq = ['一发', '一发得分', '二发得分', '挽救破发点']
    col_jq = ['一发回球得分', '二发回球得分', '成功破发']
    data_js = data_m[col_fq+col_jq]
    data1 = data_js[data_m['姓名']=='Rafael Nadal']
    data2 = data_js[data_m['姓名']=='Roger Federer']
    c_chema = []
    for i in data_js.columns:
        dict ={}
        dict['name'] = i
        dict['max'] = 100
        dict['min'] = 0
        c_chema.append(dict)
    
    c_chema
    from pyecharts import Radar
    radar = Radar('各项技术水平比较')
    radar.config(c_schema=c_chema)
    radar.add('纳达尔',[data1.iloc[0]],is_area_show=True,area_opacity=0.6,area_color='#F25F5C')
    radar.add('费德勒',[data2.iloc[0]],is_area_show=True,area_opacity=0.6,area_color='#247BA0')
    radar
    

    男性运动员和女性运动技术水平指标类比

    datam_js = data_m[col_fq+col_jq]
    dataf_js = data_f[col_fq+col_jq]
    from pyecharts import Radar
    radar = Radar('各项技术水平比较')
    radar.config(c_schema=c_chema)
    radar.add('男性运动员',[datam_js.mean()],is_area_show=True,area_opacity=0.6,area_color='#F25F5C')
    radar.add('女性运动员',[round(dataf_js.mean(),2)],is_area_show=True,area_opacity=0.6,area_color='#247BA0')
    radar
    

    ACE,双误变量为统计运动员所有参赛的ACE和双误数,将其转变为参赛数为基准的计数
    运动等级排名分类成'TOP25','TOP25-50','TOP50-75','TOP75-100'

    data_f['等级']=pd.cut(data_f['排名'],bins=(0,25,50,75,100),labels=['TOP25','TOP25-50','TOP50-75','TOP75-100'])
    data_m['等级']=pd.cut(data_m['排名'],bins=(0,25,50,75,100),labels=['TOP25','TOP25-50','TOP50-75','TOP75-100'])
    data_f['ACES数'] = data_f['ACES']/data_f['锦标赛']
    data_m['ACES数'] = data_m['ACES']/data_m['锦标赛']
    data_f['双误数'] = data_f['双误']/data_f['锦标赛']
    data_m['双误数'] = data_m['双误']/data_m['锦标赛']
    

    男性选手等级和ACE数,双误数的相关性

    fig,ax = plt.subplots(ncols=2,figsize=(10,4))
    sns.boxplot(x='等级',y='ACES数',data=data_m,ax=ax[0])
    sns.boxplot(x='等级',y='双误数',data=data_m,ax=ax[1])
    
    image.png

    ACE数,双误数与运动员等级有明显相关性
    其中某些运动员ACES数达到40以上,了解一下这些运动员



    安迪穆雷和德约科维奇都是擅长发球的选手

    女性选手等级和ACE数,双误数的相关性


    通过方差分析探究一下女性选手等级和ACE数,双误数的相关性

    import statsmodels.api as sm
    from statsmodels.formula.api import ols
    ana1 = ols('双误数~C(等级)',data=data_f).fit()
    sm.stats.anova_lm(ana1)
    ana2 = ols('ACES数~C(等级)',data=data_f).fit()
    sm.stats.anova_lm(ana2)
    
    
    双误数~C(等级) ACES数~C(等级)

    F值偏小,女性双误数/ACES数与等级相关性都不显著

    3.构建模型

    对男性运动员构建模型

    #定义自标量标签
    cols = data_m.columns.tolist()
    cols.remove('排名')
    cols.remove('锦标赛')
    cols.remove('ACES')
    cols.remove('双误')
    cols.remove('姓名')
    cols.remove('等级')
    #相关性分析
    corr = data_m[cols].corr()
    plt.figure(figsize=(10,7))
    sns.heatmap(corr,vmax=1,annot=True)
    #一发变量与其他变量相关性不高,剔除一发属性
    cols.remove('一发')
    

    各变量间相关性较高,一发成功率与其他变量相关性不高,剔除该变量,其他变量做降维处理
    由于因子分析具有较好的解释性,选择因子分析法降维

    1. 对变量进行标准化处理
    #z-score 标准化
    from sklearn.preprocessing import scale
    data_zs = scale(data_m[cols])
    
    1. 对变量进行主成分分析法
    from sklearn.decomposition import PCA
    pca = PCA()
    pca.fit(data_zs)
    #查看累计贡献度
    pca.explained_variance_ratio_.cumsum()
    

    array([ 0.34301552, 0.56753275, 0.65095733, 0.7158034 , 0.77711738,
    0.83333131, 0.87353708, 0.91081821, 0.94416561, 0.9682807 ,
    0.98886887, 1. ])
    累计贡献度显示5个主成分能解释77%的变异数据
    可以选取4-6个因子

    1. 用方差最大化做因子转化,保留五个公共因子
    from fa_kit import FactorAnalysis
    from fa_kit import plotting as fa_plot
    #数据导入和转化
    fa = FactorAnalysis.load_data_samples(data_zs,preproc_demean=True,preproc_scale=True)
    #抽取主成分
    fa.extract_components()
    #确认保留因子的数量,使用top_n法
    fa.find_comps_to_retain(method='top_n',num_keep=5)
    #使用最大方差法进行因子旋转
    fa.rotate_components(method='varimax')
    #制图
    fa_plot.graph_summary(fa)
    

    最大方差法进行因子旋转后各因子界限更加明显

    1. 查看个因子在各变量上权重,定义各因子
    #查看个因子在各变量上权重
    fas = pd.DataFrame(fa.comps['rot'],index=cols)
    fas
    

    因子0在一发得分,ACES数,双误数权重较大,球员表现较为注重发球得分,定义为发球因子
    因子1在一发回球得分,二发回球得分,成功破发权重较大,球员表现较为注重回球得分,定义为回球因子
    因子2在二发得分,首盘告负权重较大,球员表现在先失球后赢球,较为抗压,定义为抗压因子
    因子3在抢七权重较大,定义为抢七因子
    因子4在首盘获胜,决胜盘权重较大,球员表现在顺风局获胜概率大,定义为顺风因子

    1. 将各球员表现转化为因子得分
    #将各球员表现转化为因子得分
    score = pd.DataFrame(np.dot(data_zs,fas))
    score.columns = ['发球因子','回球因子','抗压因子','抢七因子','顺风因子']
    score['等级'] = data_m['等级']
    score.head()
    

    费德勒和纳达尔各因子(技术水平)对比

    from pyecharts import Radar
    c_schema=[]
    for i in score.columns[:-1]:
        dict = {}
        dict['name'] = i
        dict['max'] = score[i].max()
        dict['min'] = score[i].min()
        c_schema.append(dict)
    c_schema
    radar1 = Radar('费纳技术对比')
    radar1.config(c_schema=c_schema)
    color = ['#50514F','#F25F5C']
    radar1.add('纳达尔',[score.iloc[0,:-1]],is_area_show=True,area_opacity=0.6,area_color='#F25F5C')
    radar1.add('费德勒',[score.iloc[1,:-1]],is_area_show=True,area_opacity=0.6,area_color='#247BA0')
    radar1
    

    费德勒技术较为全面在抗压方面最为突出,纳达尔在回击球方面较为突出

    男性运动员各等级各项因子得分

    #各等级各项因子得分
    score_top = score.groupby('等级').mean()
    radar2 = Radar('男性网球运动各项因子均值')
    radar2.config(c_schema=c_schema)
    color = ['#D63E34','#304454','#619FA8','#D48465']
    for i in range(len(score_top)):
        radar2.add(score_top.index[i],[score_top.iloc[i]],is_area_show=True,area_opacity=0.6,area_color=color[i])
    radar2
    

    排名靠前的运动员全面领先其他运动

    使用决策树选择影响排名的重要因素

    from sklearn.tree import DecisionTreeClassifier
    dt = DecisionTreeClassifier(max_depth=3)
    dt.fit(score.iloc[:,:-1],score.iloc[:,-1:])
    pd.Series(dt.feature_importances_,index=score.columns[:-1])
    

    发球因子 0.352640
    回球因子 0.088491
    抗压因子 0.329660
    抢七因子 0.164658
    顺风因子 0.064551
    对排名影响最大的变量分别为发球,抗压和抢七

    绘制决策树

    from sklearn import tree
    from sklearn.externals.six import StringIO
    import graphviz
    dot_data = StringIO()
    tree.export_graphviz(dt, out_file=dot_data,  
                                             feature_names=score.columns[:-1],  
                                             class_names=['top25','top25-50','top50-75','top75-100'],  
                                             filled=True, rounded=True, 
                                             special_characters=True)
    
    graph = graphviz.Source(dot_data.getvalue())  
    graph
    

    相关文章

      网友评论

          本文标题:决策树-网球运动员排名分析

          本文链接:https://www.haomeiwen.com/subject/ljewrqtx.html