天天看點

一次失敗的kaggle比賽Santander Customer Satisfaction:賽題簡介與初次嘗試

題目描述:https://www.kaggle.com/c/santander-customer-satisfaction

簡單總結:一堆匿名屬性;label是0/1;目标是最大化AUC(ROC曲線下的面積)。

第一次嘗試:

特征:

由于比賽已經關閉,隻能作為測試,我就直接用了暴力搜尋提取較好的特征:

[python]  view plain  copy  

一次失敗的kaggle比賽Santander Customer Satisfaction:賽題簡介與初次嘗試
一次失敗的kaggle比賽Santander Customer Satisfaction:賽題簡介與初次嘗試
  1. #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! better use a RFC or GBC as the clf  
  2. #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! because the final predict model are those two  
  3. #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! we should select better feature for RFC or GBC, not for LR  
  4. clf = LogisticRegression(class_weight='balanced', penalty='l2', n_jobs=-1)  
  5. selectedFeaInds=GreedyFeatureAdd(clf, trainX, trainY, scoreType="auc", goodFeatures=[], maxFeaNum=150)  
  6. joblib.dump(selectedFeaInds, 'modelPersistence/selectedFeaInds.pkl')  
  7. #selectedFeaInds=joblib.load('modelPersistence/selectedFeaInds.pkl')   
  8. trainX=trainX[:,selectedFeaInds]  
  9. testX=testX[:,selectedFeaInds]  
  10. print trainX.shape  

模型:

直接使用sklearn中最常用的三個模型:

[python]  view plain  copy  

一次失敗的kaggle比賽Santander Customer Satisfaction:賽題簡介與初次嘗試
一次失敗的kaggle比賽Santander Customer Satisfaction:賽題簡介與初次嘗試
  1. trainN=len(trainY)  
  2. print "Creating train and test sets for blending..."  
  3. #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! always use a seed for randomized procedures  
  4. models=[  
  5.     RandomForestClassifier(n_estimators=1999, criterion='gini', n_jobs=-1, random_state=SEED),  
  6.     RandomForestClassifier(n_estimators=1999, criterion='entropy', n_jobs=-1, random_state=SEED),  
  7.     ExtraTreesClassifier(n_estimators=1999, criterion='gini', n_jobs=-1, random_state=SEED),  
  8.     ExtraTreesClassifier(n_estimators=1999, criterion='entropy', n_jobs=-1, random_state=SEED),  
  9.     GradientBoostingClassifier(learning_rate=0.1, n_estimators=101, subsample=0.6, max_depth=8, random_state=SEED)  
  10. ]  
  11. #StratifiedKFold is a variation of k-fold which returns stratified folds: each set contains approximately the same percentage of samples of each target class as the complete set.  
  12. #kfcv=KFold(n=trainN, n_folds=nFold, shuffle=True, random_state=SEED)  
  13. kfcv=StratifiedKFold(y=trainY, n_folds=nFold, shuffle=True, random_state=SEED)  
  14. dataset_trainBlend=np.zeros( ( trainN, len(models) ) )  
  15. dataset_testBlend=np.zeros( ( len(testX), len(models) ) )  
  16. meanAUC=0.0  
  17. for i, model in enumerate(models):  
  18.     print "model ", i, "=="*20  
  19.     dataset_testBlend_j=np.zeros( ( len(testX), nFold ) )  
  20.     for j, (trainI, testI) in enumerate(kfcv):  
  21.         print "Fold ", j, "^"*20  

最終結果:

通過blending所有模型的結果:

[python]  view plain  copy  

一次失敗的kaggle比賽Santander Customer Satisfaction:賽題簡介與初次嘗試
一次失敗的kaggle比賽Santander Customer Satisfaction:賽題簡介與初次嘗試
  1. print "Blending models..."  
  2. #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if we want to predict some real values, use RidgeCV  
  3. model=LogisticRegression(n_jobs=-1)  
  4. C=np.linspace(0.001,1.0,1000)  
  5. trainAucList=[]  
  6. for c in C:  
  7.     model.C=c  
  8.     model.fit(dataset_trainBlend,trainY)  
  9.     trainProba=model.predict_proba(dataset_trainBlend)[:,1]  
  10.     trainAuc=metrics.roc_auc_score(trainY, trainProba)  
  11.     trainAucList.append((trainAuc, c))  
  12. sortedtrainAucList=sorted(trainAucList)  
  13. for trainAuc, c in sortedtrainAucList:  
  14.     print "c=%f => trainAuc=%f" % (c, trainAuc)  

[python]  view plain  copy  

一次失敗的kaggle比賽Santander Customer Satisfaction:賽題簡介與初次嘗試
一次失敗的kaggle比賽Santander Customer Satisfaction:賽題簡介與初次嘗試
  1. model.C=sortedtrainAucList[-1][1] #0.05  
  2. model.fit(dataset_trainBlend,trainY)  
  3. trainProba=model.predict_proba(dataset_trainBlend)[:,1]  
  4. print "train auc: %f" % metrics.roc_auc_score(trainY, trainProba)  #0.821439  
  5. print "model.coef_: ", model.coef_  
  6. print "Predict and saving results..."  
  7. submitProba=model.predict_proba(dataset_testBlend)[:,1]  
  8. df=pd.DataFrame(submitProba)  
  9. print df.describe()  
  10. SaveFile(submitID, submitProba, fileName="1submit.csv")  

歸一化:

[python]  view plain  copy  

一次失敗的kaggle比賽Santander Customer Satisfaction:賽題簡介與初次嘗試
一次失敗的kaggle比賽Santander Customer Satisfaction:賽題簡介與初次嘗試
  1. print "MinMaxScaler predictions to [0,1]..."  
  2. mms=preprocessing.MinMaxScaler(feature_range=(0, 1))  
  3. submitProba=mms.fit_transform(submitProba)  
  4. df=pd.DataFrame(submitProba)  
  5. print df.describe()  
  6. SaveFile(submitID, submitProba, fileName="1submitScale.csv")  

從測試結果中總結經驗:

第一:暴力搜尋特征的方式在特征數較多的情況下不可取;較少的情況下可以考慮(<200)

第二:sklearn中的這幾個模型,ExtraTreesClassifier效果最差,RandomForestClassifier效果較好且速度比較快,GradientBoostingClassifier結果最好但速度非常慢(因為不能并行)

第三:當某一個模型(GradientBoostingClassifier)比其他模型效果好很多時,不要使用blending的方法(尤其是特征空間一樣,分類器類似的情況,比如這裡的五個分類器都在同一組特征上模組化,而且都是基于樹的分類器),因為blending往往會使整體效果低于單獨使用最好的一個模型

第四:對于AUC,實際上關心的是樣本間的排名,而不是具體數值的大小,是以結果沒必要做歸一化處理;關于這個結論,自行搜尋資料了解

持續更新後續經驗,歡迎關注^_^

繼續閱讀