其他
NBA球员薪资分析——基于随机森林算法(二)
本文作者:宋 骁
文字编辑:钱梦璇
导读
上篇文章中我们将NBA球员的技术统计和薪资数据做了一些前期的清理和分析,现在我们就要使用机器学习模型进行薪资的预测了。但是在将数据放入算法之前,需要对数据进行进一步的特征工程处理。由于特征中有一些是类别变量,算法本身无法处理。这里需要自定义一个函数将类别变量处理成哑变量,并且默认将样本量最大的类别作为参照组。
def convert_dummy(df, feature,rank=0):
'''
将类别变量转换为哑变量
'''
pos = pd.get_dummies(df[feature], prefix = feature)
mode = df[feature].value_counts().index[rank]
biggest = feature + '_' + str(mode)
pos.drop([biggest],axis = 1,inplace = True)
df.drop([feature],axis = 1,inplace = True)
df = df.join(pos)
return df
变量转换
建模前需要进行变量标准化,同时对Y进行对数转换。
stats_salary0 = stats_salary.copy()
stats_salary0.drop(['Player'],axis=1,inplace=True)
Y = stats_salary0.iloc[:,10]
X = stats_salary0.iloc[:,:10]
X = convert_dummy(X,'Pos')
from sklearn.preprocessing import RobustScaler
def robust_transfer(df):
Scaler = RobustScaler().fit(df)
newdf = Scaler.transform(df)
df0 = pd.DataFrame(newdf,columns = df.columns)
return df0
X = robust_transfer(X)
from scipy.stats import norm
from scipy import stats
sns.distplot(Y, fit=norm);
fig = plt.figure()
res = stats.probplot(Y, plot=plt)
Y = np.log1p(Y) # 对数转换
sns.distplot(Y , fit=norm);
fig = plt.figure()
res = stats.probplot(Y, plot=plt)
建模 —交叉验证
k折交叉验证是一种防止模型过拟合的方法,将数据集划分成k个相同大小的子样本,每次取出其中1份作为验证集,另k-1份作为训练集。这里,我们对数据人工划分训练集和测试集,并在训练集上进行10折交叉验证。
评价回归问题的度量指标通常为误差均方根(RMSE, root mean square error)与判定系数
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size = 0.3)
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import r2_score
from sklearn.model_selection import cross_val_score
#model.fit(x_train, y_train)
def print_r2(model,x,y,cv): # 模型, x, y, 交叉验证数
'''
交叉验证分数打印
'''
cvscore = cross_val_score(model, x, y, cv = cv,scoring='r2')
print(cv,'折交叉验证R2为',round(cvscore.mean(),3))
def print_rmse(model,x,y,cv): # 模型, x, y, 交叉验证数
'''
交叉验证分数打印
'''
cvscore = cross_val_score(model, x, y,
cv = cv,
scoring = 'neg_mean_squared_error')
nmse = cvscore.mean()
rmse0 = np.sqrt(-nmse)
print(cv,'折交叉验证RMSE为',round(rmse0,3))
rfr = RandomForestRegressor(n_estimators=100)
print_r2(rfr,x_train, y_train,10)
print_rmse(rfr,x_train, y_train,10)
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
def print_reg_metric(model,x_train,y_train,x_test,y_test,predict = False):
'''
打印测试集RMSE和R2
'''
rgf = model.fit(np.array(x_train),np.array(y_train))
ypred = rgf.predict(np.array(x_test))
rmse = np.sqrt(mean_squared_error(y_test, ypred))
r2 = r2_score(y_test, ypred)
print('测试集R2为%.3f, 测试集RMSE为%.3f'%(r2,rmse))
if predict:
name = stats_salary.iloc[x_test.index,0]
example = pd.DataFrame({'姓名': name,'真实薪资':np.expm1(y_test),
'预测薪资':np.expm1(ypred)})
return example.head(10)
print_reg_metric(rfr, x_train,y_train,x_test,y_test,predict = True)
建模 —变量重要性统计
下面比较对薪资贡献较大的统计指标:
dtree = rfr.fit(x_train, y_train)
values = sorted(zip(x_train.columns, rfr.feature_importances_), key = lambda x: x[1] * -1)
imp = pd.DataFrame(values,columns = ["Name", "Score"])
imp.sort_values(by = 'Score',inplace = True)
sns.scatterplot(x='Score',y='Name',linewidth=0,
data=imp,s = 30, color='red').set(
xlabel='Importance',
ylabel='Variables')
关于我们
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。