泰坦尼克号1912年4月从英国南安普顿出发,途径法国,爱尔兰在美国大西洋碰触冰山沉没,一部分人幸免于难,一部分人没有生存,这个案例中就是要经过机器学习的算法来预测一下test.csv中418人的生存情况。案例详细内容能够访问网站:https://www.kaggle.com/c/titanic。经过这个案例你能够大体掌握一个机器学习的基本步骤,本文最后附上案例的源码。算法
首先咱们从kaggle上下载了泰坦尼克号案例的train.csv和test.csv两个数据,这里我为你们已经下好,你们能够在百度网盘里下载,地址:连接:https://pan.baidu.com/s/1RV-U... 密码:zlkj。app
首先导入数据,能够看到训练数据集train.csv中有891行,12列数据,而测试数据集中有418行,11列数据;缺乏的这一列数据正是咱们要预测的生存情况数据。机器学习
import numpy as np import pandas as pd #导入训练集 train = pd.read_csv('train.csv') #导入测试集 test = pd.read_csv('test.csv') #查看测试数据集合训练数据集的形状 # print("训练数据集:",train.shape) # print("测试数据集:",test.shape) full = train.append(test,ignore_index=True) # print("合并后的数据集:",full.shape) # print(full.head(10))
经过实验结果咱们能够知道,每一名乘客都对应着一个12维数据,其含义是:函数
1.Age:乘客年龄 2.Cabin:乘客船舱座位号 3.Embarked:乘客登船的港口,有三个可选值:S:南安普顿,C:法国瑟堡 Q:爱尔兰昆士敦 4.Fare:船票费用 5.Name:乘客姓名 6.parch:乘客的父母与子女数量 7.PassengerId:乘客ID 8.Pclass:乘客所在的船舱等级,1;一等,2;二等;3:三等 9.sex:乘客性别 10.SibSp:乘客的兄弟姐妹以及配偶数量 11.Survived:乘客是否存活标志;1:活着的 0:死亡 12.Ticket:票的编号
总数据有1309行,Age、Cabin、Embarked、Fare这四列数据中有缺失的状况,接下来的第三步就是要清洗数据,填补缺失值。学习
首先处理一下缺失的数据,若是缺失的数据是数字类型的,能够用平均数代替,若是是字符串类型的,能够用出现最多的数(众数)来替代。测试
# 填充年龄缺失值 full.Age = full.Age.fillna(full.Age.mean()) # 填充船票价格缺失值 full.Fare = full.Fare.fillna(full.Fare.mean()) # #填充登船的港口,由于最多的为s,故将全部的缺失值填充为S full.Embarked = full.Embarked.fillna('S') # 因为船票号这一栏缺失值过多,故将其填充为U full.Cabin = full.Cabin.fillna('U')
在作好这一步以后,数据还须要对一些列的字符串数据类型进行编码,好比Sex性别的分类数据,须要进行one-hot编码,方便机器学习识别。这里须要对性别、港口和姓名、船舱等级这些分类数据,进行从新编码。应用map函数能够对一列数据作同一个操做:网站
sexDict = {'male':1,'female':0} sex = full.Sex.map(sexDict) print(sex.head())
登船的港口有三个,分别是英国南安普顿、法国瑟堡、爱尔兰昆士敦,分别用首字母S、C、Q表示。编码
embarked = pd.DataFrame() embarked = pd.get_dummies(full.Embarked,prefix="Embarked") print(embarked.head()) #对船舱等级采起一样的方法 pclass = pd.DataFrame() pclass = pd.get_dummies(full.Pclass,prefix="Pclass") print(pclass.head())
接下来咱们看一下名字这一列的数据字符串格式:名,头衔,姓,咱们须要从名字里面获取头衔来断定是否对生存状况的影响。经过定义一个函数:
第一步获取name1剔除名字中逗号前面的名,
第二步剔除名字中冒号后面的姓,
第三步用strip函数剔除字符串头尾指定的字符(默认为空格)而后返回中间的头衔。
第四步应用函数,用一个表格型数据Df存放提取后的头衔,
第五步讲姓名中的头衔字符串与定义头衔类别的映射关系,再把头衔进行one-hot编码,code
def title1(name): name1 = name.split(',')[1] name2 = name1.split('.')[0] #使用strip函数提出姓名列的头尾,得到头衔 name3 = name2.strip() return name3 titleDf = pd.DataFrame() titleDf['Title'] = full.Name.map(title1) titleDict = { 'Capt':'officer', 'Col':'officer', 'Major':'officer', 'Dr':'officer', 'Rev':'officer', 'Jonkheer':'Royalty', 'Don':'Royalty', 'Sir':'Royalty', 'the Countess':'Royalty', 'Dona':'Royalty', 'Lady':'Royalty', 'Mlle':'Miss', 'Miss':'Miss', 'Mr':'Mr', 'Mme':'Mrs', 'Ms':'Mrs', 'Mrs':'Mrs', 'Master':'Master' } titleDf['Title'] = titleDf['Title'].map(titleDict) titleDf = pd.get_dummies(titleDf['Title']) print(titleDf.head())
接着从座位号提取坐席类别,用seat存放客舱号的信息坐席类别就是座位号的首字母,好比C85,类别映射为首字母C,用U表明不知道的数据。使用lambda匿名函数提取Cabin中的首字母:ip
seat = pd.DataFrame() seat['seat'] = full['Cabin'] seat.seat = seat.seat.map(lambda a:a[0]) #使用one-hot编码 seat = pd.get_dummies(seat.seat,prefix="Cabin") #print(seat.head())
对船上每个乘客的家庭成员数量进行一个统计。分别将原始数据中的SibSp列和Parch中的数据相加,再加上被统计者自身。
#对船上每个乘客的家庭成员数量进行一个统计 family = pd.DataFrame() family['family'] = full.SibSp + full.Parch + 1 #print(family.head())
最后就是将原始数据复制一份,删除咱们刚刚对其中从新编码的列(Cabin、Name、Sex、Pclass、Embarked、Parch、SibSp;还有票的编号Ticket这一列没有关系的数据。
最后合并的列包括了刚刚处理产生的新列名好比:da、family、seat、titleDf、pclass、embarked、sex。咱们发现新的数据da有1309行,27列。
删除咱们刚刚对其中从新编码的列(Cabin、Name、Sex、Pclass、Embarked、Parch、SibSp; 还有票的编号Ticket这一列没有关系的数据.最后合并的列包括了刚刚处理产生的新列名好比:da、family、seat、titleDf、pclass、embarked、sex.咱们发现新的数据da有1309行,27列
da = train.append(test,ignore_index=True) #采起一样的方式填充缺失值 da.Age = da.Age.fillna(da.Age.mean()) da.Fare = da.Fare.fillna(da.Fare.mean()) da.Embarked = da.Embarked.fillna('S') da.Cabin = da.Cabin.fillna('U') #提出不须要的列 da = da.drop(['Name','Pclass','Cabin','Parch','Embarked','SibSp','Ticket','Sex'],axis=1) #合并修改后的列 da = pd.concat([titleDf,seat,family,pclass,embarked,da,sex],axis=1) #print(da.shape) #print(da.head())
#使用数据框corr获取相关系数矩阵,将相关系数提取出来,按照升序和降序排列 corrDf = da.corr() #print(corrDf['Survived'].sort_values(ascending=False)) #print(corrDf['Survived'].sort_values(ascending=True))
咱们发现相关系数大于0的列中:头衔、客舱等级、船票价格、船舱号都与生存情况呈现正线性关系在相关系数小于0的列中:头衔、性别、客舱等级、客舱号与生存状况呈现负线性相关。这些特征其实与咱们在数据清洗过程当中处理的列很是相关,这里咱们直接采用上一步最后造成的新数据da
#将原始数据集拆分为训练集合评估集 sourceRow = 891 source_X = da.loc[0:sourceRow-1,:] source_X = source_X.drop(['Survived'],axis =1) source_y =da.loc[0:sourceRow-1,'Survived'] #拆分训练集和测试集 train_X,test_X,train_y,test_y = train_test_split(source_X,source_y,train_size=0.8) #输出数据集大小 # print('原始数据集特征:',source_X.shape) # print('训练集特征:',train_X.shape) # print('测试集特征:',test_X.shape) # print('原始数据集标签:',source_y.shape) # print('训练数据集标签:',train_y.shape) # print('测试数据集标签:',test_y.shape)
导入训练数据的特征train_X712条,包括性别,头衔等,导入标签train_y712条生存情况,获得正确率0.87:
#使用逻辑回归模型 model = LogisticRegression() #使用数据,训练模型 model.fit(train_X,train_y) # print(model.fit(train_X,train_y)) # print(model.score(test_X,test_y))
用机器学习模型,对预测数据集中的生存状况进行预测,这里用乘客的ID,数据框Df保存预测状况的值。
#方案实施,对预测数据集中的数据进行预测 predict_X = da.loc[sourceRow:,:] predict_X = da.drop(['Survived'],axis=1) pred_Y = model.predict(predict_X) pred_Y = pred_Y.astype(int) #乘客ID passenger_id = da.loc[sourceRow,'PassengerId'] predDf = pd.DataFrame({'PassengerId':passenger_id,'Survived':pred_Y}) print(predDf.shape) print(predDf)
最后附上源码:连接:https://pan.baidu.com/s/1cb60... 密码:y12u。有兴趣的能够在阅读本文点赞,欢迎评论哦!