感謝做者分享-http://bjbsair.com/2020-04-07/tech-info/30750.htmlhtml
前言react
1,背景介紹
每一個足球運動員在轉會市場都有各自的價碼。本次數據練習的目的是根據球員的各項信息和能力來預測該球員的市場價值。git
FIFA2018github
3,數據文件說明
數據文件分爲三個:bootstrap
train.csv 訓練集 文件大小爲2.20MB數組
test.csv 預測集 文件大小爲1.44KBapp
sample_submit.csv 提交示例 文件大小爲65KBdom
訓練集共有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,評估方法
能夠參考博文:機器學習筆記:經常使用評估方法
傳送門:https://github.com/LeBron-Jian/sofasofa-learn
數據預處理
此處實戰一下數據預處理的理論知識點:請點擊知識點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)
爲何會有兩個結果?
隨機森林調參(網格搜索)
#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的 34=12 種組合,而後嘗試第二個dict中的超參數23 = 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)
結果以下:
感謝做者分享-http://bjbsair.com/2020-04-07/tech-info/30750.html
前言
1,背景介紹
每一個足球運動員在轉會市場都有各自的價碼。本次數據練習的目的是根據球員的各項信息和能力來預測該球員的市場價值。
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,評估方法
能夠參考博文:機器學習筆記:經常使用評估方法
傳送門:https://github.com/LeBron-Jian/sofasofa-learn
數據預處理
此處實戰一下數據預處理的理論知識點:請點擊知識點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)
爲何會有兩個結果?
隨機森林調參(網格搜索)
#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的 34=12 種組合,而後嘗試第二個dict中的超參數23 = 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)
結果以下:
感謝做者分享-http://bjbsair.com/2020-04-07/tech-info/30750.html
前言
1,背景介紹
每一個足球運動員在轉會市場都有各自的價碼。本次數據練習的目的是根據球員的各項信息和能力來預測該球員的市場價值。
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,評估方法
能夠參考博文:機器學習筆記:經常使用評估方法
傳送門:https://github.com/LeBron-Jian/sofasofa-learn
數據預處理
此處實戰一下數據預處理的理論知識點:請點擊知識點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)
爲何會有兩個結果?
隨機森林調參(網格搜索)
#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的 34=12 種組合,而後嘗試第二個dict中的超參數23 = 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)
結果以下:
感謝做者分享-http://bjbsair.com/2020-04-07/tech-info/30750.html
前言
1,背景介紹
每一個足球運動員在轉會市場都有各自的價碼。本次數據練習的目的是根據球員的各項信息和能力來預測該球員的市場價值。
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,評估方法
能夠參考博文:機器學習筆記:經常使用評估方法
傳送門:https://github.com/LeBron-Jian/sofasofa-learn
數據預處理
此處實戰一下數據預處理的理論知識點:請點擊知識點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)
爲何會有兩個結果?
隨機森林調參(網格搜索)
#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的 34=12 種組合,而後嘗試第二個dict中的超參數23 = 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)
結果以下:
感謝做者分享-http://bjbsair.com/2020-04-07/tech-info/30750.html
前言
1,背景介紹
每一個足球運動員在轉會市場都有各自的價碼。本次數據練習的目的是根據球員的各項信息和能力來預測該球員的市場價值。
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,評估方法
能夠參考博文:機器學習筆記:經常使用評估方法
傳送門:https://github.com/LeBron-Jian/sofasofa-learn
數據預處理
此處實戰一下數據預處理的理論知識點:請點擊知識點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)
爲何會有兩個結果?
隨機森林調參(網格搜索)
#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的 34=12 種組合,而後嘗試第二個dict中的超參數23 = 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)
結果以下:
感謝做者分享-http://bjbsair.com/2020-04-07/tech-info/30750.html
前言
1,背景介紹
每一個足球運動員在轉會市場都有各自的價碼。本次數據練習的目的是根據球員的各項信息和能力來預測該球員的市場價值。
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,評估方法
能夠參考博文:機器學習筆記:經常使用評估方法
傳送門:https://github.com/LeBron-Jian/sofasofa-learn
數據預處理
此處實戰一下數據預處理的理論知識點:請點擊知識點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)
爲何會有兩個結果?
隨機森林調參(網格搜索)
#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的 34=12 種組合,而後嘗試第二個dict中的超參數23 = 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)
結果以下:
感謝做者分享-http://bjbsair.com/2020-04-07/tech-info/30750.html
前言
1,背景介紹
每一個足球運動員在轉會市場都有各自的價碼。本次數據練習的目的是根據球員的各項信息和能力來預測該球員的市場價值。
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,評估方法
能夠參考博文:機器學習筆記:經常使用評估方法
傳送門:https://github.com/LeBron-Jian/sofasofa-learn
數據預處理
此處實戰一下數據預處理的理論知識點:請點擊知識點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)
爲何會有兩個結果?
隨機森林調參(網格搜索)
#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的 34=12 種組合,而後嘗試第二個dict中的超參數23 = 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)
結果以下:
感謝做者分享-http://bjbsair.com/2020-04-07/tech-info/30750.html
前言
1,背景介紹
每一個足球運動員在轉會市場都有各自的價碼。本次數據練習的目的是根據球員的各項信息和能力來預測該球員的市場價值。
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,評估方法
能夠參考博文:機器學習筆記:經常使用評估方法
傳送門:https://github.com/LeBron-Jian/sofasofa-learn
數據預處理
此處實戰一下數據預處理的理論知識點:請點擊知識點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)
爲何會有兩個結果?
隨機森林調參(網格搜索)
#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的 34=12 種組合,而後嘗試第二個dict中的超參數23 = 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)
結果以下:
感謝做者分享-http://bjbsair.com/2020-04-07/tech-info/30750.html
前言
1,背景介紹
每一個足球運動員在轉會市場都有各自的價碼。本次數據練習的目的是根據球員的各項信息和能力來預測該球員的市場價值。
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,評估方法
能夠參考博文:機器學習筆記:經常使用評估方法
傳送門:https://github.com/LeBron-Jian/sofasofa-learn
數據預處理
此處實戰一下數據預處理的理論知識點:請點擊知識點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)
爲何會有兩個結果?
隨機森林調參(網格搜索)
#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的 34=12 種組合,而後嘗試第二個dict中的超參數23 = 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)
結果以下:
感謝做者分享-http://bjbsair.com/2020-04-07/tech-info/30750.html
前言
1,背景介紹
每一個足球運動員在轉會市場都有各自的價碼。本次數據練習的目的是根據球員的各項信息和能力來預測該球員的市場價值。
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,評估方法
能夠參考博文:機器學習筆記:經常使用評估方法
傳送門:https://github.com/LeBron-Jian/sofasofa-learn
數據預處理
此處實戰一下數據預處理的理論知識點:請點擊知識點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)
爲何會有兩個結果?
隨機森林調參(網格搜索)
#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的 34=12 種組合,而後嘗試第二個dict中的超參數23 = 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)
結果以下:
感謝做者分享-http://bjbsair.com/2020-04-07/tech-info/30750.html
前言
1,背景介紹
每一個足球運動員在轉會市場都有各自的價碼。本次數據練習的目的是根據球員的各項信息和能力來預測該球員的市場價值。
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,評估方法
能夠參考博文:機器學習筆記:經常使用評估方法
傳送門:https://github.com/LeBron-Jian/sofasofa-learn
數據預處理
此處實戰一下數據預處理的理論知識點:請點擊知識點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)
爲何會有兩個結果?
隨機森林調參(網格搜索)
#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的 34=12 種組合,而後嘗試第二個dict中的超參數23 = 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)
結果以下: