做爲天池上的新手,第一次參加天池阿里雲線上的比賽,糖尿病預測,html
通常的數據挖掘比賽,流程:數據清洗,特徵工程(找特徵,特徵組合),不斷的嘗試的不一樣算法,不斷調參,也能夠考慮將多個模型進行線性組合算法
大賽初賽數據共包含兩個文件,訓練文件d_train.csv和測試文件d_test.csv,每一個文件第一行是字段名,以後每一行表明一個個體。文件共包含42個字段,包含數值型、字符型、日期型等衆多數據類型,部分字段內容在部分人羣中有缺失,其中第一列爲個體ID號。訓練文件的最後一列爲標籤列,既須要預測的目標血糖值。網絡
初賽是關於利用特徵預測血糖值,以csv格式文件進行提交。app
下面直接切入正題:post
代碼文件:xgboost_test.py,將代碼放在新建項目下,並新建一個文件夾data,原始的數據放在data文件夾中。最終結果會保存在當前項目的目錄下.csv文件。測試
算法思路:單模型+原始33個特徵阿里雲
(1) 最初想法:使用最近鄰的插補方法,即找一條與空缺值相近的且完整的記錄對空缺數據的進行插補,將插補後的數據和原始的未插補的數據都帶入算法模型中進行驗證,發現插補後的數據偏差較大,果斷放棄。最終仍然使用的是原始的帶空缺值的數據用於訓練模型。人工智能
(2) 在公佈a榜測試集答案後,把a榜的數據做爲訓練集,把訓練集拼接起來,增長了訓練集的樣本數量。url
(3) 因爲最開始的訓練集中存在血糖值異常大的記錄,刪除訓練集中血糖爲38的那一行。因爲與乙肝的缺失值太多,且相關性不高,所以刪除了乙肝等5個特徵屬性,以及刪除了‘id’、‘性別’、‘體檢日期’特徵屬性。spa
(4) 在開始部分計算了各個特徵與‘血糖’的Persona相關性係數,去相關係數較大的幾個特徵用於訓練模型,發現效果不及用33個特徵。所以算法模型採用的33個特徵,進行血糖的預測。
(5) 在不斷嘗試過catboost,LightGBM ,神經網絡等基本的算法模型和調參後,發現使用xgboost效果的最好,在無數次不斷調參後,達到最優的效果,及最終的成績86名|0.6316
最終比較幸運的初賽86名,進入複賽
代碼:
1 import pandas as pd 2 import xgboost as xgb 3 from sklearn.metrics import mean_squared_error 4 5 # 將兩部分的訓練集train1,train2共同組合成總得訓練集train 6 train1=pd.read_csv(r"data/d_train_20180102.csv",encoding='gbk') 7 # 合併訓練集 8 train2_1=pd.read_csv(r"data/d_test_A_20180102.csv",encoding='gbk') 9 train2_2=pd.read_csv(r"data/d_answer_a_20180128.csv",encoding="gbk",header=None) 10 train2_2.rename(columns={0:'血糖'},inplace=True) #取名「血糖」 11 train2=pd.concat([train2_1,train2_2],axis=1) 12 train=pd.concat([train1,train2],axis=0) 13 14 # 刪除特別大的‘血糖’異常值 15 columns=len(train.columns) 16 train.drop(train.index[[i for i in train.index if train.iloc[i,columns-1]>30]],inplace=True) 17 # 測試集 18 test=pd.read_csv(r"data/d_test_B_20180128.csv",encoding='gbk') 19 # validate=pd.read_csv(r"data/d_answer_b_20180130.csv",encoding='utf-8',header=None) 20 del_feat=['性別','體檢日期','乙肝表面抗原', '乙肝表面抗體', '乙肝e抗原', '乙肝e抗體', '乙肝核心抗體'] 21 # 刪除特徵 22 feat=[] 23 for i in train.columns: 24 if i not in del_feat: 25 feat.append(i) 26 train=train[feat] 27 feat.remove('血糖') #測試集不須要‘血糖’屬性 28 test=test[feat] 29 30 y_train = train["血糖"] 31 x_train = train.drop(['id','血糖'], axis=1) 32 y_test = test.drop('id', axis=1) 33 34 # training xgboost 35 dtrain = xgb.DMatrix(x_train, label=y_train) 36 dtest = xgb.DMatrix(y_test) 37 38 params = {'booster': 'gbtree', 39 'objective': 'reg:linear', 40 'eval_metric': 'rmse', 41 'max_depth': 6,#一般取值:3-10 42 'gamma':0.2,#給定了所需的最低loss function的值 43 'lambda': 100, 44 'subsample': 1,#用於訓練模型的子樣本佔整個樣本集合的比例 45 'colsample_bytree': 0.6, 46 'min_child_weight': 12, # 5~10,孩子節點中最小的樣本權重和,即調大這個參數可以控制過擬合 47 'eta': 0.02,#更新過程當中用到的收縮步長,取值範圍爲:[0,1] 48 'sample_type': 'uniform', 49 'normalize': 'tree', 50 'rate_drop': 0.1, 51 'skip_drop': 0.9, 52 'seed': 100, 53 'nthread':-1 54 } 55 56 bst_nb = 700 57 watchlist = [(dtrain, '訓練偏差')] 58 model = xgb.train(params, dtrain, num_boost_round=bst_nb, evals=watchlist) # 訓練模型 59 60 y_pred = model.predict(dtest) 61 62 # print((mean_squared_error(validate,y_pred))/2) 63 y_predDF=pd.DataFrame({None:y_pred}) 64 y_predDF.to_csv("SMUDMers_test_B_res.csv",header=None,index=False,float_format="%.2f")
順便把大佬們的思路粘貼一下: