Kaggle入门Titanic——模型建立

0,介绍

通过前面的特征分析,我们已经得到的想要的训练集和测试集,这样我们就可以利用这些训练集训练模型,并通过模型对测试集进行预测。我们得到的训练集和测试集结构如下所示。

print(train.head(5))
print(test.head(5))

   Survived  Pclass  Sex  Age  Fare  Embarked  FamilySize  IsAlone  Title
0         0       3    1    1     0         0           2        0      1
1         1       1    0    2     3         1           2        0      3
2         1       3    0    1     1         0           1        1      2
3         1       1    0    2     3         0           2        0      3
4         0       3    1    2     1         0           1        1      1
   Pclass  Sex  Age  Fare  Embarked  FamilySize  IsAlone  Title
0       3    1    2     0         2           1        1      1
1       3    0    2     0         0           2        0      3
2       2    1    3     1         2           1        1      1
3       3    1    1     1         0           1        1      1
4       3    0    1     1         0           3        0      3

1,几种基本模型

这里用的是sklearn库和xgboost,结果如下所示,需要注意的是为了防止过拟合,在这里我们对训练集进行划分,每次选择训练集的90%对模型进行训练,然后对测试集进行预测,计算预测的准确率,如此重复十次,将得到的结果进行平均作为我们最后得到的准确率。

mport matplotlib.pyplot as plt
import xgboost as xgb

from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier, GradientBoostingClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis, QuadraticDiscriminantAnalysis
from sklearn.linear_model import LogisticRegression

##所有的分类器模型,采用默认参数
classifiers = [
    KNeighborsClassifier(3),
    DecisionTreeClassifier(),
    RandomForestClassifier(),
    SVC(probability=True),
    AdaBoostClassifier(),
    GradientBoostingClassifier(),
    GaussianNB(),
    LinearDiscriminantAnalysis(),
    QuadraticDiscriminantAnalysis(),
    LogisticRegression(),
    xgb.XGBClassifier()
    ]

sss = StratifiedShuffleSplit(n_splits=10, test_size=0.1, random_state=0)#生成十组训练集和测试集,每组测试集为1/10
x = train[:, 1:]
y = train[:, 0]
accuracy = np.zeros(len(classifiers))#每个模型的准确率
for train_index, test_index in sss.split(x, y):
    x_train, x_test = x[train_index], x[test_index]
    y_train, y_test = y[train_index], y[test_index]
    clf_num = 0
    for clf in classifiers:
        clf_name = clf.__class__.__name__
        clf.fit(x_train, y_train)
        accuracy[clf_num] += (y_test == clf.predict(x_test)).mean()#该模型的准确率,十次平均
        clf_num += 1

accuracy = accuracy / 10
plt.bar(np.arange(len(classifiers)), accuracy, width=0.5, color='b')
plt.xlabel('Alog')  
plt.ylabel('Accuracy')  
plt.xticks(np.arange(len(classifiers)) + 0.25, 
           ('KNN', 'DT', 'RF', 'SVC', 'AdaB', 'GBC', 'GNB',
            'LDA', 'QDA', 'LR', 'xgb'))

结果如下所示,各种模型的准确率都在0.8左右,其中GradientBoostingClassifier,SVC和xgBoost的效果比较好。

array([ 0.79444444,  0.82666667,  0.82555556,  0.82888889,  0.82222222,
        0.83444444,  0.79222222,  0.79666667,  0.81222222,  0.80777778,
        0.82888889])

采用GradientBoostingClassifier模型对测试数据进行预测,并提交结果,得分为0.77033。

gbc = GradientBoostingClassifier().fit(x, y)
test_predictions = gbc.predict(test)
StackingSubmission = pd.DataFrame({ 'PassengerId': PassengerId,
                            'Survived': test_predictions.astype(int) })
StackingSubmission.to_csv("gbc.csv", index=False)

2,模型融合

除了基本的模型以外,如果我们对基本模型的基础上对几个模型进行融合能够得到更佳的效果。

(1)我们通过几个基本模型得到了结果之后,可以对这几个模型进行简单的加权投票来得到最终的结果,我们这里采用的是最简单的平均加权。

(2)我们可以在基本模型之上采用第二层模型来进行非线性拟合得到最终结果,我们这里采用xgboos作为第二层模型来进行模型融合。

(3)我们可以对训练集进行处理,每次采用训练集不同部分对同个模型进行训练,也可以得到不同的模型,最后再进行加权投票。前面一步的时候也用到了这个方法。

平均加权。将上述训练得到的模型对测试集进行测试,得到对应结果,可以得到这些模型之间的相关系数图,如图所示。对于模型融合而言,一般要选择相关性小的模型进行融合,这样可以提高模型多样化,使总的模型可以学到更多的信息,提高模型的准确率。

import matplotlib.pylab as pyl
sss = StratifiedShuffleSplit(n_splits=10, test_size=0.1, random_state=0)#生成十组训练集和测试集,每组测试集为1/10
x = train[:, 1:]
y = train[:, 0]
x1_test = np.zeros((test.shape[0], len(classifiers)))#存储第一层测试集的输出结果
accuracy = np.zeros(len(classifiers))#每个模型的准确率
for train_index, test_index in sss.split(x, y):
    x_train, x_test = x[train_index], x[test_index]
    y_train, y_test = y[train_index], y[test_index]
    clf_num = 0
    for clf in classifiers:
        clf_name = clf.__class__.__name__
        clf.fit(x_train, y_train)
        x1_test[:, clf_num] += clf.predict(test)#直接对测试集进行预测,总共有十次,进行平均
        accuracy[clf_num] += (y_test == clf.predict(x_test)).mean()#该模型的准确率,十次平均
        clf_num += 1
        
x1_test = x1_test / 10
accuracy = accuracy / 10
plt.bar(np.arange(len(classifiers)), accuracy, width=0.5, color='b')
plt.xlabel('Alog')  
plt.ylabel('Accuracy')  
plt.xticks(np.arange(len(classifiers)) + 0.25, 
           ['KNN', 'DT', 'RF', 'SVC', 'AdaB', 'GBC', 'GNB',
            'LDA', 'QDA', 'LR', 'xgb'])

pyl.pcolor(np.corrcoef(x1_test.T), cmap = 'Blues')
pyl.colorbar() 
pyl.xticks(np.arange(0.5, 11.5),
           ['KNN', 'DT', 'RF', 'SVC', 'AdaB', 'GBC', 'GNB','LDA', 'QDA', 'LR', 'xgb'])
pyl.yticks(np.arange(0.5, 11.5),
           ['KNN', 'DT', 'RF', 'SVC', 'AdaB', 'GBC', 'GNB','LDA', 'QDA', 'LR', 'xgb'])
pyl.show()

根据上面的相关系数图,我们选择了KNN,DT,RF,LR和GBC这五个模型得到的结果进行平均投票,得到的分数为0.78947。

index = [0, 1, 2, 5, 9]
linear_prediction = x1_test[:, index].mean(axis=1)
linear_prediction[linear_prediction >= 0.5] = 1
linear_prediction[linear_prediction < 0.5] = 0
StackingSubmission = pd.DataFrame({ 'PassengerId': PassengerId,
                            'Survived': linear_prediction.astype(int) })
StackingSubmission.to_csv("linear_prediction.csv", index=False)

非线性融合。在第二层模型中应用xgboost对第一层模型输出的结果进行拟合,提交结果得到的分数是0.76555。在第一层的时候,为了使第一层的输出能够作为第二层的训练集,需要对训练集进行分块,大小为0.1,然后用训练集的0.9对模型进行训练,得到的模型对训练集剩下的0.1进行预测,这样就能将第一层的输出用于第二层的训练集。但是结果并不是很理想,原因可能是第二层输入特征太少,用模型进行拟合效果不佳。

import xgboost as xgb
from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.cross_validation import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier,GradientBoostingClassifier
from sklearn.linear_model import LogisticRegression

##所有的分类器模型,采用默认参数
classifiers = [
    KNeighborsClassifier(3),
    DecisionTreeClassifier(),
    RandomForestClassifier(),
    GradientBoostingClassifier(),
    LogisticRegression()
    ]

sss = StratifiedShuffleSplit(n_splits=10, test_size=0.1, random_state=0)#生成十组训练集和测试集,每组测试集为1/10
x = train[:, 1:]#原始数据,在下面会进行划分,方便线下求准确率,并且是重复十次防止过拟合
y = train[:, 0]
x1_train = np.zeros((x.shape[0], len(classifiers)))#存储第一层训练集的输出结果
x1_test = np.zeros((test.shape[0], len(classifiers)))#存储第一层测试集的输出结果
accuracy = np.zeros(len(classifiers))#每个模型的准确率
#在这里进行模型融合的时候,采用的是在训练集中每次选取一定数目的训练集进行训练,然后对其余的训练集和测试
#集进行预测,输出作为第二层的输入,这样就可以再次进行训练
for train_index, test_index in sss.split(x, y):
    x_train, x_test = x[train_index], x[test_index]
    y_train, y_test = y[train_index], y[test_index]
    clf_num = 0
    for clf in classifiers:
        clf_name = clf.__class__.__name__
        clf.fit(x_train, y_train)
        x1_train[test_index, clf_num] = clf.predict(x_test)#下层模型的训练集输入是上层模型对于对应测试集的预测输出
        x1_test[:, clf_num] += clf.predict(test)#直接对测试集进行预测,总共有十次,进行平均
        accuracy[clf_num] += (y_test == x1_train[test_index, clf_num]).mean()#该模型的准确率,十次平均
        clf_num += 1

x2_train, x2_test, y2_train, y2_test = train_test_split(x1_train, y, test_size=0.1, random_state=0)

gbm = xgb.XGBClassifier().fit(x2_train, y2_train)
predictions = gbm.predict(x2_test)
print((y2_test == predictions).mean())

test_predictions = gbm.predict(x1_test)
StackingSubmission = pd.DataFrame({ 'PassengerId': PassengerId,
                            'Survived': test_predictions.astype(int) })
StackingSubmission.to_csv("xgboost_Stacking.csv", index=False)

3,总结

上面只是初步的理解,后续还需要对特征,模型参数,模型融合等方式进行进一步的研究提高得分。

 

posted @ 2017-03-10 20:12  linhao_0204  阅读(637)  评论(0编辑  收藏  举报