Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)

1、引言

这是第一次写博客,作为一个刚刚上路的小白,要学的东西很多。本来很多笔记都是以文本的形式储存在本地的,但是很想尝试写一次博客。大学快一年了,学的东西不多,但也不少。不多是在整个专业知识来说的,看了许多大牛的经历,深深感觉到自己要走的路还长,而相对于大学目前要求的基本专业内容,也算是学了不少的东西。
这个是应实验室学长的要求完成的一个自学作业。说实话,一开始看这个kaggle题目,完全不知道它讲的是什么东西,然后通过查阅了许多资料,最后在寒小阳的《机器学习系列(3)_逻辑回归应用之Kaggle泰坦尼克之灾》这篇文章帮助下完成了这道题目的第一步。又受到简书上王树义老师的文章影响,最终决定尝试写一篇博客笔记,内容则是选择了我刚刚完成的kaggle的初体验题目:泰坦尼克之灾。
这篇博客主要是一个笔记,记录了泰坦尼克之灾的代码实现方法,实际上这个笔记还不能算完整,最后模型的优化还没有完成,但内心想完成这篇笔记的念头很重了。所以在完成了大纲的内容,和主要知识点的整理后,我便开始了这个笔记的填写。
这篇笔记中的代码实现框架采用是寒小阳先生的文章,如果有同学是和我一样刚刚接触机器学习的数据分析,作为学习的话,我建议是看寒小阳先生的文章。那篇文章要更加有趣,语言还是很幽默的。本文的内容主要是对寒小阳先生代码的重新实现,主要是有一些函数的使用方法不相同。因为这个是笔记类型的,所以有些地方或许没有很详细的表达。好了,那就不扯废话了。

2、kaggle泰坦尼克之灾的介绍

这是一道数据分析的入门题,很适合新手初步了解数据分析是什么东西,怎么实现的。不过数据分析不只是做到这个,它还有对文本情感的分析,图像数字识别等等,具有不同的方向,所以我还有好长的路要走。
kaggle链接
本题处理的数据集是泰坦尼克号上的乘客的基本信息,然后凭借这些数据的信息来判断这些乘客最后有没有幸存下来。这里采用的处理算法是逻辑回归,但事实上还有其他的算法也可以完成处理。可以参考scikit-learn提供的一张导图来选择合适的算法。Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
关于逻辑回归,寒小阳先生有很详细的介绍,可以在下面的链接看到,我也重新附上了他实现这道题的链接:
《机器学习系列(1)_逻辑回归初步》,作者:寒小阳
《机器学习系列(2)_从初等数学视角解读逻辑回归》,作者:寒小阳
《机器学习系列(3)_逻辑回归应用之Kaggle泰坦尼克之灾》,作者:寒小阳

3、笔记

用到的函数

pandas包:
DataFrame(简写df)
pd.read_csv()
pd.get_dumines(data, prefix)
pd.concat(data, axis)
df.notnull()
df.isnull()
df.as_matrix()
df.loc()
df.drop(data, axis, inplace)
df.filter(regex)
df.index
df.sort_index()
df.sort_values()

matplotlib包
pyptlot包
这部分的函数见matplot的笔记(当然说我自己的笔记啦)
其中pandas提供了plt接口直接依据df数据绘制图像。
这个接口在某些情况下好像并不理想,比如bar图像的坐标的ticks横向,更改值容易造成数据错误。

numpy包:
np.astype()
np.int32()

sklearn包:
ensemble模块中的RandForestRegressor算法(简写rfr)
rfr.fit()
rfr.predict()
preprocessing模块中的StandardScaler()函数(简写scalar)
scalar.fit()
scalar.fit().transform()
linear_model模块中的LogisticRegression算法(简写clf)
clf.fit()
clf.predict()
把这些函数列出来的原因是收到我开头提到的那位王老师影响,王老师在一篇关于文本情感分析机器学习文章中是先让我们去了解需要用到的函数怎么用后再去尝试敲代码,我认为这样挺好,所以把所有用到的函数都列出来了,除了matplotlib包的,主要是有点多,便懒得整理了。
附上pandas和scikit-learn的官方手册:
pandas:http://pandas.pydata.org/pandas-docs/stable/reference/index.html
scikit-learn:https://scikit-learn.org/stable/glossary.html

第一步:了解数据

我认为处理数据前的第一步是了解数据,通过各种合理方便的手段了解数据的基本情况。如用excel查看csv文件中的数据,并依据kaggle里面的提示,我们会接触到以下数据:
Passengerld, Survived, Pclass, Name, Sex, Age, SibSp, Parch, Ticket, Fare, Cabin, Embarked。
整理到表格是这样的:

数据 训练集train.csv 测试集test.csv
Passengerld 乘客ID 作为唯一标识,总共有891个 作为唯一标识,总共有418个
Survived 幸存情况 0表示遇难,1表示幸存;无缺失值 最后预测对象,无本项数据
Pclass 乘客等级/船舱等级 1头等舱,2二等舱,3三等舱;无缺失值 1头等舱,2二等舱,3三等舱;无缺失值
Name 名字 无缺失值 Name 名字
Sex 性别 无缺失值 无缺失值
Age 年龄 共714个,有缺失值 共332个,有缺失值
SibSp 船上的兄妹/配偶数 无缺失值 无缺失值
Parch 船上的子女/父母数 无缺失值 无缺失值
Ticket 船票的编号 无缺失值 无缺失值
Fare 船票的费用 无缺失值 共417个,有缺失值
Cabin 船舱编号 共204个,有缺失值 共91个,有缺失值
Embarked 登船口 S、C、Q三个港口;共879,有缺失值 无缺失值

第二步:分析数据之间的关系

这里主要需要数据可视化的内容,这一步在单独的py文件中实现。
首先是将数据导入,然后建立一个专门的文件夹DF来存放可视化的图片和文件。

#引入pandas包
import pandas as pd
#导入数据
data_train = pd.read_csv(r"C:Users\87515\Desktop\train.csv")
data_train.describe().to_csv(r'DF\describe.csv')

有几点必须要说明一下,这块数据关系的分析我是将基本上有关系的属性都进行了一些分析,或许会有一些不严谨的地方和多余的分析,但主要是作为一篇笔记。如果不想看的可以跳过。
目前我的感悟是,这些图像分析是到用到的时候才会去写它们的代码,比如说补全Age的时候,我们需要判断哪些属性可以被用来作为特征。还有就是任何合理便捷的手段来认识这些数据应该都是可行的,只不过作为初学者,应该是通过matplotlb来认识数据,帮助我们了解数据分析。所以,不一定要和我一样去把这些数据全部分析个完,也不需要提前分析好所有数据。其实有些代码是我后来补上的,很多应该是在系统优化阶段准备的,只是我把它放在了这里罢了。
同时声明一下,其中个别代码是按照寒小阳先生的代码来写的。
1、通过describe来查看数据的一些基本信息。
Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
生存率大概在38%,平均年龄在30,船票价格平均在32左右。
2、可视化分析
引入包,添加中文支持,我用的spyder需要添加这个中文支持

#可视化分析
import matplotlib.pyplot as plt

#中文支持
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

fig = plt.figure(figsize = (12,6))#这里针对不同的图片需要调整参数
fig.set(alpha = 0)
fig.set(dpi = 72)

数据分析主要目的是两个:

  • 分析有缺失值的属性和其他属性的关系,填补缺失值
  • 分析Survived和其他属性的关系

2.1、生存情况

#生存情况
data_train.Survived.value_counts().plot(kind = 'bar', width = .2)
plt.title('生存情况')
S = data_train.Survived.value_counts()
for index, y in enumerate(np.array(data_train.Survived.value_counts())):
    plt.text(index, y+20, '%d' % y, ha='center', va= 'top', size = 14)
plt.xticks(rotation = 0, size = 14)
plt.savefig('DF\生存情况')
#show要在savefig的后面
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
生存情况的统计,三分之一左右的人幸存。
2.2、乘客等级分布

S = data_train.Pclass
S.value_counts().plot(kind = 'bar', width = .2)
plt.title('乘客等级分布')
for index, y in enumerate(np.array(S.value_counts())):
   plt.text(index, y+20, '%d' % y, ha='center', va= 'top', size = 14)
plt.xticks(rotation = 0, size = 14)
plt.savefig('DF\乘客等级分布')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
大部分是三等舱,头等舱和二等舱相差不大。
2.3、乘客性别统计

#乘客性别
S = data_train.Sex
S.value_counts().plot(kind = 'bar', width = .2)
plt.title('乘客性别')
for index, y in enumerate(np.array(S.value_counts())):
   plt.text(index, y+20, '%d' % y, ha='center', va= 'top', size = 14)
plt.xticks(rotation = 0, size = 14)
#plt.savefig('DF\乘客性别')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
男性的人数是女性的人数2倍左右,结合电影剧情分析,女的应该比男的更容易幸存。
2.4、女&男和生存的关系

#Female&male与Survived关系
S1 = data_train.Sex
S2 = data_train.Survived

plt.subplot(1,2,1)
S1.value_counts().plot(kind='bar', color = 'g', width=.2, label='0')
plt.xticks(rotation = 0, size = 14)
plt.bar(range(0,2), S1[S2 == 1].value_counts(),color = 'b', width=.2,label='1')
plt.legend()
plt.title(r'Female&Male的Survived情况', size = 14)

plt.subplot(1,2,2)
S2.value_counts().plot(kind='bar', width=.2, color = 'g', label='Female')
plt.xticks(rotation = 0, size = 14)
plt.bar(range(0,2), S2[S1 == 'male'].value_counts(), color = 'b', width=.2, label='Male')
plt.legend()
plt.title('Survived的Female&Male情况')
plt.savefig(r'DF\Female&male与Survived关系')

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
女性比男性更容易幸存,幸存人数里面女性是男性的两倍多,所以性别Sex是一个主要特征。
2.5、年龄与生存的关系

#年龄与生存的关系
S1=data_train.Age
S2=data_train.Surviveds
s1=S1.value_counts().sort_index()
s2=S1[S2 == 0].value_counts().sort_index()
plt.bar(s1.index, s1, width = .6, label='获救')
plt.bar(s2.index, s2, width = .6, label='未获救')
plt.legend()
plt.xticks(rotation = 0, size = 14)
plt.xticks(range(0,85,5))
plt.xlim(-1,81)
plt.ylim(0,31)
plt.title('年龄与生存的关系', size=14)
plt.xlabel('年龄', size=14)
plt.ylabel('')
plt.savefig('DF\年龄与生存的关系')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
儿童的更容易幸存,年龄18~60的情况一般情况下有一半偏少的人幸存,超过60的,幸存率较低,所以年龄也是一个主要特征。
2.6、各乘客等级的获救情况

S1=data_train.Pclass
S2=data_train.Survived
df=pd.DataFrame({u'获救':S1[S2 == 1].value_counts(), u'未获救':S1[S2 == 0].value_counts()})
df.plot(kind='bar', stacked=True)
plt.xticks(rotation=0)
plt.title(u"各乘客等级的获救情况")
plt.xlabel(u"乘客等级") 
plt.ylabel(u"人数") 
plt.savefig(r'DF\各乘客等级的获救情况')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
从幸存率上来看,头等舱和二等舱的乘客更容易幸存,所以应该是主要特征
2.7、各登录港口乘客的获救情况

#各登录港口乘客的获救情况
Survived_0 = data_train.Embarked[data_train.Survived == 0].value_counts()
Survived_1 = data_train.Embarked[data_train.Survived == 1].value_counts()
df=pd.DataFrame({u'获救':Survived_1, u'未获救':Survived_0})
df.plot(kind='bar', stacked=True)
plt.xticks(rotation=0)
plt.title(u"各登录港口乘客的获救情况")
plt.xlabel(u"登录港口") 
plt.ylabel(u"人数") 
plt.savefig(r"DF\各登录港口乘客的获救情况")
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
S港人数最多,Q港人数最少,但生存率都在三分之一左右,C港的生存率过半,等下看看是什么影响的,性别还是船舱等级
2.8、根据舱等级和性别的获救情况

#根据舱等级和性别的获救情况
S1 = data_train.Sex
S2 = data_train.Pclass
S3 = data_train.Survived

plt.subplot(141)
plt.title(u"高级船舱女性的获救情况")
plt.bar([0,1], S3[S1=='female'][S2!=3].value_counts(), color='#FA2479', width=.5)
plt.xticks([0,1],[u'获救',u'未获救'])
plt.xlim([-.5,1.5])
plt.yticks(range(0,350,100))
plt.legend([u"女性/高级舱"], loc='best')

plt.subplot(142)
plt.title(u"低级船舱女性的获救情况")
plt.bar([0,1], S3[S1=='female'][S2==3].value_counts(), color='pink', width=.5)
plt.xticks([0,1],[u'获救',u'未获救'])
plt.xlim([-.5,1.5])
plt.yticks(range(0,350,100))
plt.legend([u"女性/低级舱"], loc='best')

plt.subplot(143)
plt.title(u"高级船舱男性的获救情况")
plt.bar([0,1], S3[S1=='male'][S2!=3].value_counts(), color='lightblue', width=.5)
plt.xticks([0,1],[u'获救',u'未获救'])
plt.xlim([-.5,1.5])
plt.yticks(range(0,350,100))
plt.legend([u"男性/高级舱"], loc='best')

plt.subplot(144)
plt.title(u"低级船舱男性的获救情况")
plt.bar([0,1], S3[S1=='male'][S2==3].value_counts(), color='steelblue', width=.5)
plt.xticks([0,1],[u'获救',u'未获救'])
plt.xlim([-.5,1.5])
plt.yticks(range(0,350,100))
plt.legend([u"男性/低级舱"], loc='best')

plt.savefig(r'DF\根据舱等级和性别的获救情况')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
不同等级船舱男女性的生存情况, 可以看出高级船舱对生存率的影响要比性别的略高。
2.9、不同等级船舱的年龄分布

#不同等级船舱的年龄分布
S1=data_train.Age
S2=data_train.Pclass
S1[S2==1].plot(kind='kde', label='头等舱')
S1[S2==2].plot(kind='kde', label='二等舱')
S1[S2==3].plot(kind='kde', label='三等舱')
plt.xlabel('年龄',size=14)
plt.ylabel('')
plt.legend()
plt.title('不同等级船舱的年龄分布', size=14)
plt.savefig('DF\不同等级船舱的年龄分布')
print('头等舱平均年龄:',S1[S2==1].mean())
print('二等舱平均年龄:',S1[S2==2].mean())
print('三等舱平均年龄:',S1[S2==3].mean())

头等舱平均年龄: 38.233440860215055
二等舱平均年龄: 29.87763005780347
三等舱平均年龄: 25.14061971830986

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
不同船舱的年龄分布差不多,所以船舱等级高的更容易幸存不是年龄造成的。
但明显的是平均年龄依次递减,头等舱平均年龄最高,这应该是影响年龄的一个特征。
2.10、不同港口的船舱等级、性别情况

#10、不同港口的船舱等级、性别情况
S=data_train.Embarked
S1=data_train.Pclass
S2=data_train.Sex
plt.subplot(131)
plt.title(u'S港口')
plt.bar([0.5,0.6,0.7],S1[S=='S'].value_counts().sort_index(),width=0.1,color=['pink','lightgreen','lightblue'])
plt.bar([1.5,1.6],S2[S=='S'].value_counts().sort_index(),width=0.1,color=['steelblue','#FA2479'])
plt.xlim([0,2])
plt.xticks([0.6,1.55],[u'船舱等级(1、2、3)',u'性别(女/男)'])
plt.yticks(range(0,500,100))
plt.ylabel(u'人数')

plt.subplot(132)
plt.title(u'C港口')
plt.bar([0.5,0.6,0.7],S1[S=='C'].value_counts().sort_index(),width=0.1,color=['pink','lightgreen','lightblue'])
plt.bar([1.5,1.6],S2[S=='C'].value_counts().sort_index(),width=0.1,color=['steelblue','#FA2479'])
plt.xlim([0,2])
plt.xticks([0.6,1.55],[u'船舱等级(1、2、3)',u'性别(女/男)'])
plt.yticks(range(0,500,100))
plt.ylabel(u'人数')

plt.subplot(133)
plt.title(u'Q港口')
plt.bar([0.5,0.6,0.7],S1[S=='Q'].value_counts().sort_index(),width=0.1,color=['pink','lightgreen','lightblue'])
plt.bar([1.5,1.6],S2[S=='Q'].value_counts().sort_index(),width=0.1,color=['steelblue','#FA2479'])
plt.xlim([0,2])
plt.xticks([0.6,1.55],[u'船舱等级(1、2、3)',u'性别(女/男)'])
plt.yticks(range(0,500,100))
plt.ylabel(u'人数')
plt.savefig(r'DF\不同港口的船舱等级、性别情况')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
首先可以看出的是性别和港口无关,但是船舱等级好像没有太大规律可言,Q港口基本上是三等舱的,C港口二等舱较少。
2.11、不同港口的年龄分布

#不同等级船舱的年龄分布
S1=data_train.Age
S2=data_train.Embarked
S1[S2=='S'].plot(kind='kde', label='S')
S1[S2=='C'].plot(kind='kde', label='C')
S1[S2=='Q'].plot(kind='kde', label='Q')
plt.xlabel('年龄',size=14)
plt.ylabel('')
plt.legend()
plt.title('不同等级船舱的年龄分布', size=14)
plt.savefig('DF\不同港口的年龄分布')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
不同港口的年龄也分布差不多,所以综上港口不大适合作为一个主要特征,先作为一个备选特征
2.12、船票费用和生存的关系

#船票费用和生存的关系
=data_train.sort_values('Fare')
S1=S.Survived
S2=S.Fare
S1.loc[S1==0]=-1
print(S1)
print(S2)
plt.scatter(S2,S1)
plt.xlim([-5,513])
plt.yticks([-1,1])
ax=plt.gca()
ax.spines['bottom'].set_position(('data',0))
ax.spines['top'].set_color('none')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
好像没有太大关系,不是主要特征,作为备选特征
2.13、兄妹&配偶数和生存的关系

S=data_train
S1=S.Survived
S2=S.SibSp[S1==1].value_counts().sort_index()
S3=S.SibSp[S1==0].value_counts().sort_index()
#print(S2)
#print(S3)
plt.bar(S2.index,S2,width=.4)
plt.bar(S3.index,-S3,width=.4)
plt.xticks(range(0,9))
ax=plt.gca()
ax.spines['bottom'].set_position(('data',0))
ax.spines['top'].set_color('none')
plt.savefig(r'DF\兄妹&配偶数和生存的关系')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
兄妹&配偶数越多,生存的越少,猜测父母数/子女可能也是这样。
2.14、子女&父母数和生存的关系

S=data_train
S1=S.Survived
S2=S.Parch[S1==1].value_counts().sort_index()
S3=S.Parch[S1==0].value_counts().sort_index()
#print(S2)
#print(S3)
plt.bar(S2.index,S2,width=.4)
plt.bar(S3.index,-S3,width=.4)
plt.xticks(range(0,9))
ax=plt.gca()
ax.spines['bottom'].set_position(('data',0))
ax.spines['top'].set_color('none')
plt.savefig(r'DF\子女&父母数和生存的关系')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
确实是这样。
2.15、按Cabin有无看获救情况

Survived_cabin = data_train.Survived[pd.notnull(data_train.Cabin)].value_counts()
Survived_nocabin = data_train.Survived[pd.isnull(data_train.Cabin)].value_counts()
df=pd.DataFrame({u'有':Survived_cabin, u'无':Survived_nocabin}).transpose()
df.plot(kind='bar', stacked=True)
plt.title(u"按Cabin有无看获救情况")
plt.xticks(rotation=0)
plt.xlabel(u"Cabin有无") 
plt.ylabel(u"人数")
plt.savefig(r'DF\按Cabin有无看获救情况')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
缺失值有点多,按照图像的情况看无缺失值的更容易生存,所以预处理的时候按照是否有Cabin来处理吧。
2.16、年龄和船票费用的关系
按照常识年龄和船票价格肯定有所联系。

S=data_train.sort_values('Age')
S1=data_train.Age
S2=data_train.Fare
plt.scatter(S1,S2)
plt.xlabel(u'年龄')
plt.ylabel(u'费用')
plt.ylim(-1,550)
plt.savefig(u'DF\年龄和船票费用的关系')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
但事实上好像没有太大关系啊。
2.17、年龄和SibSp的关系

S=data_train.sort_values('Age')
S1=data_train.Age
S2=data_train.SibSp
plt.scatter(S1,S2)
plt.xlabel(u'年龄')
plt.ylabel(u'SibSp')
#plt.ylim(-1,550)
#plt.savefig(u'DF\年龄和SibSp的关系')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
两者还是有点关系的,可以作为年龄的特征。
2.18、年龄和Parch的关系

#年龄和Parch的关系
S=data_train.sort_values('Age')
S1=data_train.Age
S2=data_train.Parch
plt.scatter(S1,S2)
plt.xlabel(u'年龄')
plt.ylabel(u'Parch')
#plt.savefig(u'DF\年龄和Parch的关系')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
两者的关系不是很大,但可以作为年龄的备选特征
2.19、年龄和性别的关系

#年龄和性别的关系
S=data_train.sort_values('Age')
S1=S.Age
S2=S.Sex
S3=S1[S2=='female'].value_counts()
S4=S1[S2=='male'].value_counts()
plt.subplot(211)
plt.title('年龄和性别的关系')
plt.bar(S3.index, S3)
plt.xlabel('男')
plt.yticks(range(0,25,5))
plt.ylabel('人数')
plt.subplot(212)
plt.bar(S4.index, S4, color='orange')
plt.xlabel('女')
plt.yticks(range(0,25,5))
plt.ylabel('人数')
plt.savefig(u'DF\年龄和性别的关系')
plt.show()

Kaggle泰坦尼克之灾:逻辑回归模型实现笔记(一)
好像没有太大关系,作为年龄的备选特征。

接下来第三、四、五步都是数据的预处理过程

第三步:补全缺失值

在第二步中,
我们发现年龄Age主要和Pclass,Parch,SibSp有关,Fare、Sex可以作为备选特征。
而Cabin则按照有和无来区分。
下面是实现代码:
其中对于年龄采用随机森林分类回归来处理缺失值

from sklearn.ensemble import RandomForestRegressor

def set_missing_ages(df):
    
    # 把选定特征取出来丢进Random Forest Regressor中
    age_df = df[['Age','Fare', 'Parch', 'SibSp', 'Pclass']]
    
    # 乘客分成已知年龄和未知年龄两部分
    known_age = age_df[age_df.Age.notnull()].as_matrix()
   # print(known_age)
    unknown_age = age_df[age_df.Age.isnull()].as_matrix()
    
    # y即目标年龄
    y = known_age[:, 0]
   # print(y)
    
    # X即特征属性值
    X = known_age[:, 1:]
   # print(X)
    
    #random_state表示一个种子的值,n_estimators表示子树的值,n_jobs表示最大的处理器,-1表示不限制
    rfr = RandomForestRegressor(random_state=0, n_estimators=2000, n_jobs=-1)
    # fit到RandomForestRegressor之中
    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

#缺失值处理
data_train, rfr = set_missing_ages(data_train)
data_train = set_Cabin_type(data_train)

这一步是对训练集的缺失值的处理,测试集的处理则放到后面测试集的预处理中
用df.to_csv()函数可以查看完成缺失值处理的数据集

第四步:特征因子化

逻辑回归建模,需要输入的特征是数值型特征,所以需要对数据的特征因子化
特征因子化:以Cabin为例,原本一个属性维度,因为其取值可以是[‘yes’,‘no’],而将其平展开为’Cabin_yes’,'Cabin_no’两个属性。
原本Cabin取值为yes的,在此处的"Cabin_yes"下取值为1,在"Cabin_no"下取值为0;
原本Cabin取值为no的,在此处的"Cabin_yes"下取值为0,在"Cabin_no"下取值为1。
特征因子化通过pd的get_dumies()函数来完成:

dummies_Cabin = pd.get_dummies(data_train['Cabin'], prefix= 'Cabin')
dummies_Embarked = pd.get_dummies(data_train['Embarked'], prefix= 'Embarked')
dummies_Sex = pd.get_dummies(data_train['Sex'], prefix= 'Sex')
dummies_Pclass = pd.get_dummies(data_train['Pclass'], prefix= 'Pclass')

对于完成因子化的数据链接到原数据集上

#合成数据集
df = pd.concat([data_train, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1)
#删除指定数据集,axis为0(index) or 1(columns),inpalace表示是否对内部操作,如果True则不返回
df.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'], axis=1, inplace=True)

第五步:处理浮动较大的数值

逻辑回归建模中,浮动值极大的数字对收敛速度影响较大,所以要把Age和Fare进行scaling,也就是将他们特征化到[-1,1]之间。

#处理数据集中浮动较大的数值到(-1,1)之间
import sklearn.preprocessing as preprocessing
scaler = preprocessing.StandardScaler()
#fit的数据需要以2维([[]])的形式传入
age_scale_param = scaler.fit(df[['Age']])
#将fit的数据处理后的结果以np.array的形式返回
df['Age_scaled'] =age_scale_param.transform(df[['Age']])
fare_scale_param = scaler.fit(df[['Fare']])
df['Fare_scaled'] = fare_scale_param.transform(df[['Fare']])
df['Age']=df['Age_scaled']
df['Fare']=df['Fare_scaled']
#最后得到的df数据情况如下所示
#df.to_csv('look.csv')
#inddex(None) Passenger Age SibSp Parch Fare Cabin_No Cabin_Yes
#Embarked_C Embaked_Q Embarked_S Sex_female Sex_male
#Pclass_1 Pclass_2 Pclass_3 Age_scaled Fare_scaled

第六步:筛选数据

#筛选数据(结果+特征)
#利用正则表达式
train_df = df.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
#train_df.to_csv('look_filter.csv')
train_np = train_df.as_matrix()

第七步:数据建模

# y即Survival结果
y = train_np[:, 0]

# X即特征属性值
X = train_np[:, 1:]

from sklearn import linear_model
# fit到RandomForestRegressor之中
clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
clf.fit(X, y)

成功得到了clf这个模型,下面就是对测试集内容进行相同的预处理后就可以把特征数据填入获取结果了。

第八步:测试集预处理

#测试集预处理

data_test = pd.read_csv(r'C:\Users\87515\Desktop\test.csv')

#缺失值处理
data_test.loc[ (data_test.Fare.isnull()), 'Fare' ] = 0
tmp_df = data_test[['Age','Fare', 'Parch', 'SibSp', 'Pclass']]
null_age = tmp_df[data_test.Age.isnull()].as_matrix()
X = null_age[:, 1:]
predictedAges = rfr.predict(X)
data_test.loc[ (data_test.Age.isnull()), 'Age' ] = predictedAges

data_test = set_Cabin_type(data_test)

#向量化
dummies_Cabin = pd.get_dummies(data_test['Cabin'], prefix= 'Cabin')
dummies_Embarked = pd.get_dummies(data_test['Embarked'], prefix= 'Embarked')
dummies_Sex = pd.get_dummies(data_test['Sex'], prefix= 'Sex')
dummies_Pclass = pd.get_dummies(data_test['Pclass'], prefix= 'Pclass')

#合成新的数据集
df_test = pd.concat([data_test, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1)
df_test.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'], axis=1, inplace=True)

#处理浮动值大的数据
age_scale_param = scaler.fit(df_test[['Age']])
df_test['Age_scaled'] =age_scale_param.transform(df_test[['Age']])
fare_scale_param = scaler.fit(df_test[['Fare']])
df_test['Fare_scaled'] = fare_scale_param.transform(df_test[['Fare']])
df_test['Age']=df_test['Age_scaled']
df_test['Fare']=df_test['Fare_scaled']

#筛选数据(特征)
test = df_test.filter(regex='Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
test = test.as_matrix()

第九步:结果预测

#筛选数据(特征)
predictions = clf.predict(test)
result = pd.DataFrame({'PassengerId':data_test['PassengerId'].as_matrix(),
 'Survived':predictions.astype(np.int32)})
result.to_csv("first_test_reslut.csv", index=False)

上传到Kaggle得到的结果是0.766,以上就是一个模型建立的第一步,接下来是对模型的优化和调整以获取更好的模型。

4、总结

这篇笔记最后还是完成了,或许有一些没有校对的错误,不过我自己不再校对了,如果有同学或大佬指出来,我会去修正的。这也算是完成了一个小梦想吧。
王树义老师给自己的标签是终身学习者,我则是一个刚刚踏上学习的小白,未来我不知道可以走到哪一步,我希望我也可以一名合格的软件工程师。虽然到大学时候才真正意识到学习的可贵(以前说学习重要的时候怕都是在说屁话吧),所以终身学习者我怕是做不到的了,但是至少从现在开始。最后感谢寒小阳先生文章指引我进入了机器学习的第一步,以及王老师文章中散发着的强烈的学习精神。
还有博客笔记会不会写第二章,这个得看以后我自己情况了,这篇只是一个尝试罢了,现在更多的是学习,怕是没有太多时间去弄博客笔记吧,虽然很多零碎的知识是需要一个笔记,但是存在本地然后上传到云端就好啦。写博客还是太费神了,heyhey,就是懒啦。
最后这个笔记上的所有代码都上传在GitHub,网址如下
https://github.com/DimBottom/KaggleTitanic.git
first_test文件是数据模型的建立实现代码,而first_test2文件则是数据可视化部分的代码。