作為天池上的新手,第一次參加天池阿里雲線上的比賽,糖尿病預測,
一般的數據挖掘比賽,流程:數據清洗,特征工程(找特征,特征組合),不斷的嘗試的不同算法,不斷調參,也可以考慮將多個模型進行線性組合
大賽初賽數據共包含兩個文件,訓練文件d_train.csv和測試文件d_test.csv,每個文件第一行是字段名,之后每一行代表一個個體。文件共包含42個字段,包含數值型、字符型、日期型等眾多數據類型,部分字段內容在部分人群中有缺失,其中第一列為個體ID號。訓練文件的最后一列為標簽列,既需要預測的目標血糖值。
初賽是關於利用特征預測血糖值,以csv格式文件進行提交。
下面直接切入正題:
代碼文件:xgboost_test.py,將代碼放在新建項目下,並新建一個文件夾data,原始的數據放在data文件夾中。最終結果會保存在當前項目的目錄下.csv文件。
算法思路:單模型+原始33個特征
(1) 最初想法:使用最近鄰的插補方法,即找一條與空缺值相近的且完整的記錄對空缺數據的進行插補,將插補后的數據和原始的未插補的數據都帶入算法模型中進行驗證,發現插補后的數據誤差較大,果斷放棄。最終仍然使用的是原始的帶空缺值的數據用於訓練模型。
(2) 在公布a榜測試集答案后,把a榜的數據作為訓練集,把訓練集拼接起來,增加了訓練集的樣本數量。
(3) 由於最開始的訓練集中存在血糖值異常大的記錄,刪除訓練集中血糖為38的那一行。由於與乙肝的缺失值太多,且相關性不高,因此刪除了乙肝等5個特征屬性,以及刪除了‘id’、‘性別’、‘體檢日期’特征屬性。
(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")
順便把大佬們的思路粘貼一下: