Titanic数据集包含11个特征,分别是:
Survived:0代表死亡,1代表存活
Pclass:船舱类别,3类别最高
Name、Sex、Age分别为姓名、性别、年龄,其中年龄有缺失
SibSp:乘客的兄弟姐妹/配偶的个数(整数值)
Parch:乘客的父母/孩子的个数(整数值)
Ticket:船票号码
Fare:船票价格
Cabin:乘客所在船舱(数据大量缺失)
Embark:乘客登船港口:S、C、Q(有缺失)
代码如下:
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
titanic_=pd.read_csv('C:\\Users\\HP\\Titanic\\train.csv')
#舍去无关变量
titanic=titanic_.drop(['PassengerId','Cabin','Name','Ticket','SibSp','Parch','Fare'],axis=1)
titanic.head()
titanic["Age"]=titanic["Age"].fillna(titanic["Age"].mean())
titanic["Embarked"]=titanic["Embarked"].fillna("S")
将数据进行清洗,舍去无关或相关性较低的变量,对有缺失的数据进行填补。前五行如下:
#Pclass,Sex为数值型变量,将其转化为类别型,进行哑变量处理
titanic.Pclass=titanic.Pclass.astype('category')
#哑变量处理
dummy=pd.get_dummies(titanic[['Sex','Pclass','Embarked']])
#水平合并原数据集和哑变量
titanic=pd.concat([titanic,dummy],axis=1)
#删除为处理时时变量,保留哑变量
titanic.drop(['Sex','Pclass','Embarked'],inplace=True,axis=1)
print(titanic.head())
Pclass是数值型变量,我们将其转化为类别型,然后进行哑变量的处理。比如说Pclass的是三个等级可以表示为001、010、100,这样在决策树上只要判断是否大于或小于0.5就可以区分了。Embarked和Sex也是同理。
#数据分割
predictors=titanic.columns[1:]
from sklearn.cross_validation import train_test_split
X_train,X_test,y_train,y_test=train_test_split(titanic[predictors],titanic['Survived'],test_size=0.2)
print(predictors)
分割数据,同时将特征值打包
#预剪枝,采用网格搜索法调参
from sklearn.model_selection import GridSearchCV
from sklearn.tree import DecisionTreeClassifier
max_depth=[4,5,6,7,8]
min_samples_split=[2,4,6,8,10]
min_samples_leaf=[2,4,6,8,10]
parameters={'max_depth':max_depth,'min_samples_split':min_samples_split,'min_samples_leaf':min_samples_leaf}
grid_search=GridSearchCV(estimator=DecisionTreeClassifier(),param_grid=parameters,cv=10,n_jobs=-1)
grid_search.fit(X_train,y_train)
grid_search.best_params_
为了防止过拟合,这里采用预剪枝的方法,限制决策树的最大深度、最小的非叶子结点的变量值与最小叶子结点变量值。采用网格搜索法,来对参数进行调优。
GridSearchCV方法,只要把参数输进去,就能给出最优化的结果和参数。比如SVM的惩罚因子C,核函数kernel,gamma参数等
class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, fit_params=None, n_jobs=1, iid=True, refit=True, cv=None, verbose=0, pre_dispatch=‘2*n_jobs’, error_score=’raise’, return_train_score=’warn’)
其中:
estimator:选择使用的分类器
param_grid:需要最优化的参数的取值,值为字典或者列表
CV:为交叉验证次数
{'max_depth': 6, 'min_samples_leaf': 10, 'min_samples_split': 2}
经过网格搜索法得到最大深度为6,最小的非叶子结点的变量值为2,最小叶子结点变量值为10。
接下来根据这个参数构建决策树
#根据调参结果构建决策树
from sklearn import metrics
dtc=DecisionTreeClassifier(max_depth=6,min_samples_split=2,min_samples_leaf=10)
dtc.fit(X_train,y_train)
y_predict=dtc.predict(X_test)
print("决策树模型在测试集上的准确率为:",metrics.accuracy_score(y_test,y_predict))
输出:决策树模型在测试集上的准确率为: 0.8379888268156425
单棵决策树进行剪枝以后不仅避免了过拟合,准确率还算挺高的。
import pydotplus
from sklearn.tree import export_graphviz
dot_data = export_graphviz(dtc,out_file=None,feature_names=predictors,class_names="Survived",filled=True, rounded=True,special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data)
###保存图像到pdf文件
graph.write_pdf("titanic_tree5.pdf")
导出决策树可视化的图像
#构建随机森林模型
from sklearn.ensemble import RandomForestClassifier
RF=RandomForestClassifier(n_estimators=233,random_state=1234)
RF.fit(X_train,y_train)
RF_predict=RF.predict(X_test)
print("随机森林模型在测试集上的准确率为:",metrics.accuracy_score(y_test,RF_predict))
print("随机森林模型在训练集上的准确率为:",metrics.accuracy_score(y_train,RF.predict(X_train)))
随机森林模型在测试集上的准确率为: 0.7932960893854749
随机森林模型在训练集上的准确率为: 0.9143258426966292
随机森林在训练集上的准确率很高,但是到了测试集反而没有决策树来的高了,也试着换了不同的参数,也没有实质性的高许多这样子,还没搞清楚问题所在。
#影响乘客是否幸存的重要因素
importance=RF.feature_importances_
series=pd.Series(importance,index=X_train.columns)
series.sort_values(ascending=True).plot('barh')
plt.show()
画图看一下影响船员幸存的因素
可以看出,年龄和性别确实影响着幸存与否,同时3等舱的乘客幸存的几率也比较大。