天天看点

一次失败的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,实际上关心的是样本间的排名,而不是具体数值的大小,所以结果没必要做归一化处理;关于这个结论,自行搜索资料理解

持续更新后续经验,欢迎关注^_^

继续阅读