精华内容
下载资源
问答
  • 泰坦尼克号生存预测数据集 泰坦尼克号生存预测数据集 Taitanic data.zip
  • 随机森林:泰坦尼克号生存预测随机森林:
  • 泰坦尼克号生存预测

    千次阅读 2020-04-01 16:46:07
    kaggle 泰坦尼克号生存预测——六种算法模型实现与比较 Kaggle初体验-机器学习之泰坦尼克号乘客生存预测(上) 猴子数据分析之泰坦尼克号生存率预测 数据集:https://www.kaggle.com/c/titanic 字段 Age:年龄...

    学习

    机器学习之特征工程

    使用sklearn做单机特征工程

    参考

    kaggle 泰坦尼克号生存预测——六种算法模型实现与比较

    Kaggle初体验-机器学习之泰坦尼克号乘客生存预测(上)

    猴子数据分析之泰坦尼克号生存率预测

     

    数据集:https://www.kaggle.com/c/titanic

     

    字段

    Age:年龄

    Cabin:船舱号

    Embarked:登船港口 C为Cherbourg Q为Queenstown S为Southampton

    Fare:船票费用

    Name:姓名

    Parch:在船上的父母/孩子人数

    PassengerId:乘客编号

    Pclass:船票等级 1为一等舱 2为二等舱 3为三等舱

    Sex:性别

    Sibsp:在船上的兄弟姐妹人数

    Ticket:船票编号

    Survived:生存与否 预测值

     

    导入数据

    import warnings
    warnings.filterwarnings('ignore')
    
    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    import seaborn as sns
    sns.set(style='darkgrid',font_scale=1.5)
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    train = pd.read_csv('train.csv')
    test = pd.read_csv('test.csv')
    print ('训练数据集:',train.shape,'测试数据集:',test.shape)
    训练数据集: (891, 12) 测试数据集: (418, 11)
    #合并数据集 方便同时对两个数据集进行清洗
    full = train.append(test,ignore_index=True)

     

    数据清洗

    缺失值统计

    full.isnull().sum()

    年龄 船舱的缺失数据较多

    登船港口 船票价格的缺失数据较少

    Survived的缺失是合并后的测试集

    缺失值处理

    很多机器学习算法为了训练模型,要求传入的特征中不能有空值:

    1、如果是数值类型,用平均值代替

    2、如果是分类数据,用最常见的类别取代

    3、使用KNN等模型预测缺失值

    #年龄缺失值处理
    full['Age'] = full['Age'].fillna(full['Age'].mean())
    #船票缺失值处理
    full['Fare'] = full['Fare'].fillna(full['Fare'].mean())
    #embarked&cabin为字符串列
    #查看最常见的港口类别
    full['Embarked'].value_counts()
    #用最常见的类别填充
    full['Embarked'] = full['Embarked'].fillna('S')
    
    #查看最常见的船舱类别
    full['Cabin'].value_counts()
    #缺失数据过多,且不同船舱号的数量差距不大
    #船舱号(Cabin)缺失值填充为U,表示未知(Uknow) 
    full['Cabin'] = full['Cabin'].fillna( 'U' )

     

    特征分析

    相关系数矩阵

    corr = train.corr()
    #热度图可视化相关系数矩阵 只显示数字之间的
    plt.subplots(figsize=(10,4)) # 可以先试用plt设置画布的大小,然后在作图,修改
    sns.heatmap(corr, annot = True) # 使用热度图可视化这个相关系数矩阵

    绝对值排序为pclass fare parch age sibsp passengerid

    pclass 社会阶层

    sns.countplot(x='Pclass',hue='Survived',data=train)

    船舱等级为一等舱的乘客生存几率较高 pclass与生存率有关

    sex 性别

    sns.countplot(x='Sex',hue='Survived',data=train)

    女性生存几率较高 女士优先原则 性别与生存率有关

    age 年龄

    train_age = sns.FacetGrid(train, col='Survived',height=5)
    train_age.map(plt.hist, 'Age', bins=40)

    fig = plt.figure(figsize=(10, 6))
    sns.violinplot(  x='Survived',y='Age', data=train, 
                   split=True,palette={0: "r", 1: "g"} )
    plt.title('乘客年龄与存活关系')
    plt.ylabel('年龄')

    年龄较小的乘客生存率较高,年龄较大的次之,20-40岁的青壮年明显生存率较低

    符合儿童优先原则 年龄与生存率相关

    sibsp 兄弟姐妹数

    sns.countplot(x='SibSp',hue='Survived',data=train)

    =0生存率低 1-2较高 >3低

    parch 父母子女数

    sns.countplot(x='Parch',hue='Survived',data=train)

    =0生存率低 1-2较高 >3低

    家庭成员数

    sibsp与parch的分布相似 可结合起来看家庭成员数

    家庭人数 = Parch兄弟姐妹数+SibSp父母子女数+自己

    train['members'] = train['Parch'] + train['SibSp']
    sns.countplot(x='members',hue='Survived',data=train)

    =0生存率低 1-3较高 >4低

    fare 船票价格

    train['Fare'].describe()
    train_fare = sns.FacetGrid(train, col='Survived',height=5)
    train_fare.map(plt.hist, 'Fare', bins=5)
    #train_fare.set(xticks=[0,600])

    # 按船舱等级分组
    train.groupby('Pclass').agg('mean')['Fare'].plot(kind='bar', figsize=(10,6))
    plt.title('船舱等级与船票价格关系')
    plt.xlabel('船舱等级')
    plt.ylabel('平均船票价格')

    船票价格高-船舱等级高-与生存率有关

    cabin 船舱编号

    #有编号的的为y,没有的为n
    train['Cabin']=train['Cabin'].map(lambda x:'y' if type(x)==str else 'n')
    sns.countplot(x="Cabin", hue="Survived", data=train)

    有编号的存活率更高【为啥?难道因为船员没编号?但这不是乘客名单吗 船还有无座的?

    embarked 上船港口

    sns.countplot(x="Embarked", hue="Survived", data=train)

    C港口上船的存活率更高【这又是为啥 难道这个港口上船的人比较有钱?

     

    特征提取

    查看数据类型,将其分为三类

    对类别数据进行处理:用数值代替类别,并进行one-hot编码

    full.info()

    1、数值类型:
    乘客编号(PassengerId),年龄(Age),船票价格(Fare),同代直系亲属人数(SibSp),不同代直系亲属人数(Parch)
    2、时间序列:无
    3、分类数据:
    1)有直接类别的
    乘客性别(Sex):男性male,女性female
    登船港口(Embarked):出发地点S=英国南安普顿Southampton,途径地点1:C=法国 瑟堡市Cherbourg,出发地点2:Q=爱尔兰 昆士敦Queenstown
    客舱等级(Pclass):1=1等舱,2=2等舱,3=3等舱
    2)字符串类型:如果可以从这里面提取出特征来,也归到分类数据中
    乘客姓名(Name)
    客舱号(Cabin)
    船票编号(Ticket)

    分类数据-有直接类别的

    sex 性别

    full['Sex'].head()
    #将性别的值映射为数值
    #male对应1 female对应0
    sex_mapDict = {'male':1,'female':0}
    
    full['Sex'] = full['Sex'].map(sex_mapDict)
    full['Sex'].head()

    embarked 登船港口

    full['Embarked'].head()
    
    embarkedDf = pd.DataFrame()#新建
    
    #使用get_dummies进行one-hot编码
    #产生虚拟变量(dummy variables),列名前缀是Embarked
    embarkedDf = pd.get_dummies(full['Embarked'],prefix='Embarked')
    embarkedDf.head()

    #添加one-hot编码产生的虚拟变量(dummy variables)到泰坦尼克号数据集full
    full = pd.concat([full,embarkedDf],axis=1)
    
    #替代原embarked
    full.drop('Embarked',axis=1,inplace=True)
    full.head()

    pclass 客舱等级

    full['Pclass'].head()
    
    pclass_Df = pd.DataFrame()
    
    pclass_Df = pd.get_dummies(full['Pclass'],prefix='Pclass')
    pclass_Df.head()
    
    #添加one-hot编码产生的虚拟变量(dummy variables)到泰坦尼克号数据集full
    full = pd.concat([full,pclass_Df],axis=1)
    
    #替代原pclass
    full.drop('Pclass',axis=1,inplace=True)
    full.head()

    分类数据-字符串类型

    name 姓名

    full['Name'].head()

    乘客头衔每个名字当中都包含了具体的称谓或者说是头衔
    将这部分信息提取出来后可以作为非常有用的一个新变量,可以帮助我们进行预测。
    逗号前面的是“名”,逗号后面是‘头衔. 姓’

    #定义函数 从姓名中获取头衔
    def getTitle(name):
        s1 = name.split(',')[1]
        s2 = s1.split('.')[0]
        s = s2.strip()#移除字符串头尾指定的字符(默认为空格)
        return s
    titleDf = pd.DataFrame()
    
    titleDf['Title'] = full['Name'].map(getTitle)
    titleDf.groupby('Title').size()

    定义以下几种头衔类别:

    Officer政府官员
    Royalty王室(皇室)
    Mr已婚男士
    Mrs已婚妇女
    Miss年轻未婚女子
    Master有技能的人/教师

    #姓名中头衔字符串与定义头衔类别的映射关系
    title_mapDict = {
                        "Capt":       "Officer",
                        "Col":        "Officer",
                        "Major":      "Officer",
                        "Jonkheer":   "Royalty",
                        "Don":        "Royalty",
                        "Sir" :       "Royalty",
                        "Dr":         "Officer",
                        "Rev":        "Officer",
                        "the Countess":"Royalty",
                        "Dona":       "Royalty",
                        "Mme":        "Mrs",
                        "Mlle":       "Miss",
                        "Ms":         "Mrs",
                        "Mr" :        "Mr",
                        "Mrs" :       "Mrs",
                        "Miss" :      "Miss",
                        "Master" :    "Master",
                        "Lady" :      "Royalty"
                        }
    #map函数:对Series每个数据应用自定义的函数计算
    titleDf['Title'] = titleDf['Title'].map(title_mapDict)
    
    #使用get_dummies进行one-hot编码
    titleDf = pd.get_dummies(titleDf['Title'])
    titleDf.head()
    
    #添加one-hot编码产生的虚拟变量(dummy variables)到泰坦尼克号数据集full
    full = pd.concat([full,titleDf],axis=1)
    
    #删掉姓名这一列
    full.drop('Name',axis=1,inplace=True)
    full.head()

    cabin 客舱号

    full['Cabin'].head()

    客舱号的首字母是客舱的类别

    cabinDf = pd.DataFrame()
    cabinDf['Cabin'] = full['Cabin'].map(lambda c : c[0])
    cabinDf = pd.get_dummies(cabinDf['Cabin'],prefix='Cabin')
    cabinDf.head()
    
    
    full = pd.concat([full,cabinDf],axis=1)
    full.drop('Cabin',axis=1,inplace=True)

    家庭人数和家庭类别

    家庭人数=同代直系亲属数(Parch)+不同代直系亲属数(SibSp)+乘客自己

    家庭类别:
    小家庭Family_Single:家庭人数=1
    中等家庭Family_Small: 2<=家庭人数<=4
    大家庭Family_Large: 家庭人数>=5

    familyDf = pd.DataFrame()
    
    #家庭人数=同代直系亲属数(Parch)+不同代直系亲属数(SibSp)+乘客自己
    familyDf['FamilySize'] = full['Parch'] + full['SibSp'] + 1
    
    #家庭类别
    
    #if 条件为真的时候返回if前面内容,否则返回0
    familyDf['Family_Single'] = familyDf['FamilySize'].map(lambda x: 1 if x==1 else 0)
    familyDf['Family_Small'] = familyDf['FamilySize'].map(lambda x: 1 if 2 <= x <= 4 else 0)
    familyDf['Family_Large:'] = familyDf['FamilySize'].map(lambda x: 1 if x >= 5 else 0)
    
    familyDf.head()
    
    full = pd.concat([full,familyDf],axis=1)

    我们获得了33列经过one-hot编码后的数据

    full.columns

     

    特征选择

    相关系数

    corrDf = full.corr()
    
    corrDf['Survived'].sort_values(ascending=False)

    根据相关系数排序与前面对特征的分析 选择以下特征作为模型输入

    full_X = pd.concat([titleDf,#头衔
                       pclass_Df,#船舱等级
                       familyDf,#家庭大小
                       full['Fare'],#船票价格
                       cabinDf,#船舱号
                       embarkedDf,#登船港口
                       full['Sex']#性别
                       ],axis=1)

     

    使用模型

    建立训练数据集与测试数据集

    使用项目给出的train数据集作为原始数据集source

    从source中拆分出训练数据集train用于模型训练 测试数据集test用于模型评估

    #原始数据集有891行
    sourceRow=891
    
    #从特征集合full_X中提取原始数据集提取前891行数据时,我们要减去1,因为行号是从0开始的。
    #原始数据集:特征
    source_X = full_X.loc[0:sourceRow-1,:]
    #原始数据集:生存标签
    source_y = full.loc[0:sourceRow-1,'Survived']  
    
    #预测数据集:特征
    pred_X = full_X.loc[sourceRow:,:]

     确保这里原始数据集取的是前891行的数据 以免模型出错

    #原始数据集有多少行
    print('原始数据集有多少行:',source_X.shape[0])
    #预测数据集大小
    print('原始数据集有多少行:',pred_X.shape[0])

    从原始数据集(source)中拆分出训练数据集(用于模型训练train),测试数据集(用于模型评估test)
    train_test_split是交叉验证中常用的函数,功能是从样本中随机的按比例选取train data和test data
    train_data:所要划分的样本特征集
    train_target:所要划分的样本结果
    test_size:样本占比,如果是整数的话就是样本的数量

    from sklearn.model_selection import train_test_split 
    
    train_X,test_X,train_y,test_y = train_test_split(source_X,source_y,train_size=0.8)
    
    #输出数据集大小
    print ('原始数据集特征:',source_X.shape, 
           '训练数据集特征:',train_X.shape ,
          '测试数据集特征:',test_X.shape)
    
    print ('原始数据集标签:',source_y.shape, 
           '训练数据集标签:',train_y.shape ,
          '测试数据集标签:',test_y.shape)

    训练模型&预测

    例:逻辑回归logistic regression

    #第1步:导入算法
    from sklearn.linear_model import LogisticRegression
    #第2步:创建模型:逻辑回归(logisic regression)
    model = LogisticRegression()
    #第3步:训练模型
    model.fit( train_X , train_y )
    
    #分类问题,score得到的是模型的正确率
    model.score(test_X , test_y )
    #使用机器学习模型,对预测数据集中的生存情况进行预测
    pred_Y = model.predict(pred_X)
    
    '''
    生成的预测值是浮点数(0.0,1,0)
    但是Kaggle要求提交的结果是整型(0,1)
    所以要对数据类型进行转换
    '''
    
    pred_Y=pred_Y.astype(int)
    #乘客id
    passenger_id = full.loc[sourceRow:,'PassengerId']
    #数据框:乘客id,预测生存情况的值
    predDf = pd.DataFrame( 
        { 'PassengerId': passenger_id , 
         'Survived': pred_Y } )
    predDf.shape
    predDf.head()
    #保存结果
    predDf.to_csv( 'titanic_pred.csv' , index = False )

    高斯朴素贝叶斯Gaussian Naive Bayes

    from sklearn.naive_bayes import GaussianNB
    #不需要调参
    gnb = GaussianNB()
    gnb.fit(train_X,train_y)
    gnb.score(test_X,test_y)
    #使用机器学习模型,对预测数据集中的生存情况进行预测
    pred_Y = model.predict(pred_X)
    
    '''
    生成的预测值是浮点数(0.0,1,0)
    但是Kaggle要求提交的结果是整型(0,1)
    所以要对数据类型进行转换
    '''
    
    pred_Y=pred_Y.astype(int)
    #乘客id
    passenger_id = full.loc[sourceRow:,'PassengerId']
    #数据框:乘客id,预测生存情况的值
    predDf = pd.DataFrame( 
        { 'PassengerId': passenger_id , 
         'Survived': pred_Y } )
    predDf.shape
    predDf.head()
    #保存结果
    predDf.to_csv( 'titanic_pred_gaussiannb.csv' , index = False )

    其他算法通用框架

    from sklearn.metrics import make_scorer
    from sklearn.metrics import accuracy_score,roc_auc_score
    from time import time
    from sklearn.model_selection import GridSearchCV
    #定义通用函数框架
    def fit_model(alg,parameters):
        X=source_X
        y=source_y#由于数据较少,使用全部数据进行网格搜索
        scorer=make_scorer(roc_auc_score)  #使用roc_auc_score作为评分标准
        grid = GridSearchCV(alg,parameters,scoring=scorer,cv=2)  #使用网格搜索
        start=time()#计时
        grid=grid.fit(X,y)
        end=time()
        t=round(end-start,3)
        print (grid.best_params_)  #输出最佳参数
        print('分数:',grid.best_score_)#查看最佳分数(此处为f1_score)
        print ('searching time for {} is {} s'.format(alg.__class__.__name__,t)) #输出搜索时间
        return grid #返回训练好的模型
    #列出需要使用的算法
    alg1=DecisionTreeClassifier(random_state=0)
    alg2=SVC(probability=True,random_state=0)  #由于使用roc_auc_score作为评分标准,需将SVC中的probability参数设置为True
    alg3=RandomForestClassifier(random_state=0)
    alg4=AdaBoostClassifier(random_state=0)
    alg5=KNeighborsClassifier(n_jobs=-1)
    alg6=XGBClassifier(random_state=0,n_jobs=-1)
    alg7=GradientBoostingClassifier(random_state=0)
    
    #n_jobs 使用电脑的cpu数 -1代表全部使用
    #设置random_state使结果能够重现 固定随机性以便调参

    决策树DecisionTreeClassifier

    参数:https://www.cnblogs.com/lyxML/p/9575820.html

    from sklearn.tree import DecisionTreeClassifier
    #max_depth 树的深度 越深分裂越多 更能捕获有关数据的信息 更容易过拟合 推荐5-20之间
    #min_samples_split 拆分内部节点所需最小样本数 样本数量小于此值时节点不再划分
    #min_samples_leaf 叶节点所需最小样本数 若叶节点数目小于样本数 则会和兄弟节点一起被剪枝
    #max_features 查找最佳拆分时要考虑的最大特征数量 None(所有) log2 sqrt N 特征<50时一般用所有的
    #splitter 默认的best适合样本量不大的情况 若样本数量特别大则使用random
    parameters1 = {
        'max_depth':range(5,20),
        'min_samples_split':range(5,10),
        'min_samples_leaf':range(1,10)
    }
    tree = fit_model(alg1,parameters1)

    #使用机器学习模型,对预测数据集中的生存情况进行预测
    pred_Y = tree.predict(pred_X)
    
    '''
    生成的预测值是浮点数(0.0,1,0)
    但是Kaggle要求提交的结果是整型(0,1)
    所以要对数据类型进行转换
    '''
    
    pred_Y=pred_Y.astype(int)
    #乘客id
    passenger_id = full.loc[sourceRow:,'PassengerId']
    #数据框:乘客id,预测生存情况的值
    predDf = pd.DataFrame( 
        { 'PassengerId': passenger_id , 
         'Survived': pred_Y } )
    predDf.shape
    predDf.head()
    #保存结果
    predDf.to_csv( 'titanic_pred_tree.csv' , index = False )

    支持向量机Support Vector Machines

    参数:https://www.cnblogs.com/solong1989/p/9620170.html

    from sklearn.svm import SVC, LinearSVC
    #C 惩罚系数 即对误差的宽容度 C越高表示越不能容忍出现误差 容易过拟合 C太小 容易欠拟合
    #gamma 越大支持向量越少 过拟合 越小支持向量越多 欠拟合 影响训练和预测的速度
    parameters2 = {
        'C':range(1,20),
        'gamma':np.arange(0.01,0.3)
    }
    svm = fit_model(alg2,parameters2)

    #使用机器学习模型,对预测数据集中的生存情况进行预测
    pred_Y = svm.predict(pred_X)
    
    '''
    生成的预测值是浮点数(0.0,1,0)
    但是Kaggle要求提交的结果是整型(0,1)
    所以要对数据类型进行转换
    '''
    
    pred_Y=pred_Y.astype(int)
    #乘客id
    passenger_id = full.loc[sourceRow:,'PassengerId']
    #数据框:乘客id,预测生存情况的值
    predDf = pd.DataFrame( 
        { 'PassengerId': passenger_id , 
         'Survived': pred_Y } )
    predDf.shape
    predDf.head()
    #保存结果
    predDf.to_csv( 'titanic_pred_svm.csv' , index = False )

    随机森林Random Forests Model

    参数:

    https://www.cnblogs.com/baby-lily/p/10657185.html

    https://blog.csdn.net/R18830287035/article/details/89257857

    from sklearn.ensemble import RandomForestClassifier
    #n_estimators 树的数量 理论上越多子树模型性能越好 但会变慢 选择尽可能高的值
    #max_features 随机森林允许单个决策树使用特征的最大数量 None(所有) log2 sqrt 0.2 特征<50时一般用所有的 
    parameters3 = {
        'n_estimators':range(30,200,5)
    }
    forest = fit_model(alg3,parameters3)

    #使用机器学习模型,对预测数据集中的生存情况进行预测
    pred_Y = forest.predict(pred_X)
    
    '''
    生成的预测值是浮点数(0.0,1,0)
    但是Kaggle要求提交的结果是整型(0,1)
    所以要对数据类型进行转换
    '''
    
    pred_Y=pred_Y.astype(int)
    #乘客id
    passenger_id = full.loc[sourceRow:,'PassengerId']
    #数据框:乘客id,预测生存情况的值
    predDf = pd.DataFrame( 
        { 'PassengerId': passenger_id , 
         'Survived': pred_Y } )
    predDf.shape
    predDf.head()
    #保存结果
    predDf.to_csv( 'titanic_pred_forest.csv' , index = False )

    Adaboost

    参数:https://www.cnblogs.com/mdevelopment/p/9445090.html

    from sklearn.ensemble import AdaBoostClassifier
    #base_estimator 基分类器 默认为决策树
    #n_estimators 基分类器循环次数 默认为50次 过大模型会过拟合
    #learning_rate 学习率 梯度收敛速度,默认为1,如果过大,容易错过最优值,如果过小,则收敛速度会很慢;
    #              该值需要和n_estimators进行一个权衡,当分类器迭代次数较少时,学习率可以小一些,当迭代次数较多时,学习率可以适当放大。
    #可以调整基分类器的参数
    parameters4 = {
        'n_estimators':range(10,200,5),
        'learning_rate':np.arange(0.5,2,0.1)
    }
    adaboost = fit_model(alg4,parameters4)

    #使用机器学习模型,对预测数据集中的生存情况进行预测
    pred_Y = adaboost.predict(pred_X)
    
    '''
    生成的预测值是浮点数(0.0,1,0)
    但是Kaggle要求提交的结果是整型(0,1)
    所以要对数据类型进行转换
    '''
    
    pred_Y=pred_Y.astype(int)
    #乘客id
    passenger_id = full.loc[sourceRow:,'PassengerId']
    #数据框:乘客id,预测生存情况的值
    predDf = pd.DataFrame( 
        { 'PassengerId': passenger_id , 
         'Survived': pred_Y } )
    predDf.shape
    predDf.head()
    #保存结果
    predDf.to_csv( 'titanic_pred_adaboost.csv' , index = False )

    KNN K-nearest neighbors

    参数:https://blog.csdn.net/qq_40195360/article/details/86714337

    内存不足 分两次调参

    from sklearn.neighbors import KNeighborsClassifier
    #n_neighbors k值 默认为5 k值较小 训练误差&偏差小 泛化误差&方差大 欠拟合 较大过拟合
    #weights 样本的近邻样本的权重 可选择uniform都一样/distance权重距离反比例/自定义
    #       若样本成簇 则用默认的uniform 若样本分布较乱 则可以用distance
    #leaf_size 控制使用kd树/球树时 停止建子树的叶节点数量 越小层数越深 随样本数量增加而增加 否则容易过拟合
    parameters5 = {
        'n_neighbors':range(2,10),
        'leaf_size':range(10,100,10)
    }
    knn = fit_model(alg5,parameters5)

    knn_1 = KNeighborsClassifier(weights='distance',n_neighbors=7,leaf_size=10)
    knn_1.fit(source_X,source_y)
    print(knn_1.score(source_X,source_y))

    #使用机器学习模型,对预测数据集中的生存情况进行预测
    pred_Y = knn_1.predict(pred_X)
    
    '''
    生成的预测值是浮点数(0.0,1,0)
    但是Kaggle要求提交的结果是整型(0,1)
    所以要对数据类型进行转换
    '''
    
    pred_Y=pred_Y.astype(int)
    #乘客id
    passenger_id = full.loc[sourceRow:,'PassengerId']
    #数据框:乘客id,预测生存情况的值
    predDf = pd.DataFrame( 
        { 'PassengerId': passenger_id , 
         'Survived': pred_Y } )
    predDf.shape
    predDf.head()
    #保存结果
    predDf.to_csv( 'titanic_pred_knn_1.csv' , index = False )

    Xgboost

    参数:

    https://www.cnblogs.com/tan2810/p/11154708.html

    https://blog.csdn.net/weixin_41580067/article/details/86514402

    https://www.cnblogs.com/TimVerion/p/11436001.html

    https://www.jianshu.com/p/7aab084b7f47

    from xgboost.sklearn import XGBClassifier
    #n_estimators 基分类器循环次数 默认为100
    
    #一般参数 取决于提升器,通常是树或线性模型
    
    
    #提升参数 取决于选择的提升器的相关参数
    #learning_rate学习率 [0,1] 默认为0.3
    #gamma 控制叶子 默认为0 该参数越大 越不容易过拟合
    #max_depth 每棵树的最大深度 默认为6 越大越容易过拟合
    #min_child_weight 每个叶子的最小权重和 默认为1 越大越不易过拟合
    #subsample 样本采样比率 (0,1] 默认为1
    #colsample_bytree 列采样比率 (0,1] 默认为1 对每棵树生成用的特征进行列采样
    #lambda 正则化参数 >=0 默认为1 越大越不易过拟合
    #alpha 正则化参数 >=0 默认为1 越大越不易过拟合
    
    #学习参数 取决于指定学习任务和相应的学习目标
    
    #内存不足 分四次调参
    
    parameters6_1 = {
        'n_estimators':range(10,200,5),
    #    'max_depth':range(5,20),
    #    'min_child_weight':range(2,10),
    #    'subsample':np.arange(0.1,1,0.1),
    #    'colsample_bytree':np.arange(0.1,1,0.1),
    #    'reg_lambda':np.arange(0.2,2,0.1),
    #    'reg_alpha':np.arange(0.2,2,0.1)
    }
    xgb1 = fit_model(alg6,parameters6_1)

    parameters6_2 = {
        'max_depth':range(2,20),
        'min_child_weight':range(2,10),
    }
    
    alg6=XGBClassifier(n_estimators=15,random_state=0,n_jobs=-1)
    xgb2 = fit_model(alg6,parameters6_2)

    parameters6_4 = {
        'reg_lambda':np.arange(0.2,2,0.1),
        'reg_alpha':np.arange(0.2,2,0.1)
    }
    
    alg6=XGBClassifier(n_estimators=15,max_depth=5,min_child_weight=7,random_state=0,n_jobs=-1)
    xgb4 = fit_model(alg6,parameters6_4)

    在调subsample和colsample_bytree的时候发现score反而下降 就算了

    #使用机器学习模型,对预测数据集中的生存情况进行预测
    pred_Y = xgb4.predict(pred_X)
    
    '''
    生成的预测值是浮点数(0.0,1,0)
    但是Kaggle要求提交的结果是整型(0,1)
    所以要对数据类型进行转换
    '''
    
    pred_Y=pred_Y.astype(int)
    #乘客id
    passenger_id = full.loc[sourceRow:,'PassengerId']
    #数据框:乘客id,预测生存情况的值
    predDf = pd.DataFrame( 
        { 'PassengerId': passenger_id , 
         'Survived': pred_Y } )
    predDf.shape
    predDf.head()
    #保存结果
    predDf.to_csv( 'titanic_pred_xgb.csv' , index = False )

     Gradient Boosting Classifier

    参数:

    https://blog.csdn.net/RuDing/article/details/78332192

    https://blog.csdn.net/han_xiaoyang/article/details/52663170

    from sklearn.ensemble import GradientBoostingClassifier
    #初始值
    parameters7_1 = {
        'n_estimators':range(10,200,5)
    }
    gbc1 = fit_model(alg7,parameters7_1)

    #先调整对结果影响较大的参数
    #max_depth min_samples_split
    parameters7_2 = {
        'max_depth':range(2,20),
        'min_samples_split':(5,10)
    }
    alg7=XGBClassifier(n_estimators=20,random_state=0,n_jobs=-1)
    gbc2 = fit_model(alg7,parameters7_2)

    #min_samples_leaf
    parameters7_3 = {
        'min_samples_leaf':(10,100,5)
    }
    alg7=XGBClassifier(max_depth=5,min_samples_split=5,n_estimators=20,random_state=0,n_jobs=-1)
    gbc3 = fit_model(alg7,parameters7_3)

    #max_features
    parameters7_4 = {
        'max_features':(2,100,5)
    }
    alg7=XGBClassifier(min_samples_leaf=10,max_depth=5,min_samples_split=5,n_estimators=20,random_state=0,n_jobs=-1)
    gbc4 = fit_model(alg7,parameters7_4)

    #使用机器学习模型,对预测数据集中的生存情况进行预测
    pred_Y = gbc4.predict(pred_X)
    
    '''
    生成的预测值是浮点数(0.0,1,0)
    但是Kaggle要求提交的结果是整型(0,1)
    所以要对数据类型进行转换
    '''
    
    pred_Y=pred_Y.astype(int)
    #乘客id
    passenger_id = full.loc[sourceRow:,'PassengerId']
    #数据框:乘客id,预测生存情况的值
    predDf = pd.DataFrame( 
        { 'PassengerId': passenger_id , 
         'Survived': pred_Y } )
    predDf.shape
    predDf.head()
    #保存结果
    predDf.to_csv( 'titanic_pred_gbc.csv' , index = False )

     

    预测结果

     

    总结

    再 次 入 门

    1、熟悉常用模型&基本原理

    2、学习调参姿势

     

     

     

     

     

    展开全文
  • 泰坦尼克号生存预测(超详细)

    千次阅读 多人点赞 2021-01-15 11:21:05
    第二部分:泰坦尼克号生存预测 一、实验目的 通过数据堆叠、数据清洗、特征提取、特征选择、构建模型等方法,实现对泰坦尼克号生存人数的预测。 二、实验内容 1、提出问题 2、理解数据 3、数据清洗 4、特征提取 5...

    上学期尝试着去做的一个python关于数据处理的项目,主要过程包括数据预处理、特征提取、特征选择、模型构建与求解,每一部分都有详细的分析和总结。由于时间原因,没有考虑文章的排版以及可能忽略了一些细节,欢迎大家一起学习交流~

    泰坦尼克号生存率预测

    通过数据堆叠、数据清洗、特征提取、特征选择、构建模型等方法,实现对泰坦尼克号生存人数的预测。

    1、提出问题
    已给的数据包含训练数据和测试数据,其中训练数据维度为 891 12, 测试数据集维度为 418 11,训练集比测试集多了一列特征 Survived。我们要解决的问题就是根据所给的数据选择合适的模型,来预测测试数据集的 Survived 特征的那一列。

    2、理解数据

    1)采集数据
    从Kaggle泰坦尼克号项目页面下载数据:https://www.kaggle.com/c/titanic

    2)导入数据
    首先我们将训练数据和测试数据进行纵向堆叠,方便数据处理。

    #合并数据集,方便同时对两个数据集进行清洗
    full = train.append( test , ignore_index = True )#使用append
    print ('合并后的数据集:',full.shape)进行纵向堆叠
    

    在这里插入图片描述
    3)查看数据集信息
    在这用 describe 函数进行了描述,发现没有异常值,但是存在缺失值。我们发现数据总共有 1309 行。

    其中数据类型列:年龄(Age)、船舱号(Cabin)里面有缺失数据:
    1)年龄(Age)里面数据总数是 1046 条,缺失了 1309-1046=263
    2)船票价格(Fare)里面数据总数是 1308 条,缺失了 1 条数据。

    字符串列:
    1)登船港口(Embarked)里面数据总数是 1307,只缺失了 2 条数据,缺失比较少
    2)船舱号(Cabin)里面数据总数是 295,缺失了 1309-295=1014,缺失比较大。
    这为我们下一步数据清洗指明了方向,只有知道哪些数据缺失数据,我们才能有针对性的处理。

    print(full.isnull().sum())
    

    在这里插入图片描述

    3、数据清洗
    1)数据预处理(fullna 函数)
    缺失值处理一般采用以下方式:
    如果是数值类型,用平均值取代;
    如果是分类数据,用最常见的类别取代;
    使用模型预测缺失值,例如:K-NN

    在这采用的是以下方式进行处理:
    数值类型:对于年龄和船票价格,采用的是平均数来填充缺失值。

    print ('合并后的数据集:',full.shape)
    print('处理前:')
    print(full.isnull().sum())
    #年龄(Age)
    full['Age']=full['Age'].fillna( full['Age'].mean() )
    #船票价格(Fare)
    full['Fare'] = full['Fare'].fillna( full['Fare'].mean() )
    print('处理后:')
    print(full.isnull().sum())
    

    在这里插入图片描述

    字符串类型:
    对于登船港口(Embarked),分别计算出各个类别的数量,采用最常见的类别进行填充。
    在这里插入图片描述
    对于船舱号(Cabin),由于缺失的数据太多,将缺失的数据用’U’代替,表示未知。

    在这里插入图片描述

    4、特征提取

    数据分类
    数据分类的过程比较麻烦,对于有直接类别的数据还有字符串类型的数据进行了不同方式的处理。

    1)有直接类别的
    乘客性别(Sex):男性 male,女性female

    在这里插入图片描述
    2)有直接类别的字符串类型
    登船港口(Embarked):
    出发地点S=英国南安普顿Southampton
    途径地点 1:C=法国 瑟堡市Cherbourg,
    出发地点 2:Q=爱尔兰 昆士敦 Queenstown

    在这使用get_dummies进行one-hot编码,产生虚拟变量(dummy variables),列名前缀是Embarked。

    embarkedDf = pd.DataFrame()
    embarkedDf = pd.get_dummies( full['Embarked'] , prefix='Embarked' )
    

    在这里插入图片描述

    对客舱等级(Pclass)进行类似于登船港口(Embarked)相同的处理方式。

    pclassDf = pd.DataFrame()
    #使用get_dummies进行one-hot编码,列名前缀是Pclass
    pclassDf = pd.get_dummies( full['Pclass'] , prefix='Pclass' )
    full = pd.concat([full,pclassDf],axis=1)
    #删掉客舱等级(Pclass)这一列
    full.drop('Pclass',axis=1,inplace=True)
    

    在这里插入图片描述

    做到这一步肯定有同学存在疑问:one-hot是什么呢?
    下面我们就逐步解释一下:
    one-hot的基本思想:将离散型特征的每一种取值都看成一种状态,若你的这一特征中有N个不相同的取值,那么我们就可以将该特征抽象成N种不同的状态,one-hot编码保证了每一个取值只会使得一种状态处于“激活态”,也就是说这N种状态中只有一个状态位值为1,其他状态位都是0。

    那么为什么使用one-hot编码?
    我们之所以不使用标签编码,因为标签编码的问题是它假定类别值越高,该类别更好。显然在实际应用和生活中,这肯定不是一个好的方案,是我们所不能接受的。
    我们使用one hot编码器对类别进行“二进制化”操作,然后将其作为模型训练的特征,原因正在于此。当然,如果我们在设计网络的时候考虑到这点,对标签编码的类别值进行特别处理,那就没问题。不过,在大多数情况下,使用one hot编码是一个更简单直接的方案。
    另外,如果原本的标签编码是有序的,那one hot编码就不合适了——会丢失顺序信息。

    举个例子:
    如果把客舱等级分为1,2,3,我们要预测的是泰坦尼克号的生存率,你知道每个人的生存率跟客舱等级具体有什么样的关系吗?
    也就是说我们并不知道客舱等级是1,2,3哪个好,我们没办法对其量化,1,2,3只是一个标签,并不能对其进行分类,但是我们可以通过one-hot编码来量化这个特征是0还是1.也就是说可以找到这个特征存在于不存在与生存和死亡之间的关系。

    3)没有直接类别的字符串类型:对这部分数据的处理比较麻烦,可能从这部分数据里面提取出特征来,并对数据进行分类。
    分别包括对乘客姓名(Name) 客舱号(Cabin) 船票编号(Ticket)的处理:

    对于乘客名字(Name)的处理:
    注意到在乘客名字(Name)中,有一个非常显著的特点:
    乘客头衔每个名字当中都包含了具体的称谓或者说是头衔,将这部分信息提取出来后可以作为非常有用一个新变量,可以帮助我们进行预测,因为在那个年代的西方国家是很注重称谓的。

    于是我们可以从姓名中获取头衔并进行 one-hot 编码。

    def getTitle(name):
        str1=name.split( ',' )[1] #Mr. Owen Harris
        str2=str1.split( '.' )[0]#Mr
        #strip() 方法用于移除字符串头尾指定的字符(默认为空格)
        str3=str2.strip()
        return str3
    
    titleDf = pd.DataFrame()
    #map函数:对Series每个数据应用自定义的函数计算
    titleDf['Title'] = full['Name'].map(getTitle)
    

    在这里插入图片描述
    根据常识,外国人很讲究的,称呼不同对应于不同的社会地位:
    定义以下几种头衔类别:
    Officer政府官员
    Royalty王室(皇室)
    Mr已婚男士
    Mrs已婚妇女
    Miss年轻未婚女子
    Master有技能的人/教师

    title_mapDict = {
                        "Capt":       "Officer",
                        "Col":        "Officer",
                        "Major":      "Officer",
                        "Jonkheer":   "Royalty",
                        "Don":        "Royalty",
                        "Sir" :       "Royalty",
                        "Dr":         "Officer",
                        "Rev":        "Officer",
                        "the Countess":"Royalty",
                        "Dona":       "Royalty",
                        "Mme":        "Mrs",
                        "Mlle":       "Miss",
                        "Ms":         "Mrs",
                        "Mr" :        "Mr",
                        "Mrs" :       "Mrs",
                        "Miss" :      "Miss",
                        "Master" :    "Master",
                        "Lady" :      "Royalty"
                        }
    #map函数:对Series每个数据应用自定义的函数计算
    titleDf['Title'] = titleDf['Title'].map(title_mapDict)
    #使用get_dummies进行one-hot编码
    titleDf = pd.get_dummies(titleDf['Title'])
    

    在这里插入图片描述
    对于客舱号(Cabin)的处理(与Name 类似):从客舱号中提取客舱类别并进行 one-hot 编码,在这里就不赘述了,后面会给出详细的代码。

    在这里插入图片描述

    对于同代直系亲属数(Parch)和不同代直系亲属数(SibSp)的处理:

    家庭人数=同代直系亲属数(Parch)+不同代直系亲属数(SibSp)+乘客自己
    (因为乘客自己也是家庭成员的一个,所以这里加1)
    familyDf[ ‘FamilySize’ ] = full[ ‘Parch’ ] + full[ ‘SibSp’ ] + 1

    同时我们要根据家庭人数建立家庭类别:
    家庭人数=同代直系亲属数(Parch)+不同代直系亲属数(SibSp)+乘客自己
    家庭类别:小家庭Family_Single:家庭人数=1;
    中等家庭Family_Small: 2<=家庭人数<=4
    大家庭Family_Large: 家庭人数>=5

    我们为什么要这么处理呢?
    因为我们并不知道最后具体到每个人的生存概率和家庭成员人数之间到底有着怎样的关系,所以我们要将其量化,变成方便我们预测的形式。

    familyDf[ 'Family_Single' ] = familyDf[ 'FamilySize' ].map( lambda s : 1 if s == 1 else 0 )
    familyDf[ 'Family_Small' ]  = familyDf[ 'FamilySize' ].map( lambda s : 1 if 2 <= s <= 4 else 0 )
    familyDf[ 'Family_Large' ]  = familyDf[ 'FamilySize' ].map( lambda s : 1 if 5 <= s else 0 )
    

    在这里插入图片描述

    5、特征选择

    (1)相关系数法:计算各个特征的相关系数
    在这里插入图片描述

    (2)提取特征:对矩阵中 Survived 那一列输出:
    在这里插入图片描述
    存在问题:在进行特征选择时面临了问题,cabinDf(船舱号)和embarked(登船港口)这两个特征与特征Survived的相关性的没超过0.2,但是也不是没有相关性,所以在此尝试了使用与不使用这两种特征的两种情况,分别进行了实验,结果表明两种特征都要结果会好一点。

    full_X = pd.concat( [titleDf,#头衔
                         pclassDf,#客舱等级
                         familyDf,#家庭大小
                         full['Fare'],#船票价格
                         full['Sex'],#性别
                         cabinDf,#船舱号
                         embarkedDf,#登船港口
                        ] , axis=1 )
    #只留cabinDf船舱号
    # full_X = pd.concat( [titleDf,#头衔
    #                      pclassDf,#客舱等级
    #                      familyDf,#家庭大小
    #                      full['Fare'],#船票价格
    #                      full['Sex']#性别
    #                      cabinDf,#船舱号
    #                     ] , axis=1 )
    # #只留embarkedDf,#登船港口
    # full_X = pd.concat( [titleDf,#头衔
    #                      pclassDf,#客舱等级
    #                      familyDf,#家庭大小
    #                      full['Fare'],#船票价格
    #                      full['Sex']#性别
    #                      embarkedDf,#登船港口
    #                     ] , axis=1 )
    # #两个都不要
    # full_X = pd.concat( [titleDf,#头衔
    #                      pclassDf,#客舱等级
    #                      familyDf,#家庭大小
    #                      full['Fare'],#船票价格
    #                      full['Sex']#性别
    #                     ] , axis=1 )
    

    6、构建模型
    (1)建立训练数据集和测试数据集,从原始数据集(名名为 source,即前 891 行数据)中拆分出训练数据集和测试数据集。
    在这里插入图片描述

    (2)选择机器学习算法
    在这里尝试了不同的机器学习算法,并对每个算法进行了评估。

    from sklearn.model_selection import train_test_split
    for i in range(0,4):
        train_X, test_X, train_y, test_y = train_test_split(source_X ,
                                                            source_y,
                                                          train_size=size[i],
                                                            random_state=5)
        #逻辑回归
        from sklearn.linear_model import LogisticRegression
        model = LogisticRegression()
        model.fit( train_X , train_y )
        scorelist[0].append(model.score(test_X , test_y ))
    
        #随机森林Random Forests Model
        from sklearn.ensemble import RandomForestClassifier
        model = RandomForestClassifier(n_estimators=100)
        model.fit( train_X , train_y )
        scorelist[1].append(model.score(test_X , test_y ))
    
        #支持向量机Support Vector Machines
        from sklearn.svm import SVC
        model = SVC()
        model.fit( train_X , train_y )
        scorelist[2].append(model.score(test_X , test_y ))
    
        #梯度提升决策分类Gradient Boosting Classifier
        from sklearn.ensemble import GradientBoostingClassifier
        model = GradientBoostingClassifier()
        model.fit( train_X , train_y )
        scorelist[3].append(model.score(test_X , test_y ))
    
        #KNN最邻近算法 K-nearest neighbors
        from sklearn.neighbors import KNeighborsClassifier
        model = KNeighborsClassifier(n_neighbors = 3)
        model.fit( train_X , train_y )
        scorelist[4].append(model.score(test_X , test_y ))
    
        #朴素贝叶斯分类 Gaussian Naive Bayes
        from sklearn.naive_bayes import GaussianNB
        model = GaussianNB()
        model.fit( train_X , train_y )
        scorelist[5].append(model.score(test_X , test_y ))
        # 分类问题,score得到的是模型的正确率
        #print(model.score(test_X , test_y ))
    

    (3)训练、评估模型
    在这里插入图片描述对比不同模型的准确率,我们发现逻辑回归模型的表现在这个数据集上的表现要好一点。

    7、方案实施
    使用预测数据集到底预测结果,并保存到 csv 文件中:

    在这里插入图片描述

    总结:
    选择了一个比较基础的kaggle项目,目的是熟悉kaggle竞赛流程,深入分析理解项目中的每一行个过程,这个项目对数据的特征处理那一步 进行了比较多的处理,从中学习到了很多。

    后续:
    经老师和同学们的反馈,还能将工作进行进一步的细化,以提高预测的准确率,比如可以在对年龄这一列进行处理的过程中,可以根据年龄的大小将年龄进行分段处理,感觉年龄的大小与最终生存率的大小有一定的关系。

    但是由于时间有限(我太懒)并没有去尝试,有缘再见吧。。。

    
    #导入处理数据包
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    #导入数据
    #训练数据集
    train = pd.read_csv("./train.csv")
    #测试数据集
    test  = pd.read_csv("./test.csv")
    #这里要记住训练数据集有891条数据,方便后面从中拆分出测试数据集用于提交Kaggle结果
    print ('训练数据集:',train.shape,'测试数据集:',test.shape)
    rowNum_train=train.shape[0]
    rowNum_test=test.shape[0]
    print('kaggle训练数据集有多少行数据:',rowNum_train,
         ',kaggle测试数据集有多少行数据:',rowNum_test,)
    #合并数据集,方便同时对两个数据集进行清洗
    full = train.append( test , ignore_index = True )#使用append进行纵向堆叠
    
    # print ('合并后的数据集:',full.shape)
    # print('处理前:')
    print(full.isnull().sum())
    #年龄(Age)
    full['Age']=full['Age'].fillna( full['Age'].mean() )
    #船票价格(Fare)
    full['Fare'] = full['Fare'].fillna( full['Fare'].mean() )
    # print('处理后:')
    # print(full.isnull().sum())
    full['Embarked'] = full['Embarked'].fillna( 'S' )
    full['Cabin'] = full['Cabin'].fillna( 'U' )
    sex_mapDict={'male':1,
                'female':0}
    #map函数:对Series每个数据应用自定义的函数计算
    full['Sex']=full['Sex'].map(sex_mapDict)
    embarkedDf = pd.DataFrame()
    embarkedDf = pd.get_dummies( full['Embarked'] , prefix='Embarked' )
    full = pd.concat([full,embarkedDf],axis=1)
    full.drop('Embarked',axis=1,inplace=True)
    pclassDf = pd.DataFrame()
    
    #使用get_dummies进行one-hot编码,列名前缀是Pclass
    pclassDf = pd.get_dummies( full['Pclass'] , prefix='Pclass' )
    full = pd.concat([full,pclassDf],axis=1)
    
    #删掉客舱等级(Pclass)这一列
    full.drop('Pclass',axis=1,inplace=True)
    def getTitle(name):
        str1=name.split( ',' )[1] #Mr. Owen Harris
        str2=str1.split( '.' )[0]#Mr
        #strip() 方法用于移除字符串头尾指定的字符(默认为空格)
        str3=str2.strip()
        return str3
    
    titleDf = pd.DataFrame()
    #map函数:对Series每个数据应用自定义的函数计算
    titleDf['Title'] = full['Name'].map(getTitle)
    title_mapDict = {
                        "Capt":       "Officer",
                        "Col":        "Officer",
                        "Major":      "Officer",
                        "Jonkheer":   "Royalty",
                        "Don":        "Royalty",
                        "Sir" :       "Royalty",
                        "Dr":         "Officer",
                        "Rev":        "Officer",
                        "the Countess":"Royalty",
                        "Dona":       "Royalty",
                        "Mme":        "Mrs",
                        "Mlle":       "Miss",
                        "Ms":         "Mrs",
                        "Mr" :        "Mr",
                        "Mrs" :       "Mrs",
                        "Miss" :      "Miss",
                        "Master" :    "Master",
                        "Lady" :      "Royalty"
                        }
    
    #map函数:对Series每个数据应用自定义的函数计算
    titleDf['Title'] = titleDf['Title'].map(title_mapDict)
    
    #使用get_dummies进行one-hot编码
    titleDf = pd.get_dummies(titleDf['Title'])
    #添加one-hot编码产生的虚拟变量(dummy variables)到泰坦尼克号数据集full
    full = pd.concat([full,titleDf],axis=1)
    
    #删掉姓名这一列
    full.drop('Name',axis=1,inplace=True)
    #存放客舱号信息
    cabinDf = pd.DataFrame()
    
    '''
    客场号的类别值是首字母,例如:
    C85 类别映射为首字母C
    '''
    full[ 'Cabin' ] = full[ 'Cabin' ].map( lambda c : c[0] )#客舱号的首字母代表处于哪个,U代表不知道属于哪个船舱
    
    ##使用get_dummies进行one-hot编码,列名前缀是Cabin
    cabinDf = pd.get_dummies( full['Cabin'] , prefix = 'Cabin' )
    #添加one-hot编码产生的虚拟变量(dummy variables)到泰坦尼克号数据集full
    full = pd.concat([full,cabinDf],axis=1)
    
    #删掉客舱号这一列
    full.drop('Cabin',axis=1,inplace=True)
    familyDf = pd.DataFrame()
    
    '''
    家庭人数=同代直系亲属数(Parch)+不同代直系亲属数(SibSp)+乘客自己
    (因为乘客自己也是家庭成员的一个,所以这里加1)
    '''
    familyDf[ 'FamilySize' ] = full[ 'Parch' ] + full[ 'SibSp' ] + 1
    familyDf[ 'Family_Single' ] = familyDf[ 'FamilySize' ].map( lambda s : 1 if s == 1 else 0 )
    familyDf[ 'Family_Small' ]  = familyDf[ 'FamilySize' ].map( lambda s : 1 if 2 <= s <= 4 else 0 )
    familyDf[ 'Family_Large' ]  = familyDf[ 'FamilySize' ].map( lambda s : 1 if 5 <= s else 0 )
    full = pd.concat([full,familyDf],axis=1)
    full.drop('FamilySize',axis=1,inplace=True)
    corrDf = full.corr()
    corrDf['Survived'].sort_values(ascending =False)
    
    full_X = pd.concat( [titleDf,#头衔
                         pclassDf,#客舱等级
                         familyDf,#家庭大小
                         full['Fare'],#船票价格
                         full['Sex'],#性别
                         cabinDf,#船舱号
                         embarkedDf,#登船港口
                        ] , axis=1 )
    
    #只留cabinDf船舱号
    # full_X = pd.concat( [titleDf,#头衔
    #                      pclassDf,#客舱等级
    #                      familyDf,#家庭大小
    #                      full['Fare'],#船票价格
    #                      full['Sex']#性别
    #                      cabinDf,#船舱号
    #                     ] , axis=1 )
    # #只留embarkedDf,#登船港口
    # full_X = pd.concat( [titleDf,#头衔
    #                      pclassDf,#客舱等级
    #                      familyDf,#家庭大小
    #                      full['Fare'],#船票价格
    #                      full['Sex']#性别
    #                      embarkedDf,#登船港口
    #                     ] , axis=1 )
    # #两个都不要
    # full_X = pd.concat( [titleDf,#头衔
    #                      pclassDf,#客舱等级
    #                      familyDf,#家庭大小
    #                      full['Fare'],#船票价格
    #                      full['Sex']#性别
    #                     ] , axis=1 )
    
    sourceRow=891
    
    '''
    sourceRow是我们在最开始合并数据前知道的,原始数据集有总共有891条数据
    从特征集合full_X中提取原始数据集提取前891行数据时,我们要减去1,因为行号是从0开始的。
    '''
    #原始数据集:特征
    source_X = full_X.loc[0:sourceRow-1,:]
    #原始数据集:标签
    source_y = full.loc[0:sourceRow-1,'Survived']
    
    #预测数据集:特征
    pred_X = full_X.loc[sourceRow:,:]
    
    #建立模型用的训练数据集和测试数据集
    
    size=np.arange(0.6,1,0.1)
    scorelist=[[],[],[],[],[],[]]
    from sklearn.model_selection import train_test_split
    for i in range(0,4):
        train_X, test_X, train_y, test_y = train_test_split(source_X ,
                                                            source_y,
                                                          train_size=size[i],
                                                            random_state=5)
        #逻辑回归
        from sklearn.linear_model import LogisticRegression
        model = LogisticRegression()
        model.fit( train_X , train_y )
        scorelist[0].append(model.score(test_X , test_y ))
    
        #随机森林Random Forests Model
        from sklearn.ensemble import RandomForestClassifier
        model = RandomForestClassifier(n_estimators=100)
        model.fit( train_X , train_y )
        scorelist[1].append(model.score(test_X , test_y ))
    
        #支持向量机Support Vector Machines
        from sklearn.svm import SVC
        model = SVC()
        model.fit( train_X , train_y )
        scorelist[2].append(model.score(test_X , test_y ))
    
        #梯度提升决策分类Gradient Boosting Classifier
        from sklearn.ensemble import GradientBoostingClassifier
        model = GradientBoostingClassifier()
        model.fit( train_X , train_y )
        scorelist[3].append(model.score(test_X , test_y ))
    
        #KNN最邻近算法 K-nearest neighbors
        from sklearn.neighbors import KNeighborsClassifier
        model = KNeighborsClassifier(n_neighbors = 3)
        model.fit( train_X , train_y )
        scorelist[4].append(model.score(test_X , test_y ))
    
        #朴素贝叶斯分类 Gaussian Naive Bayes
        from sklearn.naive_bayes import GaussianNB
        model = GaussianNB()
        model.fit( train_X , train_y )
        scorelist[5].append(model.score(test_X , test_y ))
        # 分类问题,score得到的是模型的正确率
        #print(model.score(test_X , test_y ))
    
    plt.rcParams['font.sans-serif'] = 'SimHei'
    plt.rcParams['axes.unicode_minus'] = False
    color_list = ('red', 'blue', 'lightgreen', 'cornflowerblue', 'turquoise', 'magenta')
    for i in range(0,6):
        plt.plot(size,scorelist[i],color=color_list[i])
    plt.legend(['逻辑回归', '随机森林','支持向量机','梯度提升决策分类', 'KNN最邻近算法','朴素贝叶斯'])
    
    plt.xlabel('训练集占比')
    plt.ylabel('准确率')
    plt.title('不同的模型随着训练集占比变化曲线')
    plt.show()
    
    
    展开全文
  • 最常用的数据集就是我在之前写的MNIST,波士顿房价,还有今天要给大家介绍的泰坦尼克号生存预测问题。 泰坦尼克号的故事背景大家一定都非常熟悉了,下面我们一起来探索一下相关数据,以及看看如何用机器学习的方法...

    学习机器学习的小伙伴,在入门的时候可以通过相对赶紧简单和干净的数据入门。 最常用的数据集就是我在之前写的MNIST,波士顿房价,还有今天要给大家介绍的泰坦尼克号生存预测问题。

    泰坦尼克号的故事背景大家一定都非常熟悉了,下面我们一起来探索一下相关数据,以及看看如何用机器学习的方法进行分类预测。

    数据加载

    本数据也是Kaggle平台的入门数据之一,可以同Kaggle平台下载训练数据和测试数据,这个竞赛项目也是长年开放的,大家也可以将自己的预测结果上传到Kaggle上。
    https://www.kaggle.com/c/titanic/data

    import pandas as pd
    train_data = pd.read_csv("train.csv")
    
    #预览一下数据
    train_data.head()
    PassengerId	Survived	Pclass	Name	Sex	Age	SibSp	Parch	Ticket	Fare	Cabin	Embarked
    0	1	0	3	Braund, Mr. Owen Harris	male	22.0	1	0	A/5 21171	7.2500	NaN	S
    1	2	1	1	Cumings, Mrs. John Bradley (Florence Briggs Th...	female	38.0	1	0	PC 17599	71.2833	C85	C
    2	3	1	3	Heikkinen, Miss. Laina	female	26.0	0	0	STON/O2. 3101282	7.9250	NaN	S
    3	4	1	1	Futrelle, Mrs. Jacques Heath (Lily May Peel)	female	35.0	1	0	113803	53.1000	C123	S
    4	5	0	3	Allen, Mr. William Henry	male	35.0	0	0	373450	8.0500	NaN	S
    
    print(train_data.shape)
    (891, 12)
    
    train_data.info()
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 891 entries, 0 to 890
    Data columns (total 12 columns):
    PassengerId    891 non-null int64
    Survived       891 non-null int64
    Pclass         891 non-null int64
    Name           891 non-null object
    Sex            891 non-null object
    Age            714 non-null float64
    SibSp          891 non-null int64
    Parch          891 non-null int64
    Ticket         891 non-null object
    Fare           891 non-null float64
    Cabin          204 non-null object
    Embarked       889 non-null object
    dtypes: float64(2), int64(5), object(5)
    memory usage: 83.7+ KB
    
    #可以看到有一些列 比如Cabin,Age有非常多的缺失值
    

    缺失值处理

    泰坦尼克号的数据预处理有两点非常值得大家练手,首先就是缺失值处理,可以看到Cabin和Age是有相当多的缺失值的。

    缺失值常见处理方式:

    1. 如果缺值的样本占总数比例极高,可以直接舍弃了,否则作为特征可能会有带来噪声,影响结果
    2. 如果缺值的样本数适中,且该特征是非连续值(离散),可以把NaN作为一个类别Category,加到类别特征中
    3. 如果缺值的样本数适中,且该属性为连续值,可以考虑给定一个step(比如这里的age,可以考虑每隔2/3岁为一个步长),然后把它离散化,之后把NaN作为一个category加类别特征中
    4. 有些情况下,缺失的值个数并不是特别多,那我们也可以试着根据已有的值,拟合一下数据,补充上

    处理Cabin缺失值
    在决定处理之前不妨先看一下Cabin分布情况。

    Cabin = train_data['Cabin']
    Cabin.value_counts()
    
    B96 B98        4
    C23 C25 C27    4
    G6             4
    E101           3
    D              3
                  ..
    F38            1
    C50            1
    A5             1
    C91            1
    E63            1
    Name: Cabin, Length: 147, dtype: int64
    

    可以看到Cabin的值比较分散,Cabin值基本出现不大于4次,很多都只出现一次。
    下面看一下Cabin的有无对Survive与否的影响。

    import matplotlib.pyplot as plt
    %matplotlib inline
    
    fig = plt.figure()
    fig.set(alpha=0.2)  # 设定图表颜色alpha参数
    
    Survived_nocabin = train_data.Survived[pd.isnull(train_data.Cabin)].value_counts()
    Survived_cabine = train_data.Survived[pd.notnull(train_data.Cabin)].value_counts()
    df=pd.DataFrame({u'with Cabin':Survived_cabin, u'without Cabin':Survived_nocabin}).transpose()
    df.plot(kind='bar', stacked=True)
    plt.title(u"Cabin and Survived Situation")
    plt.xlabel(u"with Cabin or not ") 
    plt.ylabel(u"Number of people")
    plt.show()
    

    有Cabin记录的乘客survival 比例稍高, 可以采用缺失值处理的第二种方法,把这个值分成两个特征,有cabin和无cabin。
    在这里插入图片描述
    处理Age缺失值
    Age属性有177个乘客没有记录, 可以用方法3或者方法4, 下面我们一起来试一下方法4.
    用随机森林拟合一下缺失的年龄数据

    ### 使用 RandomForestClassifier 填补缺失的年龄属性
    def set_missing_ages(df):
     
        # 把已有的数值型特征取出来丢进RandomForestRegressor中
        age_df = df[['Age','Fare', 'Parch', 'SibSp', 'Pclass']]
    
        # 准备训练数据(已知年龄和)和待预测数据(未知年龄)
        known_age = age_df[age_df.Age.notnull()].values
        unknown_age = age_df[age_df.Age.isnull()].values
    
        # y即目标年龄
        y = known_age[:, 0]
    
        # X即特征属性值
        X = known_age[:, 1:]
    
        # fit到RandomForestRegressor之中
        rfr = RandomForestRegressor(random_state=0, n_estimators=2000, n_jobs=-1)
        rfr.fit(X, y)
        
        # 用得到的模型进行未知年龄结果预测
        predictedAges = rfr.predict(unknown_age[:, 1::])
        
        # 用得到的预测结果填补原缺失数据
        df.loc[ (df.Age.isnull()), 'Age' ] = predictedAges 
        
        return df, rfr
    
    def set_Cabin_type(df):
        df.loc[ (df.Cabin.notnull()), 'Cabin' ] = "Yes"
        df.loc[ (df.Cabin.isnull()), 'Cabin' ] = "No"
        return df
    
    
    train_data, rfr = set_missing_ages(train_data)
    train_data = set_Cabin_type(train_data)
    
    

    然后再看一下数据概况

    train_data.info()
    
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 891 entries, 0 to 890
    Data columns (total 12 columns):
    PassengerId    891 non-null int64
    Survived       891 non-null int64
    Pclass         891 non-null int64
    Name           891 non-null object
    Sex            891 non-null object
    Age            891 non-null float64
    SibSp          891 non-null int64
    Parch          891 non-null int64
    Ticket         891 non-null object
    Fare           891 non-null float64
    Cabin          891 non-null object
    Embarked       889 non-null object
    dtypes: float64(2), int64(5), object(5)
    memory usage: 83.7+ KB
    

    最后一步准备数据特征

    # 因为逻辑回归建模时,需要输入的特征都是数值型特征
    # 我们先对类目型的特征离散/因子化
    # 以Cabin为例,原本一个属性维度,因为其取值可以是['yes','no'],而将其平展开为'Cabin_yes','Cabin_no'两个属性
    # 原本Cabin取值为yes的,在此处的'Cabin_yes'下取值为1,在'Cabin_no'下取值为0
    # 原本Cabin取值为no的,在此处的'Cabin_yes'下取值为0,在'Cabin_no'下取值为1
    # 我们使用pandas的get_dummies来完成这个工作,并拼接在原来的data_train之上,如下所示
    dummies_Cabin = pd.get_dummies(train_data['Cabin'], prefix= 'Cabin')
    dummies_Embarked = pd.get_dummies(train_data['Embarked'], prefix= 'Embarked')
    dummies_Sex = pd.get_dummies(train_data['Sex'], prefix= 'Sex')
    dummies_Pclass = pd.get_dummies(train_data['Pclass'], prefix= 'Pclass')
    df = pd.concat([train_data, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1)
    df.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'], axis=1, inplace=True)
    df
    
    
    PassengerId	Survived	Age	SibSp	Parch	Fare	Cabin_No	Cabin_Yes	Embarked_C	Embarked_Q	Embarked_S	Sex_female	Sex_male	Pclass_1	Pclass_2	Pclass_3
    0	1	0	22.00000	1	0	7.2500	1	0	0	0	1	0	1	0	0	1
    1	2	1	38.00000	1	0	71.2833	0	1	1	0	0	1	0	1	0	0
    2	3	1	26.00000	0	0	7.9250	1	0	0	0	1	1	0	0	0	1
    3	4	1	35.00000	1	0	53.1000	0	1	0	0	1	1	0	1	0	0
    4	5	0	35.00000	0	0	8.0500	1	0	0	0	1	0	1	0	0	1
    ...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...
    886	887	0	27.00000	0	0	13.0000	1	0	0	0	1	0	1	0	1	0
    887	888	1	19.00000	0	0	30.0000	0	1	0	0	1	1	0	1	0	0
    888	889	0	16.19395	1	2	23.4500	1	0	0	0	1	1	0	0	0	1
    889	890	1	26.00000	0	0	30.0000	0	1	1	0	0	0	1	1	0	0
    890	891	0	32.00000	0	0	7.7500	1	0	0	1	0	0	1	0	0	1
    891 rows × 16 columns
    
    

    看一下协方差

    correlation_matrix = df.corr().round(2)
    sns.heatmap(data=correlation_matrix,annot=True)
    

    数据预处理

    # 接下来我们要接着做一些数据预处理的工作,比如scaling,将一些变化幅度较大的特征化到[-1,1]之内
    # 这样可以加速logistic regression的收敛
    import sklearn.preprocessing as preprocessing
    scaler = preprocessing.StandardScaler()
    age_scale_param = scaler.fit(df['Age'].values.reshape(-1,1))
    df['Age_scaled'] = scaler.fit_transform(df['Age'].values.reshape(-1,1), age_scale_param)
    fare_scale_param = scaler.fit(df['Fare'].values.reshape(-1,1))
    df['Fare_scaled'] = scaler.fit_transform(df['Fare'].values.reshape(-1,1), fare_scale_param)
    df
    
    # 我们把需要的feature字段取出来,转成numpy格式,使用scikit-learn中的LogisticRegression建模
    from sklearn import linear_model
    
    train_df = df.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
    train_np = train_df.as_matrix()
    # y即Survival结果
    y = train_np[:, 0]
    # X即特征属性值
    X = train_np[:, 1:]
    # fit到RandomForestRegressor之中
    clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
    clf.fit(X, y)   
    clf
    
    展开全文
  • 泰坦尼克号生成预测 这是kaggle上面比较入门的一个比赛。今天让我们来看看怎么做吧。kaggle传送门。首先报名,下载数据集。 数据载入及概述 首先导入从Kaggle上面下载的数据集,在导入的过程中就需要先导入一些必备...

    泰坦尼克号生存预测

    这是kaggle上面比较入门的一个比赛。今天让我们来看看怎么做吧。kaggle传送门。首先报名,下载数据集。

    数据载入及概述

    首先导入从Kaggle上面下载的数据集,在导入的过程中就需要先导入一些必备的包了。

    import numpy as np
    import pandas as pd
    
    # 接着导入我们的训练数据
    filename = 'titanic/train.csv'  # 这是我存放的文件路径,这边换成你们自己的
    train = pd.read_csv(filename)
    

    然后来看看训练数据集长啥样。(每个列的名字的含义,在kaggle页面有介绍,这边就不说了。)

    train.head()
    

    image-20200820170750314

    train.info()
    
    image-20200820170950383

    通过info()这个函数我们可要知道,哪些特征的数值类型是什么。比如,上面PassengerId,Survived,Pclass,Age等是数值型数据,而Name,Sex,Ticket等是字符型数据。字符型数据肯定到后面是要转换的,可能转换成one-hot类型的。不过数值型数据也可能是需要转换的。后面会细说。

    trian.isnull().sum()
    
    image-20200820171408946

    通过isnull()可以看出哪些列缺失了数据,缺失了多少行。只有对缺失数据的处理有很多种,比如说填充,或者删去。

    数据可视化

    年龄与生存

    我们都知道,在危难来临之际,一般都会让孩子和老人先脱离危险,所以我们将年龄分成3个段[0,20],[20,60],[60,80]。画出存活的人数和年龄段的图。

    import seaborn as sns
    examine = train.copy() # 这边将训练数据集备份一份
    #将连续变量Age划分为[0,5) [5,15) [15,30) [30,50) [50,80)五个年龄段,并分别用类别变量12345表示
    examine['AgeBand'] = pd.cut(examine['Age'],[0,20,60,80],labels = ['1','2','3'])
    sns.barplot(x='AgeBand', y='Survived', data=examine)
    
    image-20200820173257324

    从上图,可以明显看出小孩的存活率偏高,那为什么老人存活率最低呢,是因为泰坦尼克号与一座冰山相撞,那么有冰山,必然说明那个地方的气候很寒冷,老人的身体不太好,所以存活率这么一解释,是不是也说得通。

    性别与生存

    前面说的小孩和老人优先,当然了还有一句是女士优先。所以我们来看看性别与存活的关系。

    sns.barplot(x="Sex", y="Survived", data=examine)
    
    image-20200820173638288 image-20200820180456938
    # 提示:计算男女中死亡人数 1表示生存,0表示死亡
    examine.groupby(['Sex','Survived'])['Survived'].count().unstack().plot(kind='bar',stacked='True')
    plt.title('survived_count')
    plt.ylabel('count')
    

    从上面两个图,明显可以看出两者存活的几率是相差很大的。女性的存活率是明显高于男性。这也符合实际,在泰坦尼克号这部电影中,也是能够看出来。

    社会地位与生存

    可能有人看到社会地位就有点疑惑了,数据集里面哪有这个特征,其实不然。仓位等级和票价多多少少都能说明的。就好比几十年前,家里有车的人都是大户人家,地主官僚跟普通人的地位还是差别很大的。因此萌发一个想法,看这个特征跟存活率的关系如何。

    sns.barplot(x="Pclass", y="Survived", data=examine)
    
    image-20200820180018917

    从图中看出来,仓位等级跟生存关系还是很大的,这也比较符合现实。懂得都懂。

    泰坦尼克号数据集中不同仓位等级的人年龄分布情况

    examine.Age[examine.Pclass == 1].plot(kind='kde')
    examine.Age[examine.Pclass == 2].plot(kind='kde')
    examine.Age[examine.Pclass == 3].plot(kind='kde')
    plt.xlabel("age")
    plt.legend((1,2,3),loc="best")
    
    image-20200820180703425

    不过这个图好像跟生存关系不大。

    数据清洗及特征处理

    缺失值的处理

    image-20200820171408946

    前面分析过,'Cabin'这列缺失了687个数据,总共才891个数据。而且这列确实跟生存与否没什么关系,因此就直接删除掉这列。还有'Name''Ticket '跟生存也没什么关系,一并删除了。

    train.drop(['Cabin', 'Name', 'Ticket'], inplace=True, axis=1)
    train.head()
    
    image-20200820181911481

    然后来看'Age'这列的缺失值,这列缺失了100多条数据,因此我们采用填充的方式,不过填充的方式有很多,这边使用均值填充。

    train["Age"] = train["Age"].fillna(train["Age"].mean())
    trian.isnull().sum()
    
    image-20200820182510244

    现在看到只有'Embarked'这列还剩下2个缺失值,2个缺失值好办,我们直接删掉就好了,对结果没什么影响。

    train = train.dropna()
    

    删掉这两条数据之后,总得数据就变成了889条了。缺失值的处理就到这里差不多结束了。

    分类变量的处理

    首先将二分类变量'Sex'转换成0和1。

    train['Sex'] = (train['Sex'] == 'male').astype(np.int64)
    

    然后将三分类变量'Embarked'转换成0、1、2。

    labels = train['Embarked'].unique().tolist()
    train['Embarked'] = train['Embarked'].apply(lambda x : labels.index(x))
    

    当然,将分类变量转换成数值型的方式又很多,我只是写了其中的一种。

    将数据中的训练变量和标签分开

    X = train.iloc[:, train.columns != 'Survived']
    y = train.iloc[:, train.columns == 'Survived']
    X.shape, y.shape
    # 输出
    # (889, 8), (889, 1)
    

    接下来,要将训练集拆分为训练集和验证集。并且训练集和验证集的比列为3:1。

    from sklearn.model_selection import train_test_split
    Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.25)
    Xtrain.shape, Xtest.shape
    # 输出
    # (666, 8), (223, 8)
    

    还有最后一步,我们要重新设置下索引。至于为什么需要,看下面这张图就可以了。

    image-20200820210343454
    for i in [Xtrain, Xtest, Ytrain, Ytest]:
        i.reset_index(drop=True, inplace=True)
    

    到这里,数据的清洗,特征处理的工作基本完成了。接下来就是建模了。

    数据建模及模型评估

    先导入一些后面会用到的库

    from sklearn.tree import DecisionTreeClassifier
    from sklearn.model_selection import train_test_split
    from sklearn.model_selection import GridSearchCV
    from sklearn.model_selection import cross_val_score
    from sklearn.linear_model import LogisticRegression
    from sklearn.ensemble import RandomForestClassifier
    import matplotlib.pyplot as plt
    

    决策树

    clf = DecisionTreeClassifier(random_state=0)
    clf.fit(Xtrain, Ytrain)
    # 查看验证集score值
    print("Testing set score: {:.2f}".format(clf.score(Xtest, Ytest)))
    # Testing set score: 0.74
    

    使用10折交叉验证来评估,并且取平均。

    score = cross_val_score(clf,X,y,cv=10).mean()
    # 0.757
    

    接下来优化下这个模型

    tr = []
    te = []
    for i in range(1, 11):
        clf = DecisionTreeClassifier(random_state=0,max_depth=i,criterion="entropy")
        clf = clf.fit(Xtrain, Ytrain)
        score_tr = clf.score(Xtrain,Ytrain)
        score_te = cross_val_score(clf,X,y,cv=10).mean()
        tr.append(score_tr)
        te.append(score_te)
    print(max(te))
    plt.plot(range(1,11),tr,color="red",label="train")
    plt.plot(range(1,11),te,color="blue",label="test")
    plt.xticks(range(1,11))
    plt.legend()
    
    image-20200820211514091

    可以看出,最大深度为3的时候,得分最高为0.8166624106230849

    逻辑回归

    # 默认参数逻辑回归模型
    lr = LogisticRegression()
    lr.fit(Xtrain, Ytrain)
    print("Testing set score: {:.2f}".format(lr.score(Xtest, Ytest)))
    # Testing set score: 0.80
    

    使用10折交叉验证来评估,并且取平均。

    score = cross_val_score(lr,X,y,cv=10).mean()
    # 0.795
    

    随机森林

    test = []
    for i in range(1, 11):
        rfc = RandomForestClassifier(n_estimators=100, max_depth=i, random_state=20)
        score = cross_val_score(rfc, X, y, cv=10)
        test.append(score.mean())
    plt.plot(range(1, 11), test)
    
    image-20200820214323400

    可以,发现当最大深度为6的时候,模型的得分最高。接近0.83,我们可以使用网格搜索来获取最优的参数,但是网格搜索比较耗时,这边就不写出来了。

    Bagging

    from sklearn.ensemble import BaggingClassifier
    test = []
    
    for i in range(10, 50, 5):
        clf = BaggingClassifier(n_estimators=i)
        score = cross_val_score(clf, X, y, cv=10)
        test.append(score.mean())
        
    plt.plot(range(10, 50, 5), test)
    plt.ylabel('score')
    plt.xlabel('n_estimators')
    
    image-20200820215404157

    从上图看出,最高应该在0.82左右。

    LGBClassifier

    from lightgbm import LGBMClassifier
    test = []
    for i in range(10, 100, 5):
        lgb = LGBMClassifier(max_depth=2, n_estimators=i)
        score = cross_val_score(lgb, X, y, cv=10)
        test.append(score.mean())
        
    plt.plot(range(10, 100, 5), test)
    plt.ylabel('score')
    plt.xlabel('n_estimators')
    
    image-20200820220218847

    从图中可以看出,最高得分接近0.84。

    集成几个模型

    最后将几个模型集成一下

    clf = [None]*5
    clf[0] = DecisionTreeClassifier(random_state=0,max_depth=3,criterion="entropy")
    clf[1] = LogisticRegression()
    clf[2] = RandomForestClassifier(n_estimators=100, max_depth=6, random_state=20)
    clf[3] = BaggingClassifier(n_estimators=20)
    clf[4] = LGBMClassifier(max_depth=2, n_estimators=40)
    
    predictFrame = pd.DataFrame()
    for model in clf:
        model.fit(Xtrain, Ytrain)
        predictFrame[str(model)[:14]] = model.predict(Xtest)
    
    te = []
    for i in range(1, 10):
        clf_ = RandomForestClassifier(n_estimators=100, max_depth=i, random_state=0)
        score = cross_val_score(clf_, predictFrame, Ytest, cv=10, scoring='precision')
        te.append(score.mean())
        
    plt.plot(range(1,10), te)
    
    image-20200821002438273

    从上图看出,集成后的得分超过了0.91比单个模型的正确率提升了很多。但还是挺菜的。

    最后简单总结下,自己能力有限,一些参数也是简单的定了下来,当然我相信你们分数都会比我高。

    展开全文
  • 决策树:泰坦尼克号生存预测决策树:
  • kaggle泰坦尼克号生存预测(附代码、数据集和答案) 之前总结的数据预处理方法:https://blog.csdn.net/qq_43012160/article/details/98462307 先看一下数据集: 这次需要分类的标签被存储在了训练集的Survived列里...
  • 基本的Kaggle ML预测比赛挑战-泰坦尼克号生存预测 0.74641 二进制时代-> 0.76076 二进制年龄+二进制票价-> 0.76794 边界年龄组+边界票价组-> 0.7703 边界票价组+矢量化Pcl,性别,SibSp,帕奇,上船-> 0.77990 ...
  • 里面包含训练集和测试集,总共1200多条数据,涉及年龄,性别,船仓等信息可用于数据挖掘
  • 33题实战“泰坦尼克号生存预测”全流程 点击以上链接???? 不用配置环境,直接在线运行 大家好,此次的教程基于泰坦尼克号生存预测的问题,带大家完整的走完一整套数据科学竞赛的流程。并且相关数据集中,我们特地搞...
  • 便参加了kaggle 上最为经典的泰坦尼克号生存预测项目,期间自己探索了一些,也拜读了一些大神的作品,感觉收获蛮大。为了不至于忘掉,在此做个总结,并希望与大家交流探讨。   1.项目基本信息 项目的背景...
  • Kaggle数学竞赛泰坦尼克号生存预测的代码。方便没有梯子的同学。
  • 泰坦尼克号生存预测(python)

    千次阅读 2018-08-31 17:33:00
    客舱代表着所处船上的位置,可能不同的客舱位置跑到救援船上的几率有一定的相关性 缺失的客舱可能是没有客舱,统一替换为X 有客舱的整体来说比没有客舱的获救几率更高些 # Cabin dataset[ " Cabin " ]=pd...
  • 7. 预测模型 首先将train分为训练集和测试集: # 将目标变量和特征分开 X_train = train.drop('Survived',axis=1) y_train = train['Survived'] # 将train分为训练集和测试集 # 用sklearn.model_selection 里的...
  • 5. 特征再分析 对处理过的数据再分析 train[['Survived','Pclass','Sex','Age_level','Fare_log','Embarked','Familysize','isAlone','Has_Cabin','Title']].groupby('Survived',as_...下一篇将着重于模型预测~
  • 经典又兼具备趣味性的案例泰坦尼克号问题源码。大家都熟悉的『Jack and Rose』的故事,豪华游艇倒了,大家都惊恐逃生,可是救生艇的数量有限,无法人人都有,副船长发话了『lady and kid first!』,所以是否获救...
  • --------- Survival Correlation by: Embarked Embarked Survived 0 C 0.553571 1 Q 0.389610 2 S 0.336957 ---------- 观察可以看到女性相比男性更容易生存,Pclass1生存率更高;有一个或两个亲戚更容易存活;Parch...
  • 因为主要分析生还率和其他属性的关系,所以不会涉及太多除了生存率以外的其他属性的复合分析 性别,船票等级和生还 g = sns . catplot ( x = "Pclass" , y = "Survived" , hue = "Sex" , data = train_data...
  • 案例-Kaggle泰坦尼克号生存预测分析

    千次阅读 2018-06-15 10:01:34
    由于它是预测生存值,所以,在测试数据集中没有。 #查看训练集信息 train.head() test.head() 为了方便对训练数据和测试数据进行清洗,将训练数据和测试数据进行合并 #通过设置ignore_index=True...
  • 其中泰坦尼克号生存预测作为最经典的启蒙数据分析项目,对于初学者来说是应该是最合适的了,后面将分享更多进阶的数据分析项目。如果已经有基础了,推荐: 1.开源项目《动手学数据分析》: ...
  • 前段时间学习了吴恩达的机器学习课程,然后蠢蠢欲动想要有所体验机器学习,于是上kaggle来体验了一下入门比赛-泰坦尼克号生存预测。 在kaggle上下载了项目训练集,就可以开始动手啦 本文仅仅是新手入门,hhh 1....
  • Kaggle泰坦尼克号生存预测挑战     这是kaggle上Getting Started 的Prediction Competition,也是比较入门和简单的新人赛,我的最好成绩好像有进入top8%,重新地回顾巩固一下这个比赛,我将分成...
  • 我们利用 sklearn 工具中的决策树分类器解决一个实际的问题:泰坦尼克号乘客的生存预测。 问题描述 泰坦尼克海难是著名的十大灾难之一,究竟多少人遇难,各方统计的结果不一。项目全部内容可以到我的github下载:...
  • """处理数据""" ##删除缺失值过多的列,和观察判断来说和预测的y没有关系的列 # inplace 是指将原有的数据进行合并。axis = 1 是指列00 data.drop(["Cabin","Name","Ticket","Cabin"],inplace=True,axis=1) data....
  • 泰坦尼克号生存预测 (Logistic and KNN)

    千次阅读 2018-08-14 16:41:46
    1912年4月15日,泰坦尼克号在处女航时与冰山相撞沉没,2224名乘客和船员中有1502人遇难。这一耸人听闻的悲剧震惊了国际社会,并导致更好的船舶安全法规。船难造成如此巨大的人员伤亡的原因之一是船上没有足够的救生...
  • 建立模型预测乘客是否生还。 2. 理解数据 数据特征含义:survival为目标变量,其他为特征。 Variable Definition Key survival Survival 0 = No, 1 = Yes pclass Ticket class 1 = 1st,...
  • 3.2 探索性可视化(Exploratory Visualization) 普遍认为泰坦尼克号中女人的存活率远高于男人,如下图所示: pd.crosstab(full.Sex,full.Survived).plot.bar(stacked=True,figsize=(8,5),color=['#4169E1','#FF00...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,508
精华内容 1,003
关键字:

泰坦尼克号生存预测