印度板球超级联赛(IPL)自2007年起由印度板球控制委员会(BCCI)创立,以其独特的20-20赛制和八支参赛队伍而闻名。IPL的特色之一是允许不同国家的球员组队参赛,这一直是许多球迷期待的场景。
IPL最初有八支队伍,分别是:皇家挑战者班加罗尔、超级国王钦奈、德干冲锋者、德里达雷魔鬼、国王XI旁遮普、骑士骑士加尔各答、印度人孟买和皇家拉贾斯坦。这些队伍的所有权最初通过拍卖决定,为期10年,起拍价为5000万美元。IPL制定了一些规则,比如只有国际和著名的印度球员才能被拍卖,每个球员都有一个基础价格,这个价格由各种表现指标决定。尽管IPL采用的是20-20赛制,但球员的基础价格可能受到他们在其他板球赛制(如一日国际赛和测试赛)中的表现的影响。
本文将尝试预测球员的拍卖价格,基于他们在其他板球赛制中过去的表现。使用的数据包含了2008年至2011年至少参加一个IPL赛季的130名球员的信息。
本节将讨论使用Python开发多变量线性回归模型的各个步骤。
从文件 "IPL IMB381IPL2013.csv" 加载数据,并打印元数据。
import numpy as np
import pandas as pd
ipl_au = pd.read_csv("IPL IMB381IPL2013.csv")
ipl_au.info()
数据显示有130个观测值和26列,没有缺失值。
由于列数较多,将显示前5行的前10列。使用 'iloc()' 函数来显示数据集的一个子集。
ipl_au.iloc[0:5,0:10]
可以构建一个模型来理解哪些球员特征影响他们的售价,或者预测未来球员的拍卖价格。将创建一个变量 x_features,其中包含将用于构建模型的特征列表,并忽略数据框的其他列。
在构建模型之前,需要将分类变量编码为虚拟变量。如果一个分类变量有n个类别,那么将需要n-1个虚拟变量。以 "playing-role" 为例,因为有四个类别,所以将需要三个虚拟变量。使用 'get_dummy()' 方法来创建虚拟变量。
cate_features = ['AGE', 'COUNTRY', 'PLAYING ROLE', 'CAPTAINCY EXP']
ipl_au_encoded_df = pd.get_dummies(ipl_au[x_features], columns=cate_features, drop_first=True)
数据集中包含了新创建的虚拟变量。可以将新特征重新分配给之前创建的 x_features 变量,以跟踪最终用于构建模型的所有特征。
在构建模型之前,将数据集按照80-20的比例分割。split函数允许使用random_state参数,这是一个随机种子函数。这里将使用42作为随机状态值。
from statsmodels import api as sm
from sklearn.model_selection import train_test_split
x = sm.add_constant(ipl_au_encoded_df)
y = ipl_au['SOLD PRICE']
X_train, X_test, Y_train, Y_test = train_test_split(x, y, test_size=0.8, random_state=42)
使用不同的随机值可能会得到不同的训练和测试数据,因此结果也会不同。
将使用训练数据集构建多变量线性回归(MLR)模型,并分析模型摘要。摘要提供了模型准确性、特征重要性和任何多重共线性效应的详细信息,将在下一节详细讨论。
ipl_model_1 = sm.OLS(Y_train, X_train).fit()
ipl_model_1.summary2()
在MLR模型中,根据p值(<0.05),只有HS、AGE_2、AVE和Country_ENG这几个特征显著。模型表明其他特征并不影响售价。这并不直观,可能是变量多重共线性的结果。为了获得更好的结果,需要处理多重共线性。让了解这是什么?
当数据集有大量独立变量时,这些独立变量中可能有一些高度相关。独立变量之间存在高度相关性被称为多重共线性。
多重共线性的存在可能会破坏多变量线性回归模型。识别多重共线性的存在并采取纠正措施是必要的。
方差膨胀因子是用于识别多重共线性存在的一种度量。可以使用statsmodels.stats.outliers_influence包中的variance_inflation_factor()方法来计算特征的VIF。
from statsmodels.stats.outliers_influence import variance_inflation_factor
def get_vif_factors(x):
x_matrix = x.to_numpy()
vif = [variance_inflation_factor(x_matrix, i) for i in range(x_matrix.shape[1])]
vif_factors = pd.DataFrame()
vif_factors['column'] = x.columns
vif_factors['VIF'] = vif
return vif_factors
现在,调用上述函数将返回相应特征的VIF。
可以生成一个相关性热图,以了解独立变量之间的相关性,这可以用来决定哪些特征包含在模型中。首先选择VIF值大于4的特征。
import seaborn as sn
import matplotlib.pyplot as plt
plt.figure(figsize=(12,10))
sn.heatmap(x[columns_with_large_vif].corr(), annot=True)
plt.title("heatmap depicting corr between features")
为了避免多重共线性,可以只保留每组高度相关变量中的一列,并移除其他列。已经决定移除以下特征。
columns_to_be_removed = ['T-RUNS', 'T-WKTS', 'RUNS-S', 'HS', 'AVE', 'RUNS-C', 'SR-B', 'AVE-BL', 'ECON', 'ODI-SR-B', 'ODI-RUNS-S', 'SR-BL', 'AGE_2']
x_new_features = list(set(x_features) - set(columns_to_be_removed))
最终变量集的VIF表明不再存在多重共线性。现在可以继续使用这组变量构建模型。
X_train = X_train[x_new_features]
ipl_model_2 = sm.OLS(Y_train, X_train).fit()
ipl_model_2.summary2()
根据p值,只有Country_IND、Country_ENG、SIXERS和CAPTAINCY EXP_1这几个变量在统计上显著。因此,决定售价的特征是:
让创建一个名为significant_vars的新列表,存储显著变量的列名,并构建一个新模型。
significant_vars = ['COUNTRY_ENG', 'COUNTRY_IND', 'SIXERS', 'CAPTAINCY EXP_1']
X_train = X_train[significant_vars]
ipl_model_3 = sm.OLS(Y_train, X_train).fit()
ipl_model_3.summary2()