泰坦尼克号幸存者数据集是kaggle竞赛中入门级的数据集,今天我们就来用决策树来预测下哪些人会成为幸存者。
数据集下载地址: https://download.csdn.net/download/ting4937/87630361
数据集中包含两个csv文件,data为训练用数据,test为测试集。
探索数据
首先我们通过pandas来读取并查看数据
import pandas as pd
data = pd.read_csv(r"data.csv") #读取数据data.head() #显示头5条数据
数据如下:里面包含了特征和标签
特征 | 描述 |
survival | 该乘客是否获救,1是获救 |
pclass | 乘客船票等级,1/2/3等舱位,一等票/二等票/三等票 |
sex | 乘客性别 |
Age | 乘客年龄,以年为单位 |
sibsp | 乘客,在泰坦尼克号上的堂兄妹/配偶的个数 |
parch | 乘客,在泰坦尼克号上的父母/孩子个数 |
ticket | 乘客船票信息 |
fare | 乘客船票价格 |
cabin | 乘客船舱信息 |
embarked | 乘客登船港口 C = Cherbourg, |
再通过info方法来查看数据有多少条,空值情况
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):# Column Non-Null Count Dtype
--- ------ -------------- ----- 0 PassengerId 891 non-null int64 1 Survived 891 non-null int64 2 Pclass 891 non-null int64 3 Name 891 non-null object 4 Sex 891 non-null object 5 Age 714 non-null float646 SibSp 891 non-null int64 7 Parch 891 non-null int64 8 Ticket 891 non-null object 9 Fare 891 non-null float6410 Cabin 204 non-null object 11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
处理数据
通过分析数据可以看出name和ticket与是否存活没多少关系,而cabin缺失值太多,这三列需要删掉
#删除指定列, inplace=True表示覆盖原数据,axis=0表示删除行,1表示删除列
data.drop(["Cabin","Name","Ticket", "PassengerId"],inplace=True,axis=1)
age有一百多条数据是空的,需要填上缺失值,我们使用均值来填充,Embarked缺失值不多,直接删掉缺失值
#处理缺失值,填上均值
data["Age"] = data["Age"].fillna(data["Age"].mean())
#删除缺失值
data = data.dropna()
由于决策树只能处理数值型数据,所以需要把性别转成0和1
#将二分类变量转换为数值型变量
data["Sex"] = (data["Sex"]== "male").astype("int")
embarked是三分类的,需要先拿到所有分类,再通过分类的index方法获取索引转成数字
#将三分类变量转换为数值型变量
labels = data["Embarked"].unique().tolist()
data["Embarked"] = data["Embarked"].apply(lambda x: labels.index(x))
数据处理完毕,我们要提取特征和标签,pandas的iloc可以通过索引来分割行列,比如data.iloc[0:5,0:2]表示取5行数据,包含前两列,要取出所有特征可以这么写data.iloc[:,data.columns != "Survived"],data.columns != "Survived"返回一个list当列不等于Survived返回True,这样iloc就会返回True的列,这样就能取出特征了
#取出所有不是Survived的列,即特征
X = data.iloc[:,data.columns != "Survived"]
#取出是Survived的列
y = data.iloc[:,data.columns == "Survived"]
我们来看下数据处理的最终结果,最终留下7个特征,889条数据,全是数值型的
0 Pclass 889 non-null int64 1 Sex 889 non-null int32 2 Age 889 non-null float643 SibSp 889 non-null int64 4 Parch 889 non-null int64 5 Fare 889 non-null float646 Embarked 889 non-null int64
训练模型
接下去分隔测试集和训练集来进行模型的训练,由于分隔方法是随机挑选,会把DataFrame的索引打乱,所以需要修正下索引
#分隔测试集,训练集
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3)
#修正测试集和训练集的索引
for i in [Xtrain, Xtest, Ytrain, Ytest]:i.index = range(i.shape[0])
训练模型,测试模型
clf = DecisionTreeClassifier(random_state=25)
clf = clf.fit(Xtrain, Ytrain)
score_ = clf.score(Xtest, Ytest)
得分
0.7378277153558053
网格搜索调参
import numpy as npparameters = {'splitter':('best','random'),'criterion':("gini","entropy"),"max_depth":[*range(1,10)],'min_samples_leaf':[*range(1,50,5)],'min_impurity_decrease':[*np.linspace(0,0.5,20)]}clf = DecisionTreeClassifier(random_state=25)
GS = GridSearchCV(clf, parameters, cv=10)
GS.fit(X,y)
查看网格搜索推荐参数
GS.best_params_
{'criterion': 'gini','max_depth': 6,'min_impurity_decrease': 0.0,'min_samples_leaf': 6,'splitter': 'best'}
根据推荐参数来训练模型
clf = DecisionTreeClassifier(random_state=25,criterion = "gini",max_depth = 9,min_impurity_decrease = 0,min_samples_leaf = 6,splitter = "best")
clf = clf.fit(Xtrain, Ytrain)
score_ = clf.score(Xtest, Ytest)
score_
0.7640449438202247