数据分析-项目实战:Kaggle泰坦尼克号(Titanic)沉船幸存者预测(易懂快速上手版)-二元分类-自读

本文介绍了Kaggle泰坦尼克号沉船幸存者预测项目,适合初学者了解机器学习流程。文章讨论了实际项目与竞赛项目的区别,并概述了机器学习的8个步骤,包括定义问题、数据处理、特征工程和模型选择等。通过该项目,作者分享了特征工程的重要性,如处理缺失值、转换数据以及如何选择合适的评估指标。此外,还提供了多个资源链接供读者进一步学习。
摘要由CSDN通过智能技术生成

#前言
Kaggle上的泰坦尼克项目,对于初学机器学习的朋友来说,是一个很好的练手机会,能大概了解整个机器学习的全过程。下面我把自己做这个项目的经验分享一下,希望对想了解机器学习的朋友有所帮助,里面结合很多前辈的智慧,大家可以参考最后的链接。
在文章最开头,我分享一下实际应用项目和竞赛项目的区别,实际应用中,训练的样本相对于实际的数据集总是少的,而它的评分标准,是以实际的数据集的准确度作为参考的,而在竞赛项目中,用于检验结果的测试集相对于训练集是偏少的,但是竞赛的评估结果,是以测试集的匹配度作为依据的,所以有可能会出现实际应用中比较好的模型,但是在竞赛项目中,因为测试集特有的偏差,而导致竞赛的结果并不好,这是很正常的现象。而泰坦尼克号这个项目,就存在这个问题,因为我们最后的标准是那个测试集,所以要达到最好的竞赛结果,需要去迎合那个测试集的分布特征。因为这点差异,所以竞赛项目中要想获得好名次,所要采取的战略是不一样的,泰坦尼克号适合你熟悉整个的机器学习流程,但是对于要想获得好的结果,就需要不断的去调整特征工程,模型和超参数,而且最关键的是要有一个参考点,类似于A/B测试,发现哪些特征适用于这个测试集,不能盲目的尝试。
一般的机器学习分为以下几个步骤:
1、定义问题
2、导入数据
3、理解分析数据
4、清洗转换数据
5、特征工程
6、模型选择及超参数调优
7、模型融合
8、获得问题的答案
在这几个步骤中,有一些操作是会反复出现的,比如说交叉验证,网格搜索,特征选择,管道(算法链),评估指标等等。我会在具体的步骤中解释。
对于一个具体的项目,如何去评估这个项目的优劣很重要,因为每一个项目都是基于真实场景的,我举一个简单的例子,比如说测试癌症的患病率,如果没有患癌症,却被误断出来癌症,对于病人的损失可能是多做几次治疗和所花的费用,这种情况的评估指标就是测准度(precision),也就是预测的结果中,实际存在不正确的例子。另外一种情况,如果一个人患癌了,但是却检测出来没患病,那对于患者的损失可能就是生命了,衡量这种情况的指标,就是测全度(recall)。回到泰坦尼克号的例子,我们判别的指标其实相对比较简单,就是判断预测出来的存活情况是否正确,不存在说,实际是存活了,我们却预测他遇难了,会带来什么实质的影响,这个就叫做精度。当然,精度对于相对平衡(0:1在0.5~2之间)的二分类数据集还是很好的指标,但是对于不平衡的数据集,那么精度就不是很好的度量了,这个时候要用到f-分数。只是给大家开一个头,具体的信息,大家需要到相关统计学或者机器学习的书籍中查找。
对于泰坦尼克号这个项目,我们的指标选择精度就够了。
那么有哪些因素是影响最后的指标的呢,主要是以下四个方面:
1、特征工程的质量
2、样本的数量
3、模型的类型和结合方式
4、模型的超参数
其实就是上面8个步骤的5-7。
下面我就从上面讲的8个步骤,4个要点,来详细演示一下这个项目。
#1、定义问题
这个项目的目的,是预测测试集中人员是否生还,也就是肯定当作二元分类的预测问题,因为是相对平衡的数据集,可以用精度作为衡量指标,而且生还和遇难并没有实质的区别(在数据层面上),所以不考虑准确度和召回率。
简单点说,就是利用训练数据集,训练模型,然后用测试数据集预测模型的精度。
#2、导入数据
该项目的数据源可以在这个链接下载,点这里下载项目数据

##导入需要用到的模块(我写这篇分享,是基于一个脚本写的,所以会把模块一次性全部导入,这样的好处是,所有的过程复现程度很快,实际挖掘过程中,刚开始是探索型的,很多子模块是根据需求加进去的)
#基础模块
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import warnings
warnings.filterwarnings('ignore')


#模型预处理
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import LabelEncoder

from sklearn.pipeline import Pipeline

from sklearn.feature_selection import RFECV

from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV


#回归模型模块
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor


#分类模型模块
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import LogisticRegressionCV
from sklearn.linear_model import Perceptron
from sklearn.linear_model import SGDClassifier
from sklearn.linear_model import PassiveAggressiveClassifier

from sklearn.neighbors import KNeighborsClassifier

from sklearn.svm import SVC, LinearSVC

from sklearn.gaussian_process import GaussianProcessClassifier

from sklearn.naive_bayes import GaussianNB
from sklearn.naive_bayes import BernoulliNB

from sklearn.tree import DecisionTreeClassifier

from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import RandomForestClassifier


##导入数据
train_raw=pd.read_csv('train.csv')
test_raw=pd.read_csv('test.csv')
#创建新的整体列表
alldata=pd.concat([train_raw,test_raw],ignore_index=True)

#3、理解分析数据
理解分析数据包括两个方面:
1、检查数据是否有缺失,异常,大体的描述统计情况
2、理解数据在实际场景中的含义

##info()和describe()两个方法是对数据大体了解的不错选择,还可以用head(),tail(),或者loc,都是不错的方式

train_raw.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.6+ KB

test_raw.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 418 entries, 0 to 417
Data columns (total 11 columns):
PassengerId    418 non-null int64
Pclass         418 non-null int64
Name           418 non-null object
Sex            418 non-null object
Age            332 non-null float64
SibSp          418 non-null int64
Parch          418 non-null int64
Ticket         418 non-null object
Fare           417 non-null float64
Cabin          91 non-null object
Embarked       418 non-null object
dtypes: float64(2), int64(4), object(5)
memory usage: 36.0+ KB

##还可以用isnull直接得到所有的缺失值,这种方式比较容易发现缺失值,方式其实很多啦,大家可以多试试。

train_raw.isnull().sum(0)
Out[23]: 
PassengerId      0
Survived         0
Pclass           0
Name             0
Sex              0
Age            177
SibSp            0
Parch            0
Ticket           0
Fare             0
Cabin          687
Embarked         2
dtype: int64

test_raw.isnull().sum(0)
Out[24]: 
PassengerId      0
Pclass           0
Name             0
Sex              0
Age             86
SibSp            0
Parch            0
Ticket           0
Fare             1
Cabin          327
Embarked         0
dtype: int64

接下来我们来讲讲,各数据的真实场景含义。
PassengerId:客户的编号,可以当作SQL中的键值,没有实际的含义;
Pclass:船舱的等级,一般和票价是成正比的,但是我发现不少船票价格是0英镑的乘客,可能还有一些其他的因素;
Name:乘客的姓名,最基本的就是姓名加一个称呼;
Sex:性别;
Age:乘客的年龄;
SibSp:乘客的非直系亲戚数量;
Parch:乘客的直系亲戚数量(父母和孩子);
Ticket:船票号码,有连号的说明是一起购买的;
Fare:船票的价格;
Cabin:具体的船舱位置;
Embarked:登陆的港口位置。
我们先对这些数据有一个感性的认识,具体的影响,还要在数据的图像化中发现。

#4、清洗转换数据
##4.1、清洗数据
数据清洗的第一步,先是处理缺失值,因为很多模型在缺失值存在的情况下,是无法运算的,而缺失值处理,一般先从缺的最少的开始,因为其他的缺失字段,比如年龄,我们可以考虑用回归的方式预测,比简单的分组平均要更准确。

##清洗转换数据
#Embarked:用众数处理空缺值
alldata.Embarked.fillna(alldata.Embarked.mode()[0],inplace=True)

#Ticket和Fare:计算重票的人数,仔细点会发现,原数据中的票价,其实是和自己同票的人的总票价,所以需要重新整理一下。
alldata['NTickets']=alldata.groupby('Ticket')['Ticket'].transform('count')
alldata['Fare_S']=alldata.Fare/alldata.NTickets
#用平均值填补空缺
alldata.Fare_S.fillna(alldata.Fare_S.mean(),inplace=True)
#Fare_S:根据每个价位段,合理的分配各价位,我选择的分配方式如下:
alldata['Fare_0']=np.where(alldata.Fare_S==0,1,0)
alldata['Fare_0_10']=np.where(((alldata.Fare_S>0)&(alldata.Fare_S<=10)),1,0)
alldata['Fare_10_15']=np.where(((alldata.Fare_S>10)&(alldata.Fare_S<=15)),1,0)
alldata['Fare_15_45']=np.where(((alldata.Fare_S>15)&(alldata.Fare_S<=45)),1,0)
alldata['Fare_45']=np.where(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值