赞
踩
谨以此篇文章记录小菜鸡作者向数据分析大佬的仰望。如有冒犯,纯属无意
这篇文章承接之前那篇文章,主要分析如何选择和训练模型,以及对模型的参数的处理。主要借鉴的是这一篇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中的这几个分类算法进行模型的构建。
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
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
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常用核函数
核函数 | 使用特征 |
---|---|
linear | 如果Feature的数量很大,跟样本数量差不多。用于线性可分 |
poly(多项式核) | 是多项分类 |
rbf(高斯核) | 最常用的核函数。如果Feature的数量比较小,样本数量一般。 |
sigmoid | 对于某些参数,sigmoid和rbf有相似的功能 |
在这里,主要用的是rbf和linear,这两种核函数。
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。
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
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。
当然,由于训练集是固定不变的,所以这个准确率有点不可靠。因为并不会晓得当训练集和验证集不断变化时,模型是否还会有这样子的准确率。因此,为了克服这个问题,使模型具有通用性,用到了交叉验证。
很多时候,数据是不平衡的。因此需要在所有的数据上测试算法,调整模型。就需要用到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可以更好的看出来各个模型发的分析结果。
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代表真正死亡却被误判为存活的人数。由此,可以得出两点结论。
模型融合是简单的模型的组合,以创建一个更强大的模型。主要有如下三种方式:
这是模型融合中最常见的一种方式。
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是模型融合的另一个更常用的方法。通过在小数据集上应用相同的子模型,这也是和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是一种集成技术。首先在完整的数据集上训练模型。该模型将获得一些正确的实例,和一些错误的实例。在下一次迭代中,模型将更多地关注错误预测的实例。因此,它将尝试正确预测之前预测错误的实例。并且此迭代过程将继续进行。
在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。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。