1. 程式人生 > >數據競賽實戰(1)——足球運動員身價估計

數據競賽實戰(1)——足球運動員身價估計

metrics 帶來 href positions speed tro 目的 失去 filename

前言

1,背景介紹

  每個足球運動員在轉會市場都有各自的價碼。本次數據練習的目的是根據球員的各項信息和能力來預測該球員的市場價值。

2,數據來源

  FIFA2018

3,數據文件說明

  數據文件分為三個:

train.csv       訓練集    文件大小為2.20mb

test.csv     預測集   文件大小為1.44kb

sample_submit.csv   提交示例 文件大小為65kb

  訓練集共有10441條樣本,預測集中有7000條樣本。每條樣本代表一位球員,數據中每個球員

有61項屬性。數據中含有缺失值。

4,數據變量說明

id 行編號,沒有實際意義
club 該球員所屬的俱樂部。該信息已經被編碼。
league 該球員所在的聯賽。已被編碼。
birth_date 生日。格式為月/日/年。
height_cm 身高(厘米)
weight_kg 體重(公斤)
nationality 國籍。已被編碼。
potential 球員的潛力。數值變量。
pac 球員速度。數值變量。
sho 射門(能力值)。數值變量。
pas 傳球(能力值)。數值變量。
dri 帶球(能力值)。數值變量。
def 防守(能力值)。數值變量。
phy 身體對抗(能力值)。數值變量。
international_reputation 國際知名度。數值變量。
skill_moves 技巧動作。數值變量。
weak_foot 非慣用腳的能力值。數值變量。
work_rate_att 球員進攻的傾向。分類變量,Low, Medium, High。
work_rate_def 球員防守的傾向。分類變量,Low, Medium, High。
preferred_foot 慣用腳。1表示右腳、2表示左腳。
crossing 傳中(能力值)。數值變量。
finishing 完成射門(能力值)。數值變量。
heading_accuracy 頭球精度(能力值)。數值變量。
short_passing 短傳(能力值)。數值變量。
volleys 淩空球(能力值)。數值變量。
dribbling 盤帶(能力值)。數值變量。
curve 弧線(能力值)。數值變量。
free_kick_accuracy 定位球精度(能力值)。數值變量。
long_passing 長傳(能力值)。數值變量。
ball_control 控球(能力值)。數值變量。
acceleration 加速度(能力值)。數值變量。
sprint_speed 沖刺速度(能力值)。數值變量。
agility 靈活性(能力值)。數值變量。
reactions 反應(能力值)。數值變量。
balance 身體協調(能力值)。數值變量。
shot_power 射門力量(能力值)。數值變量。
jumping 彈跳(能力值)。數值變量。
stamina 體能(能力值)。數值變量。
strength 力量(能力值)。數值變量。
long_shots 遠射(能力值)。數值變量。
aggression 侵略性(能力值)。數值變量。
interceptions 攔截(能力值)。數值變量。
positioning 位置感(能力值)。數值變量。
vision 視野(能力值)。數值變量。
penalties 罰點球(能力值)。數值變量。
marking 卡位(能力值)。數值變量。
standing_tackle 斷球(能力值)。數值變量。
sliding_tackle 鏟球(能力值)。數值變量。
gk_diving 門將撲救(能力值)。數值變量。
gk_handling 門將控球(能力值)。數值變量。
gk_kicking 門將開球(能力值)。數值變量。
gk_positioning 門將位置感(能力值)。數值變量。
gk_reflexes 門將反應(能力值)。數值變量。
rw 球員在右邊鋒位置的能力值。數值變量。
rb 球員在右後衛位置的能力值。數值變量。
st 球員在射手位置的能力值。數值變量。
lw 球員在左邊鋒位置的能力值。數值變量。
cf 球員在鋒線位置的能力值。數值變量。
cam 球員在前腰位置的能力值。數值變量。
cm 球員在中場位置的能力值。數值變量。
cdm 球員在後腰位置的能力值。數值變量。
cb 球員在中後衛的能力值。數值變量。
lb 球員在左後衛置的能力值。數值變量。
gk 球員在守門員的能力值。數值變量。
y 該球員的市場價值(單位為萬歐元)。這是要被預測的數值。

5,評估方法

技術分享圖片

數據預處理

  此處實戰一下數據預處理的理論知識點:請點擊知識點1,或者知識點2

1,本文數據預處理的主要步驟

  • (1) 刪除和估算缺失值(removing and imputing missing values)
  • (2)獲取分類數據(Getting categorical data into shape for machine learning)
  • (3)為模型構建選擇相關特征(Selecting relevant features for the module construction)
  • (4)對原表的年份數據進行填充,比如格式是這樣的09/10/89 ,因為要計算年齡,所以補為完整的09/10/1989
  • (5)將體重和身高轉化為BMI指數
  • (6)將球員在各個位置上的能力值轉化為球員最擅長位置上的得分

2,分類數據處理

  sklearn的官網地址:請點擊我

  對於定量特征,其包含的有效信息為區間劃分,例如本文中work_rate_att 和 work_rate_def 他們分別代表了球員進攻的傾向和球員防守的傾向。用Low,Medium,High表示。所以我們可能會將其轉化為0 , 1,2 。

技術分享圖片

  這裏使用標簽編碼來處理,首先舉例說明一下標簽編碼

from sklearn import preprocessing

labelEncoding = preprocessing.LabelEncoder()
labelEncoding.fit([‘Low‘,‘Medium‘,‘High‘])
res = labelEncoding.transform([‘Low‘,‘Medium‘,‘High‘,‘High‘,‘Low‘,‘Low‘])
print(res)
#    [1 2 0 0 1 1]

  又或者自己編碼:

import pandas as pd

df = pd.DataFrame([
            [‘green‘, ‘M‘, 10.1, ‘class1‘],
            [‘red‘, ‘L‘, 13.5, ‘class2‘],
            [‘blue‘, ‘XL‘, 15.3, ‘class1‘]])
print(df)
df.columns = [‘color‘, ‘size‘, ‘prize‘, ‘class label‘]
size_mapping = {
    ‘XL‘:3,
    ‘L‘:2,
    ‘M‘:1
}

df[‘size‘] = df[‘size‘].map(size_mapping)
print(df)
class_mapping = {label:ind for ind,label in enumerate(set(df[‘class label‘]))}
df[‘class label‘] = df[‘class label‘].map(class_mapping)

print(df)
‘‘‘
       0   1     2       3
0  green   M  10.1  class1
1    red   L  13.5  class2
2   blue  XL  15.3  class1


   color  size  prize class label
0  green     1   10.1      class1
1    red     2   13.5      class2
2   blue     3   15.3      class1


   color  size  prize  class label
0  green     1   10.1            0
1    red     2   13.5            1
2   blue     3   15.3            0
‘‘‘

  上面使用了兩種方法,一種是將分類數據轉換為數值型數據,一種是編碼分類標簽。

3,缺失值處理

3.1 統計空值情況

#using isnull() function to check NaN value 
df.isnull().sum()

  本文中空值如下:

gk_positioning                 0
gk_reflexes                    0
rw                          1126
rb                          1126
st                          1126
lw                          1126
cf                          1126
cam                         1126
cm                          1126
cdm                         1126
cb                          1126
lb                          1126
gk                          9315
y                              0
Length: 65, dtype: int64

  

3.2 消除缺失值 dropna() 函數

  一個最簡單的處理缺失值的方法就是直接刪掉相關的特征值(一列數據)或者相關的樣本(一行數據)。利用dropna()函數實現。

# 參數axis 表示軸選擇,axis = 0 代表行    axis = 1 代表列

df.dropna(axis = 1)

df.dropna(axis = 0)


# how參數選擇刪除行列數據(any / all)

dropna(how = all) 


# 刪除值少於int個數的值
dropna(thresh = int)


# subset = [‘ ‘]  刪除指定列中有空值的一行數據(整個樣本)

  雖然直接刪除很簡單,但是直接刪除會帶來很多弊端。比如樣本值刪除太多導致不能進行可靠預測;或者特征值刪除太多(列數據)可能會失去很多有價值的信息。

3.3 插值法 interpolation techniques

  比較常用的一種估值是平均值估計(mean imputation)。可以直接使用sklearn庫中的imputer類實現。

class sklearn.preprocessing .Imputer

(missing_values = ‘NaN‘, strategy = ‘mean‘, axis = 0, verbose = 0, copy = True)

miss_values :int 或者 NaN ,默認NaN(string類型)

strategy :默認mean。平均值填補
    可選項:mean(平均值)
                median(中位數)
                most_frequent(眾數)

axis : 指定軸向。axis = 0 列向(默認)   axis =1 行向

verbose :int 默認值為0

copy :默認True ,創建數據集的副本
                False:在任何合適的地方都可能進行插值

  下面舉例說明:

# 創建CSV數據集
import pandas as pd
from io import StringIO
import warnings

warnings.filterwarnings(‘ignore‘)

# 數據不要打空格,IO流會讀入空格
csv_data = ‘‘‘
A,B,C,D
1.0,2.0,3.0,4.0
5.0,6.0,,8.0
10.0,11.0,12.0,
‘‘‘

df = pd.read_csv(StringIO(csv_data))
print(df)

# 均值填充
from sklearn.preprocessing import Imputer
# axis = 0 表示列向 ,采用每一列的平均值填充空值
imr = Imputer(missing_values=‘NaN‘,strategy=‘mean‘,axis=0)
imr = imr.fit(df.values)
imputed_data = imr.transform(df.values)
print(imputed_data)
‘‘‘
      A     B     C    D
0   1.0   2.0   3.0  4.0
1   5.0   6.0   NaN  8.0
2  10.0  11.0  12.0  NaN

[[ 1.   2.   3.   4. ]
 [ 5.   6.   7.5  8. ]
 [10.  11.  12.   6. ]]
 ‘‘‘

  

4,將出生日期轉化為年齡

  如下,在這個比賽中,獲取的數據中出現了出生日期的Series,下面我們對其進行轉化。

技術分享圖片

  下面我截取了一部分數據:

技術分享圖片

  從數據來看,‘11/6/86’之類的數,最左邊的數表示月份,中間表示日,最後的數表示年。

  實際上我們在分析時候並不需要人的出生日期,而是需要年齡,不同的年齡階段會有不同的狀態,有可能age就是一個很好地特征工程指示變量。

  那麽如何將birth轉化為age呢?這裏使用到datetime這個庫。

4.1 首先把birth_date轉化為標準時間格式

    # 將出生年月日轉化為年齡
    traindata[‘birth_date‘] = pd.to_datetime(traindata[‘birth_date‘])
    print(traindata)

  結果如下:

技術分享圖片

4.2 獲取當前時間的年份,並減去birth_date 的年份

    # 獲取當前的年份
    new_year = dt.datetime.today().year
    traindata[‘birth_date‘] = new_year - traindata.birth_date.dt.year
    print(traindata)

  這裏使用了dt.datetime.today().year來獲取當前日期的年份,然後將birth數據中的年份數據提取出來(frame.birth.dt.year),兩者相減就得到需要的年齡數據,如下:

技術分享圖片

5,身高體重轉化為BMI

  官方的標桿模型對身高體重的處理使用的是BMI指數。

  BMI指數是身體質量指數,是目前國際上常用的衡量人體胖瘦程度以及是否健康的一個標準。

技術分享圖片

技術分享圖片

  這裏直接計算,公式如下:

# 計算球員的身體質量指數(BMI)
train[‘BMI‘] = 10000. * train[‘weight_kg‘] / (train[‘height_cm‘] ** 2)
test[‘BMI‘] = 10000. * test[‘weight_kg‘] / (test[‘height_cm‘] ** 2)

  

6,將球員各個位置上的評分轉化為球員最擅長位置的評分

  目前打算將這11個特征轉化為球員最擅長位置上的評分,這裏計算方式只會取這11個特征中的最大值,當然這裏也省去了對缺失值的判斷,經過對數據的研究,我們發現有門將和射門球員的區分,如果使用最擅長位置的話就省去了這一步,但是如果這樣直接取最大值的話會隱藏一些特征。

技術分享圖片

# 獲得球員最擅長位置上的評分
positions = [‘rw‘,‘rb‘,‘st‘,‘lw‘,‘cf‘,‘cam‘,‘cm‘,‘cdm‘,‘cb‘,‘lb‘,‘gk‘]

train[‘best_pos‘] = train[positions].max(axis =1)
test[‘best_pos‘] = test[positions].max(axis = 1)

  

重要特征提取及其模型訓練

1,使用隨機森林提取重要特征

# 提取重要性特征
def RandomForestExtractFeature(traindata):
    from sklearn.model_selection import train_test_split
    from sklearn.ensemble import RandomForestClassifier
    print(type(traindata))  # <class ‘numpy.ndarray‘>
    X,y = traindata[:,1:-1],traindata[:,-1]

    X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=0)
    # n_estimators 森林中樹的數量
    forest = RandomForestClassifier(n_estimators=100000,random_state=0,n_jobs=1)
    forest.fit(X_train,y_train.astype(‘int‘))
    importances = forest.feature_importances_
    return importances

  

模型訓練及其結果展示

1,自己的Xgboost,沒有做任何處理

#_*_ coding:utf-8_*_
import pandas as pd
import warnings

warnings.filterwarnings(‘ignore‘)

# 導入數據,並處理非數值型數據
def load_dataSet(filename):
    ‘‘‘
            檢查數據,發現出生日期是00/00/00類型,
            work_rate_att  work_rate_def 是Medium High Low
            下面對這三個數據進行處理
            然後對gk
            :return:
            ‘‘‘
    # 讀取訓練集
    traindata = pd.read_csv(filename,header=0)

    # 處理非數值型數據
    label_mapping = {
        ‘Low‘:0,
        ‘Medium‘:1,
        ‘High‘:2
    }
    traindata[‘work_rate_att‘] = traindata[‘work_rate_att‘].map(label_mapping)
    traindata[‘work_rate_def‘] = traindata[‘work_rate_def‘].map(label_mapping)

    # 將出生年月日轉化為年齡
    traindata[‘birth_date‘] = pd.to_datetime(traindata[‘birth_date‘])
    import datetime as dt
    # 獲取當前的年份
    new_year = dt.datetime.today().year
    traindata[‘birth_date‘] = new_year - traindata.birth_date.dt.year

    # 處理缺失值
    res = traindata.isnull().sum()
    from sklearn.preprocessing import Imputer
    imr = Imputer(missing_values=‘NaN‘,strategy=‘mean‘,axis=0)
    imr = imr.fit(traindata.values)
    imputed_data = imr.transform(traindata.values)
    return imputed_data


# 直接訓練回歸模型
def xgboost_train(traindata,testdata):
    from sklearn.model_selection import train_test_split
    import xgboost as xgb
    from xgboost import plot_importance
    from matplotlib import pyplot as plt
    from sklearn.externals import joblib
    from sklearn.metrics import mean_squared_error
    from sklearn.metrics import r2_score
    X, y = traindata[:, 1:-1], traindata[:, -1]
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1234567)
    # n_estimators 森林中樹的數量
    model = xgb.XGBRegressor(max_depth=5,learning_rate=0.1,n_estimators=160,
                             silent=True,objective=‘reg:gamma‘)
    model.fit(X_train,y_train)
    # 對測試集進行預測
    y_pred = model.predict(X_test)
    # print(y_pred)
    # 計算準確率,下面的是計算模型分類的正確率,
    MSE = mean_squared_error(y_test, y_pred)
    print("accuaracy is %s "%MSE)
    R2 = r2_score(y_test,y_pred)
    print(‘r2_socre is %s‘%R2)
    # test_pred = model.predict(testdata[:,1:])
    # 顯示重要特征
    # plot_importance(model)
    # plt.show()

    # 保存模型
    joblib.dump(model,‘Xgboost.m‘)

# 使用模型預測數據
def predict_data(xgbmodel,testdata,submitfile):
    import numpy as np
    ModelPredict = np.load(xgbmodel)
    test = testdata[:,1:]
    predict_y = ModelPredict.predict(test)
    submit_data = pd.read_csv(submitfile)
    submit_data[‘y‘] = predict_y
    submit_data.to_csv(‘my_SVM_prediction.csv‘, index=False)
    return predict_y


if __name__ == ‘__main__‘:
    TrainFile= ‘data/train.csv‘
    TestFile = ‘data/test.csv‘
    SubmitFile = ‘submit1.csv‘
    xgbmodel = ‘Xgboost.m‘
    TrainData = load_dataSet(TrainFile)
    TestData = load_dataSet(TestFile)
    # RandomForestExtractFeature(TrainData)
    xgboost_train(TrainData,TestData)
    predict_data(xgbmodel,TestData,SubmitFile)

  

技術分享圖片

2,隨機森林標桿模型

整理此隨機森林訓練模型的亮點

  • 1,將出生年月日轉化為球員的歲數(數據處理必須的)
  • 2,將球員在各個位置的能力使用球員最擅長的位置表示(!!此處有待商榷)
  • 3,利用球員的身體質量指數(BMI)來代替球員體重和身高這兩個特征值
  • 4,根據數據判斷,發現各個位置的球員缺失值主要判斷是否為守門員,此處按照是否為守門員來分別訓練隨機森林
  • 5,最終使用height_cm(身高),weight_kg(體重),potential(潛力),BMI(球員身體指數),phy(身體對抗能力),international_reputation(國際知名度),age(年齡),best_pos(最佳位置)這9個特征來預測結果

#_*_coding:utf-8_*_
import pandas as pd
import numpy as np
import datetime as dt
from sklearn.ensemble import RandomForestRegressor

# 讀取數據
train = pd.read_csv(‘data/train.csv‘)
test = pd.read_csv(‘data/test.csv‘)
submit = pd.read_csv(‘data/sample_submit.csv‘)

# 獲得球員年齡
today = dt.datetime.today().year

train[‘birth_date‘] = pd.to_datetime(train[‘birth_date‘])
train[‘age‘] = today - train.birth_date.dt.year

test[‘birth_date‘] = pd.to_datetime(test[‘birth_date‘])
test[‘age‘] = today - test.birth_date.dt.year

# 獲取球員最擅長位置的評分
positions = [‘rw‘,‘rb‘,‘st‘,‘lw‘,‘cf‘,‘cam‘,‘cm‘,‘cdm‘,‘cb‘,‘lb‘,‘gk‘]

train[‘best_pos‘] = train[positions].max(axis=1)
test[‘best_pos‘] = test[positions].max(axis=1)

# 計算球員的身體質量指數(BMI)
train[‘BMI‘] = 10000. * train[‘weight_kg‘] / (train[‘height_cm‘] ** 2)
test[‘BMI‘] = 10000. * test[‘weight_kg‘] / (test[‘height_cm‘] ** 2)

# 判斷一個球員是否是守門員
train[‘is_gk‘] = train[‘gk‘] > 0
test[‘is_gk‘] = test[‘gk‘] > 0

# 用多個變量準備訓練隨機森林
test[‘pred‘] = 0
cols =  [‘height_cm‘, ‘weight_kg‘, ‘potential‘, ‘BMI‘, ‘pac‘,
        ‘phy‘, ‘international_reputation‘, ‘age‘, ‘best_pos‘]


# 用非守門員的數據訓練隨機森林
reg_ngk = RandomForestRegressor(random_state=100)
reg_ngk.fit(train[train[‘is_gk‘] == False][cols] , train[train[‘is_gk‘] == False][‘y‘])

preds = reg_ngk.predict(test[test[‘is_gk‘] == False][cols])
test.loc[test[‘is_gk‘] == False , ‘pred‘] = preds

# 用守門員的數據訓練隨機森林
reg_gk = RandomForestRegressor(random_state=100)
reg_gk.fit(train[train[‘is_gk‘] == True][cols] , train[train[‘is_gk‘] == True][‘y‘])

preds = reg_gk.predict(test[test[‘is_gk‘] == True][cols])
test.loc[test[‘is_gk‘] == True , ‘pred‘] = preds

# 輸出預測值
submit[‘y‘] = np.array(test[‘pred‘])
submit.to_csv(‘my_RF_prediction.csv‘,index = False)

  

為什麽會有兩個結果?

  這裏解釋一下,因為這裏的標桿模型中的年齡的取值,是我以目前的時間為準,而不是以作者給的2018年為準,可能因為差了一歲導致球員的黃金年齡不同,價值也就不同。

技術分享圖片

技術分享圖片

隨機森林調參(網格搜索)

#_*_coding:utf-8_*_
import pandas as pd
import numpy as np
import datetime as dt
from sklearn.ensemble import RandomForestRegressor

# 讀取數據
train = pd.read_csv(‘data/train.csv‘)
test = pd.read_csv(‘data/test.csv‘)
submit = pd.read_csv(‘data/sample_submit.csv‘)

# 獲得球員年齡
today = dt.datetime.today().year

train[‘birth_date‘] = pd.to_datetime(train[‘birth_date‘])
train[‘age‘] = today - train.birth_date.dt.year

test[‘birth_date‘] = pd.to_datetime(test[‘birth_date‘])
test[‘age‘] = today - test.birth_date.dt.year

# 獲取球員最擅長位置的評分
positions = [‘rw‘,‘rb‘,‘st‘,‘lw‘,‘cf‘,‘cam‘,‘cm‘,‘cdm‘,‘cb‘,‘lb‘,‘gk‘]

train[‘best_pos‘] = train[positions].max(axis=1)
test[‘best_pos‘] = test[positions].max(axis=1)

# 計算球員的身體質量指數(BMI)
train[‘BMI‘] = 10000. * train[‘weight_kg‘] / (train[‘height_cm‘] ** 2)
test[‘BMI‘] = 10000. * test[‘weight_kg‘] / (test[‘height_cm‘] ** 2)

# 判斷一個球員是否是守門員
train[‘is_gk‘] = train[‘gk‘] > 0
test[‘is_gk‘] = test[‘gk‘] > 0

# 用多個變量準備訓練隨機森林
test[‘pred‘] = 0
cols =  [‘height_cm‘, ‘weight_kg‘, ‘potential‘, ‘BMI‘, ‘pac‘,
        ‘phy‘, ‘international_reputation‘, ‘age‘, ‘best_pos‘]

# 用非守門員的數據訓練隨機森林
# 使用網格搜索微調模型
from sklearn.model_selection import GridSearchCV
param_grid = [
    {‘n_estimators‘:[3,10,30], ‘max_features‘:[2,4,6,8]},
    {‘bootstrap‘:[False], ‘n_estimators‘:[3,10],‘max_features‘:[2,3,4]}
]
forest_reg = RandomForestRegressor()
grid_search = GridSearchCV(forest_reg, param_grid ,cv=5,
                           scoring=‘neg_mean_squared_error‘)

grid_search.fit(train[train[‘is_gk‘] == False][cols] , train[train[‘is_gk‘] == False][‘y‘])

preds = grid_search.predict(test[test[‘is_gk‘] == False][cols])
test.loc[test[‘is_gk‘] == False , ‘pred‘] = preds

# 用守門員的數據訓練隨機森林
# 使用網格搜索微調模型
from sklearn.model_selection import GridSearchCV
‘‘‘
先對estimators進行網格搜索,[3,10,30]
接著對最大深度max_depth 
內部節點再劃分所需要最小樣本數min_samples_split 進行網格搜索
最後對最大特征數,ax_features進行調參
‘‘‘
param_grid1 = [
    {‘n_estimators‘:[3,10,30], ‘max_features‘:[2,4,6,8]},
    {‘bootstrap‘:[False], ‘n_estimators‘:[3,10],‘max_features‘:[2,3,4]}
]
‘‘‘
parm_grid 告訴Scikit-learn 首先評估所有的列在第一個dict中的n_estimators 和
max_features的 3*4=12 種組合,然後嘗試第二個dict中的超參數2*3 = 6 種組合,
這次會將超參數bootstrap 設為False 而不是True(後者是該超參數的默認值)

總之,網格搜索會探索 12 + 6 = 18 種RandomForestRegressor的超參數組合,會訓練
每個模型五次,因為使用的是五折交叉驗證,換句話說,訓練總共有18 *5 = 90 輪,、
將花費大量的時間,完成後,就可以得到參數的最佳組合了
‘‘‘
forest_reg1 = RandomForestRegressor()
grid_search1 = GridSearchCV(forest_reg, param_grid1 ,cv=5,
                           scoring=‘neg_mean_squared_error‘)

grid_search1.fit(train[train[‘is_gk‘] == True][cols] , train[train[‘is_gk‘] == True][‘y‘])

preds = grid_search1.predict(test[test[‘is_gk‘] == True][cols])
test.loc[test[‘is_gk‘] == True , ‘pred‘] = preds

# 輸出預測值
submit[‘y‘] = np.array(test[‘pred‘])
submit.to_csv(‘my_RF_prediction1.csv‘,index = False)

# 打印參數的最佳組合
print(grid_search.best_params_)

  

技術分享圖片

3,決策樹標桿模型(四個特征)

整理此決策樹訓練模型的亮點

  • 1,將出生年月日轉化為球員的歲數(數據處理必須的)
  • 2,將球員在各個位置的能力使用球員最擅長的位置表示(!!此處有待商榷)
  • 3,直接使用潛力,國際知名度,年齡,最擅長位置評分這四個變量建立決策樹(我覺得有點草率)
#_*_coding:utf-8_*_
import  pandas as pd
import datetime as dt
from sklearn.tree import DecisionTreeRegressor

# 讀取數據
train = pd.read_csv(‘data/train.csv‘)
test = pd.read_csv(‘data/test.csv‘)
submit = pd.read_csv(‘data/sample_submit.csv‘)


# 獲得球員年齡
today = dt.datetime.today().year

train[‘birth_date‘] = pd.to_datetime(train[‘birth_date‘])
train[‘age‘] = today - train.birth_date.dt.year

test[‘birth_date‘] = pd.to_datetime(test[‘birth_date‘])
test[‘age‘] = today - test.birth_date.dt.year

# 獲得球員最擅長位置上的評分
positions = [‘rw‘,‘rb‘,‘st‘,‘lw‘,‘cf‘,‘cam‘,‘cm‘,‘cdm‘,‘cb‘,‘lb‘,‘gk‘]

train[‘best_pos‘] = train[positions].max(axis =1)
test[‘best_pos‘] = test[positions].max(axis = 1)

# 用潛力,國際知名度,年齡,最擅長位置評分 這四個變量來建立決策樹模型
col = [‘potential‘,‘international_reputation‘,‘age‘,‘best_pos‘]

reg = DecisionTreeRegressor(random_state=100)
reg.fit(train[col],train[‘y‘])

# 輸出預測值
submit[‘y‘] = reg.predict(test[col])
submit.to_csv(‘my_DT_prediction.csv‘,index=False)

  結果如下:

技術分享圖片

技術分享圖片

數據競賽實戰(1)——足球運動員身價估計