对KAGGLE经典泰坦尼克号问题的解析(二)

深入解析那些高赞回答(二)

谨以此篇文章记录小菜鸡作者向数据分析大佬的仰望。如有冒犯,纯属无意
这篇文章承接之前那篇文章,主要分析如何选择和训练模型,以及对模型的参数的处理。主要借鉴的是这一篇notebook:EDA To Prediction(DieTanic)
关于sklearn中的一些算法的简介,大家可以去看这一篇 中文文档
为了方便模型之后的调参工作,首先需要将之前的训练集再切分,分成训练集和验证集。而sklearn中自带的train_test_split 库就很好用。

from sklearn.linear_model import LogisticRegression #logistic regression
from sklearn import svm #support vector Machine
from sklearn.ensemble import RandomForestClassifier #Random Forest
from sklearn.neighbors import KNeighborsClassifier #KNN
from sklearn.naive_bayes import GaussianNB #Naive bayes
from sklearn.tree import DecisionTreeClassifier #Decision Tree
from sklearn.model_selection import train_test_split #切分训练集和验证集
from sklearn import metrics #计算准确率
from sklearn.metrics import confusion_matrix #引入混淆矩阵

#训练集切割
train,test=train_test_split(train_df,test_size=0.3,random_state=0,stratify=train_df['Survived'])
train_X = train[train.columns[1:]]
train_Y = train[train.columns[:1]]
test_X = test[test.columns[1:]]
test_Y = test[test.columns[:1]]
X = train_df[train_df.columns[1:]]
Y = train_df['Survived']

train_test_split中的test_size就是字面的意思,代表将原始训练集三七分了。random_state可能有一点难理解,就当做无论在谁的电脑上、无论什么时候,只要数据集相同,random_state的值相同,那么就可以把数据集切分成相同的样子。stratify是切分的标准,这里代表的意思就是将‘Survived’的所有值三七分了,再组合。
很明显知道这是一个分类的问题,下面主要依据sklearn中的这几个分类算法进行模型的构建。

  1. Logistic Regression 逻辑回归(虽然名字是一个回归的算法,但可以当分类算法使用)。
  2. Support Vector Machines(SVM) 支持向量机
  3. Random Forest 随机森林
  4. K-Nearest Neighbours(KNN)
  5. Naive Bayes 朴素贝叶斯
  6. Decision Tree 决策树

直接求解

Logistic Regression

model = LogisticRegression()
model.fit(train_X,train_Y)
prediction1=model.predict(test_X)
print('The accuracy of the Logistic Regression is',metrics.accuracy_score(prediction1,test_Y))

计算后的准确率大概是0.810

Decision Tree

model=DecisionTreeClassifier()
model.fit(train_X,train_Y)
prediction2=model.predict(test_X)
print('The accuracy of the Decision Tree is',metrics.accuracy_score(prediction2,test_Y))

计算后的准确率大概是0.799

KNN

a_index=list(range(1,11))
a=pd.Series()
x=[0,1,2,3,4,5,6,7,8,9,10]
for i in list(range(1,11)):
    model=KNeighborsClassifier(n_neighbors=i) 
    model.fit(train_X,train_Y)
    prediction=model.predict(test_X)
    a=a.append(pd.Series(metrics.accuracy_score(prediction,test_Y)))
plt.plot(a_index, a)
plt.xticks(x)
fig=plt.gcf()
fig.set_size_inches(12,6)
plt.show()
print('Accuracies for different values of n are:',a.values,'with the max value as ',a.values.max()

这段代码的作用是展示了当KNN中的参数n_neighbors取不同的值的时候,训练模型的准确率各为多少,从而找出准确率最高的参数值。fig=plt.gcf()中gcf的意思是get current figure,也就是可以通过改变fig的参数从而改变这个图片的参数。输出的结果入下。
在这里插入图片描述
根据结果显示,n_neighbors的值是9的时候,准确率最高为0.799。

SVM

SVM中的常用核函数有四种。下面用一张表格来介绍他们。这里引用吴恩达老师的简介。也可以参考这篇博客 svm常用核函数

核函数使用特征
linear如果Feature的数量很大,跟样本数量差不多。用于线性可分
poly(多项式核)是多项分类
rbf(高斯核)最常用的核函数。如果Feature的数量比较小,样本数量一般。
sigmoid对于某些参数,sigmoid和rbf有相似的功能

在这里,主要用的是rbflinear,这两种核函数。

model=svm.SVC(kernel='rbf',C=1,gamma=0.1)
model.fit(train_X,train_Y)
prediction1=model.predict(test_X)
print('Accuracy for rbf SVM is ',metrics.accuracy_score(prediction1,test_Y))

将kernel中的rbf改成linear,就可以得到核函数是linear时的结果。结果分别为:0.806和0.791。

Gaussian Naive Bayes

model=GaussianNB()
model.fit(train_X,train_Y)
prediction6=model.predict(test_X)
print('The accuracy of the NaiveBayes is',metrics.accuracy_score(prediction6,test_Y))

结果是0.780

Random Forests

model=RandomForestClassifier(n_estimators=100)
model.fit(train_X,train_Y)
prediction7=model.predict(test_X)
print('The accuracy of the Random Forests is',metrics.accuracy_score(prediction7,test_Y))

计算后的结果是0.802。
当然,由于训练集是固定不变的,所以这个准确率有点不可靠。因为并不会晓得当训练集和验证集不断变化时,模型是否还会有这样子的准确率。因此,为了克服这个问题,使模型具有通用性,用到了交叉验证。

Cross Validation(交叉验证)

很多时候,数据是不平衡的。因此需要在所有的数据上测试算法,调整模型。就需要用到K折交叉验证。

from sklearn.model_selection import KFold #for K-fold cross validation
from sklearn.model_selection import cross_val_score #score evaluation
from sklearn.model_selection import cross_val_predict #prediction
kfold = KFold(n_splits=10, random_state=22) # k=10, split the data into 10 equal parts
xyz=[]
accuracy=[]
std=[]
classifiers=['Linear Svm','Radial Svm','Logistic Regression','KNN','Decision Tree','Naive Bayes','Random Forest']
models=[svm.SVC(kernel='linear'),svm.SVC(kernel='rbf'),LogisticRegression(),KNeighborsClassifier(n_neighbors=9),DecisionTreeClassifier(),GaussianNB(),RandomForestClassifier(n_estimators=100)]
for i in models:
    model = i
    cv_result = cross_val_score(model,X,Y, cv = kfold,scoring = "accuracy")
    cv_result=cv_result
    xyz.append(cv_result.mean())
    std.append(cv_result.std())
    accuracy.append(cv_result)
new_models_dataframe2=pd.DataFrame({'CV Mean':xyz,'Std':std},index=classifiers)       
new_models_dataframe2

上面的代码给的是这几种算法经过交叉验证得到的准确率。用了十折交叉验证的方法。结果如下。
在这里插入图片描述
为了更好地看出来最后各个模型的预测情况,使用Confusion Matrix。

Confusion Matrix

Confusion Matrix可以更好的看出来各个模型发的分析结果。

f,ax=plt.subplots(3,3,figsize=(12,10))
y_pred = cross_val_predict(svm.SVC(kernel='rbf'),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[0,0],annot=True,fmt='2.0f')
ax[0,0].set_title('Matrix for rbf-SVM')
y_pred = cross_val_predict(svm.SVC(kernel='linear'),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[0,1],annot=True,fmt='2.0f')
ax[0,1].set_title('Matrix for Linear-SVM')
y_pred = cross_val_predict(KNeighborsClassifier(n_neighbors=9),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[0,2],annot=True,fmt='2.0f')
ax[0,2].set_title('Matrix for KNN')
y_pred = cross_val_predict(RandomForestClassifier(n_estimators=100),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[1,0],annot=True,fmt='2.0f')
ax[1,0].set_title('Matrix for Random-Forests')
y_pred = cross_val_predict(LogisticRegression(),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[1,1],annot=True,fmt='2.0f')
ax[1,1].set_title('Matrix for Logistic Regression')
y_pred = cross_val_predict(DecisionTreeClassifier(),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[1,2],annot=True,fmt='2.0f')
ax[1,2].set_title('Matrix for Decision Tree')
y_pred = cross_val_predict(GaussianNB(),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[2,0],annot=True,fmt='2.0f')
ax[2,0].set_title('Matrix for Naive Bayes')
plt.subplots_adjust(hspace=0.2,wspace=0.2)
plt.show()

结果如下图所示。
在这里插入图片描述
混淆矩阵(Confusion Matrix),中 横轴是真正的数据纵轴代表预测的数据 。以rbf-SVM为例,(0,1)上的115代表真正死亡却被误判为存活的人数。由此,可以得出两点结论。

  1. rbf-Matrix可以更好地预测死亡的乘客
  2. Naive Bayes能更好地预测存活的人

模型融合(Ensembling)

模型融合是简单的模型的组合,以创建一个更强大的模型。主要有如下三种方式:

  1. Voting Classifier
  2. Bagging
  3. Boosting

Voting Classifier

这是模型融合中最常见的一种方式。

from sklearn.ensemble import VotingClassifier
ensemble_lin_rbf=VotingClassifier(estimators=[('KNN',KNeighborsClassifier(n_neighbors=10)),
                                              ('RBF',svm.SVC(probability=True,kernel='rbf',C=0.5,gamma=0.1)),
                                              ('RFor',RandomForestClassifier(n_estimators=500,random_state=0)),
                                              ('LR',LogisticRegression(C=0.05)),
                                              ('DT',DecisionTreeClassifier(random_state=0)),
                                              ('NB',GaussianNB()),
                                              ('svm',svm.SVC(kernel='linear',probability=True))
                                             ], 
                       voting='soft').fit(train_X,train_Y)
print('The accuracy for ensembled model is:',ensemble_lin_rbf.score(test_X,test_Y))
cross=cross_val_score(ensemble_lin_rbf,X,Y, cv = 10,scoring = "accuracy")
print('The cross validated score is',cross.mean())

是先把之前的基本模型都装到了一个叫 ensemble_lin_rbf 的模型中。之后进行了一次一般的训练和一次交叉验证。得到的结果分别是0.813和0.817。

Bagging

Bagging是模型融合的另一个更常用的方法。通过在小数据集上应用相同的子模型,这也是和Voiting Classifier的最大的不同。并且,Bagging更适合高方差的模型融合,如决策树或随机森林,或者将KNN中 n_neighbors 的参数值调小。

from sklearn.ensemble import BaggingClassifier
model=BaggingClassifier(base_estimator=KNeighborsClassifier(n_neighbors=3),random_state=0,n_estimators=700)
model.fit(train_X,train_Y)
prediction=model.predict(test_X)
print('The accuracy for bagged KNN is:',metrics.accuracy_score(prediction,test_Y))
result=cross_val_score(model,X,Y,cv=10,scoring='accuracy')
print('The cross validated score for bagged KNN is:',result.mean())

model=BaggingClassifier(base_estimator=DecisionTreeClassifier(),random_state=0,n_estimators=100)
model.fit(train_X,train_Y)
prediction=model.predict(test_X)
print('The accuracy for bagged Decision Tree is:',metrics.accuracy_score(prediction,test_Y))
result=cross_val_score(model,X,Y,cv=10,scoring='accuracy')
print('The cross validated score for bagged Decision Tree is:',result.mean())

分别对KNN和决策树模型使用了Bagging的模型混合方法,计算了未使用交叉验证和使用了交叉验证的结果。分别为0.791;0.810;0.810;0.812。

Boosting

Boosting是一种集成技术。首先在完整的数据集上训练模型。该模型将获得一些正确的实例,和一些错误的实例。在下一次迭代中,模型将更多地关注错误预测的实例。因此,它将尝试正确预测之前预测错误的实例。并且此迭代过程将继续进行。

AdaBoost(Adaptive Boosting)

在AdaBoost中,默认的子模型是 决策树 ,之后可以通过更改base_estimator 这个参数来更改子模型。

from sklearn.ensemble import AdaBoostClassifier
ada=AdaBoostClassifier(n_estimators=200,random_state=0,learning_rate=0.1)
result=cross_val_score(ada,X,Y,cv=10,scoring='accuracy')
print('The cross validated score for AdaBoost is:',result.mean())

最后的结果大概是0.790。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值