sklearn机器学习:泰坦尼克号幸存者的预测

这是Kaggle的一道题,这里使用决策树完成预测,方便起见就直接在jupyter lab上来做这题了。

1、首先导入需要的包

#1、导包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import cross_val_score #交叉验证
from sklearn.model_selection import train_test_split #训练集测试集的划分
from sklearn.model_selection import GridSearchCV  #网格搜索
from sklearn import tree

2、读取数据
电脑上已经下了相关数据。有data.csv文件和test.csv文件,我们只需要使用data.csv,关于test.csv是系统用来给我们的模型打分用的,由于我们是自己来测所以就不需要了。data.csv的前面一部分内容如下
sklearn机器学习:泰坦尼克号幸存者的预测_第1张图片

#2、获取数据,探索数据
data = pd.read_csv("D:/MLCSV/Taitanic/data.csv")
#看看数据的样子,这两个方法一般就够了data.head(),data.info()

sklearn机器学习:泰坦尼克号幸存者的预测_第2张图片
注意一下,Survived为类别,即存活或死亡,其他为特征。
sklearn机器学习:泰坦尼克号幸存者的预测_第3张图片
3、数据预处理
从data.info()的信息看到,一共有891条数据,其中Cabin这个特征缺失值极多,删除掉;另外name和Ticket这两个特征与我们的预测无关,删除掉;再看Age这个特征,缺失了200多个数据,缺失部分我们填上Age的均值;Embarked这个特征有两个缺失,很少,那么对应的行删掉即可;最后来看Sex和Embarked特征是object类型,而决策树只能处理数值型数据,所以进行类型转换。

#3、数据预处理
#3.1删除掉缺失值太多的列,与预测结果无关的列
data = data.drop(["Cabin","Name","Ticket"],axis=1)
#data.info()
#3.2缺失值较多的列Age进行填充,极少缺失值的列Embarked删除有缺失值的行
#方括号写数字,表示取行,对行进行操作;写字符串,表示取列索引,对列进行操作
data["Age"]=data["Age"].fillna(data["Age"].mean())#该列的平均值  默认就是axis=0
data=data.dropna()#删除有na的行,默认就是axis=0,how="any"
#data.info(50)
#3.3 决策树不能处理文字类型,将Sex和Embarked转为数字  data["Sex"]=='male'得到的是Series类型,均为false和true
data["Sex"]=(data["Sex"]=='male').astype(int)
ls=data["Embarked"].unique().tolist()
data["Embarked"]=data["Embarked"].apply(lambda x:ls.index(x))
#data.head(10)

4、测试集和训练集划分

现在特征X和类别y是放在同一个表中的,需要单独抽出来,然后使用train_test_split进行测试集和训练集划分(3:7的比例),由于划分是随机的 所以序号会乱,最好进行排序

#4、划分训练集和测试集  ,前表示取所有行,后面表示取列     loc里面使用的是字符串,iloc使用的是索引
X=data.loc[:,data.columns!='Survived']
y=data.loc[:,data.columns=='Survived']
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])

看一下训练集的样子
sklearn机器学习:泰坦尼克号幸存者的预测_第4张图片
5、建模
使用分类树建模,对训练集拟合,对测试集进行预测评分

#5、建模  粗略看一下效果 都只有0.7xx
clf=tree.DecisionTreeClassifier()
clf.fit(Xtrain,Ytrain)
score_1 = clf.score(Xtest,Ytest) 

输出是0.7265917602996255

6、调参:学习曲线与网格搜索

#6、调参  最大深度的学习曲线
tr=[]
te=[]
for i in range(10):
    clf=tree.DecisionTreeClassifier(max_depth=i+1)
    clf.fit(Xtrain,Ytrain)
    te_score=clf.score(Xtest,Ytest)
    tr_score=clf.score(Xtrain,Ytrain)
    tr.append(tr_score)
    te.append(te_score)
print(max(te))
plt.plot(range(1,11),tr,color="r",label="训练集")
plt.plot(range(1,11),te,color="b",label="测试集")
plt.legend()
plt.show()

sklearn机器学习:泰坦尼克号幸存者的预测_第5张图片
在max_depth=3的时候算是最好的,3之前欠拟合之后过拟合严重,3这个位置的评分仍然没到0.8,可以试着调节其他参数,但是总不能一个个去试探,所以使用网格搜索

params={
        "splitter":("best","random")
         ,"criterion":("gini","entropy")
         ,"max_depth":[*range(1,8)]
         ,"min_samples_leaf":[*range(5,21,5)]
        }
clf=tree.DecisionTreeClassifier()
GS=GridSearchCV(clf,params,cv=5)
GS.fit(Xtrain,Ytrain)
print(GS.best_params_)  #最佳参数
print(GS.best_score_)  #最优评分(对应最佳参数)

最终结果如下
sklearn机器学习:泰坦尼克号幸存者的预测_第6张图片

完整代码

#1、导包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn import tree

#2、获取数据,探索数据
data = pd.read_csv("D:/MLCSV/Taitanic/data.csv")
#3、数据预处理
#3.1删除掉缺失值太多的列,与预测结果无关的列
data = data.drop(["Cabin","Name","Ticket"],axis=1)
#data.info()
#3.2缺失值较多的列Age进行填充,极少缺失值的列Embarked删除有缺失值的行
#方括号写数字,表示取行,对行进行操作;写字符串,表示取列索引,对列进行操作
data["Age"]=data["Age"].fillna(data["Age"].mean())#该列的平均值  默认就是axis=0
data=data.dropna()#删除有na的行,默认就是axis=0,how="any"
#data.info(50)
#3.3 决策树不能处理文字类型,将Sex和Embarked转为数字  data["Sex"]=='male'得到的是Series类型,均为false和true
data["Sex"]=(data["Sex"]=='male').astype(int)
ls=data["Embarked"].unique().tolist()
data["Embarked"]=data["Embarked"].apply(lambda x:ls.index(x))
#data.head(10)

#4、划分训练集和测试集  ,前表示取所有行,后面表示取列     loc里面使用的是字符串,iloc使用的是索引
X=data.loc[:,data.columns!='Survived']
y=data.loc[:,data.columns=='Survived']
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])
#5、建模  粗略看一下效果 都只有0.7xx
clf=tree.DecisionTreeClassifier()
clf.fit(Xtrain,Ytrain)
score_1 = clf.score(Xtest,Ytest) 
#6、调参
tr=[]
te=[]
for i in range(10):
    clf=tree.DecisionTreeClassifier(max_depth=i+1)
    clf.fit(Xtrain,Ytrain)
    te_score=clf.score(Xtest,Ytest)
    tr_score=clf.score(Xtrain,Ytrain)
    tr.append(tr_score)
    te.append(te_score)
print(max(te))
plt.plot(range(1,11),tr,color="r",label="训练集")
plt.plot(range(1,11),te,color="b",label="测试集")
plt.legend()
plt.show()

gini_thresholds=[*np.linspace(0,0.5,20)]#linspace返回均匀间隔的数字
params={
        "splitter":("best","random")
         ,"criterion":("gini","entropy")
         ,"max_depth":[*range(1,8)]
         ,"min_samples_leaf":[*range(5,21,5)]
        }
clf=tree.DecisionTreeClassifier()
GS=GridSearchCV(clf,params,cv=5)
GS.fit(Xtrain,Ytrain)
print(GS.best_params_)
print(GS.best_score_)

你可能感兴趣的