第一天简单回顾pandas基本的操作
https://blog.youkuaiyun.com/liufang0001/article/details/77856255?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160376195819724822529720%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=160376195819724822529720&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v28-1-77856255.pc_first_rank_v2_rank_v28&utm_term=pandas&spm=1018.2118.3001.4187
以上是pandas的库函数以及简单操作
pandas十道题练手:https://www.kesci.com/mw/project/59e77a636d213335f38daec2
2020 10-26-11-01 泰坦尼克之灾的复现
v1:首先查看了一些数据和生存率的关系,发现女生的生存率比男生高,所以直接把性别当成判定标准,得到了76%的准确率
v2:之后直接硬套随机森林,将性别,年龄,配偶以及孩子数量当成是随机森林的特征,NAN简单地用均值进行填充,也是76%的精度,认为如果要在小样本数据上做文章,特征的选取与处理应该是最重要的
v3:
首先对每列数据和生存率的关系进行数据分析和可视化
Sex:
首先看数量和比例关系,貌似lady first 随意预处理的话就不预处理了
并且没有空数据
Pclass:几号舱,分等级的
也是没有出现空值
统计一下数量和比例:
数量上面一等舱最少,毕竟富人比较多,这儿可能看不出来什么问题,但是
比例来看,确实越富越有可能获救,原因未知,大概有钱能使鬼推磨吧,这个数据也得用
Name :
名字 我想把他们的称谓以及名字长度和生存的概率进行统计,首先来看看有无数据缺失,没有
那么进行称谓(MR MRS这些的统计)
首先挑出这些称谓发现:
Master活的概率是0.6 master可能学历越高越自私的,存活率也高(hhh有博客里面说这个是小男孩的意思????虽然孩子存活率高,确实也符合逻辑,但是??????master?孩子?英语太差,抱歉TT,我以为是大师)
MISS活的概率是0.7
MR活的概率是0.18
MRS活的概率是0.78 建议所有女生原地结婚提高生存率(狗头保命
特征处理:还有些没有称谓的,但是个体数非常少,这些怎么处理呢,我想用one of key 试一试 4类人用四个one of key 其他的人就直接变成00001
Age:
Age数据是有缺失的,通过均值或者众数其他方法肯定可以补充它,现在讨论如何补充Age ,先不急,把其他没有缺失的数据先进行分析。并且可以先分析有age的数据
这儿的特征还是有些不太明显,除了0-10岁孩子的成活率比较高,70岁以上的成活率都非常低,其他的 上下上下上下,啥也不是,这个age决定保留,但是我希望它同其他特征一同构建出一个明显的新特征,首先查看一下每个货舱的年龄分布
三号货舱的人最多,但是,头等舱的平均年龄又是最大的
每个货舱下面的求生年龄概率图:
一号货舱平均年龄最高,但是生存的几率年轻人还是要高一些,相对来说除了老年朋友存活率低,都比较平均。
二号仓的平均年龄是35,但是小孩和4-50岁年龄段的人存活率会高,10-20岁,维持50%的存活率。
三号仓特征就比较明显,40-70的存活率都非常低,10-40的存活率逐步下降,0-10岁的存活率还是最高
由于我们是通过随机森林进行训练的,概率模型(树形模型)不需要归一化,因为它们不关心变量的值,而是关心变量的分布和变量之间的条件概率,如决策树、RF。而像Adaboost、SVM、LR、Knn、KMeans之类的最优化问题就需要归一化所以我们这儿通过三个阈值:0.6 0.4 0.3
将Pclass+Age构成一个新的特征值:PA
同时,Age 的填充方式的话,直接通过Pclass的中位数进行填充貌似不太行,不够细腻,所以准备通过具体价格区间的人的年龄的中位数,作为Age 的填充值(不回归,貌似其他地方说回归效果不好)
Fare:Fare所有的值都是满的,直接划定区间比较Age 到底在每个Fare的中位的关系:
均值 32.2042079685746
max 512.3292
min 0.0
本来想着price越高,年龄可能越大,存活率分布也往年龄大的地方走,但是出乎意料了…这啥分布
所以确实菜了,直接参照大佬的思路吧:
根据‘Name’提取‘Title’,再用‘Title’的中位数对‘Age‘进行插补:
Title中的Master主要代表little boy,然而却没有代表little girl的Title,由于小孩的生存率往往较高,所以有必要找出哪些是little girl,再填补Age的缺失值。
先假设little girl都没结婚(一般情况下该假设都成立),所以little girl肯定都包含在Miss里面。little boy(Master)的年龄最大值为14岁,所以相应的可以设定年龄小于等于14岁的Miss为little girl。对于年龄缺失的Miss,可以用(Parch!=0)来判定是否为little girl,因为little girl往往是家长陪同上船,不会一个人去。
def girl(aa):
if (aa.Age!=999)&(aa.Title=='Miss')&(aa.Age<=14):
return 'Girl'
elif (aa.Age==999)&(aa.Title=='Miss')&(aa.Parch!=0):
return 'Girl'
else:
return aa.Title
full['Title']=full.apply(girl,axis=1)
Tit=['Mr','Miss','Mrs','Master','Girl','Rareman','Rarewoman']
for i in Tit:
full.loc[(full.Age==999)&(full.Title==i),'Age']=full.loc[full.Title==i,'Age'].median()
具体思路不说了,看完代码就明白了 ORZ
最后一个特征Embarked:
还是老样子看看和存活率有无关系:
首先数据就缺失了三个,影响不大,所以直接看效果:
这个肯定有一些关系,估计是富人区地方上船的活的多一些,大胆猜测S是穷人区,C是富人区,直接加到特征组里面
OK,分析就到这儿,下面是具体特征工程的构建:
Age缺失值的补充(借鉴别人的思路)
Sex 无缺失
Pcalss 无缺失
Name (处理) 无缺失
Embarked(缺三个值,手动观察然后填了)
Fare 肯定也是要的 无缺失
SibSp => 兄弟姐妹数/配偶数 无缺失
Parch => 父母数/子女数 无缺失
八个特征,分别处理,
首先进行特征处理:
主要处理的是Age:
那些不规则的title有大佬分析了词意,由于那些title不是很多,我这儿直接剔除了
就留下这些:
‘Mr’,‘Miss’,‘Mrs’, 和孩子里面的’Master’(存疑) 和’girl’
其他的野鸡名字和缺失值根据性别和年龄分别划分为 Master、Mr、 Miss、girl 、Mrs
如果年龄缺失:找到那行,手动替换(就一个,查到,是个没父母孩子的头等座孤儿博士,根据经验直接判断为Mr)
通过一个title列表存着再说
list_name=[]
title=[]
list_name=df.Name
flag=0
for each in list_name:
temperal_list=each.split(',')
temperal_list=temperal_list[1].split('.')
temperal_list=temperal_list[0].split()
temperal_list=temperal_list[0]
if temperal_list == 'Mr':
pass
elif temperal_list =='Mrs':
pass
elif temperal_list =='Master':
pass
elif temperal_list =='Miss':
if df.loc[flag,'Age']<15:
temperal_list ='Girl'
else:
if (df.loc[flag,'Age']<15) & (df.loc[flag,'Sex']=='male'):
temperal_list ='Master'
elif (df.loc[flag,'Age']<15) & (df.loc[flag,'Sex']=='female'):
temperal_list ='Girl'
elif (df.loc[flag,'Age']>=15) & (df.loc[flag,'Sex']=='female'):
temperal_list ='Mrs'
elif (df.loc[flag,'Age']>=15) &(df.loc[flag,'Sex']=='male'):
temperal_list ='Mr'
else: ##一个买头等座的单身汉 Dr 直接把它当成是一个Mr处理了
temperal_list ='Mr'
title.append(temperal_list)
flag=flag+1
下面就通过title+sex把age缺失值全部替换了
nan_age_name=['Mr','Miss','Mrs','Girl','Master']
list_age=[]
list_age=df.Age
flag=0
for each in list_age:
if np.isnan(each):
df.loc[flag,'Age']=999
#177个缺失值,还是比较多的哦
flag+=1
for each in nan_age_name:
df.loc[(df.Name==each)&(df.Age==999),'Age']=df.loc[(df.Name==each),'Age'].median()
最后两个缺失值的替换(因为上面的Age的一个缺失值,他的上船地点也是缺失的),替换完了就可以开始下一步了:
flag=0
for each in df.Embarked:
if pd.isna(each):
# print(flag)
pass
flag+=1
# print(df.loc[df.Pclass==1,['Embarked','Survived']].groupby(['Embarked']).count().plot.bar())
df.loc[61,'Embarked']='S'
df.loc[829,'Embarked']='S'
急性子,直接RF先上一波,看看和之前的有无变化
好了2%的精度,进了20%
改进:
如果使用十折交叉验证之后查看错误样本,EDA之后调整特征工程
然后用集成学习,引入归一化,结果可能会好一些,估计会到10%左右,但是由于时间关系,就先这样吧,刷下一题了。