码迷,mamicode.com
首页 > 其他好文 > 详细

kaggle—first play—Titanic

时间:2018-12-17 02:13:18      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:等级   rest   csv   param   gis   小孩   sim   inpu   img   

 

 

玩了很久总算是又静下心来好好看书,经过一段时间的学习,打算稍微检验一下知识的掌握程度,所以去kaggle参加了久闻的泰坦尼克生还预测,以下是正文。

-----------------------------------------------------------------------------------------

1、观察数据

拿到数据集后,先来了解数据的大致情况。

data.info()
data_des = data.describe() 

技术分享图片          技术分享图片

可以得知数据集有12列,891行,其中‘Age‘、‘Cabin‘、‘Embarked‘列存在缺失值,所有样本的平均生还率未0.383838;2等3等舱的人数比1等舱多;平均年龄为29.6991岁等等。

同时明确了需要预测的结果,即‘Survived‘的预测,是个明显的二分类问题,优先考虑逻辑回归、决策树、神经网络等算法。

以下为各列的含义:

passengerid_乘客ID    survived_是否获救(目标)    pclass_乘客等级
name_姓名    sex_性别    age_年龄(缺失)   sibsp_堂兄弟/妹个数    parch_父母/小孩个数   
ticket_船票信息    fare_票价    cabin_客舱号(缺失)    embarked_登船港口(缺失)

对数据分组对比,先观察乘客等级、年龄、性别、登船港口与是否生还的关系:

#性别生还率:女性生还率74.2%,男性生还率18.9%
sex_survived = data.groupby(by=[Sex])[Survived].agg({总人数:np.size, 生还人数:np.sum})
sex_survived[未生还人数] = sex_survived[总人数] - sex_survived[生还人数]
sex_survived[生还率] = sex_survived[生还人数] / sex_survived[总人数]
#乘客等级生还率:1级乘客生还率最高
pclass_survived = data.groupby(by=[Pclass])[Survived].agg({总人数:np.size, 生还人数:np.sum})
pclass_survived[未生还人数] = pclass_survived[总人数] - pclass_survived[生还人数]
pclass_survived[生还率] = pclass_survived[生还人数] / pclass_survived[总人数]
#各年龄段生还率:0-10岁生还率最高,60岁以上生还率最低
bins = [0,10,20,30,40,50,60,70,80]
data[age_cut] = pd.cut(data[Age],bins,right=False)
age_survived = data.groupby(by=[age_cut])[Survived].agg({总人数:np.size, 生还人数:np.sum})
age_survived[未生还人数] = age_survived[总人数] - age_survived[生还人数]
age_survived[生还率] = age_survived[生还人数] / age_survived[总人数]
#各登船港口生还率:C港生还率最高,S港人数最多、生还率最低
embarked_survived = data.groupby(by=[Embarked])[Survived].agg({总人数:np.size, 生还人数:np.sum})
embarked_survived[未生还人数] = embarked_survived[总人数] - embarked_survived[生还人数]
embarked_survived[生还率] = embarked_survived[生还人数] / embarked_survived[总人数]

###可视化
plt.rcParams[font.sans-serif]=[SimHei]
plt.rcParams[axes.unicode_minus] =False

plt.subplot(221)  #将图形区域分成2行*2列,将图形设置在第1个位置
plt.bar(sex_survived.index, sex_survived[生还人数], color=b, alpha=0.7)
plt.bar(sex_survived.index, sex_survived[未生还人数], bottom=sex_survived[生还人数], color=lightblue)
plt.title(性别获救情况)
plt.ylabel(人数) 
plt.grid(b=True, which=major, axis=y)

plt.subplot(222)
plt.bar(pclass_survived.index, pclass_survived[生还人数], color=b, alpha=0.7)
plt.bar(pclass_survived.index, pclass_survived[未生还人数], bottom=pclass_survived[生还人数], color=lightblue)
plt.xticks(pclass_survived.index)
plt.title(乘客等级获救情况)
plt.xlabel(乘客等级)
plt.ylabel(人数)
plt.grid(b=True, which=major, axis=y)

plt.subplot(223)
age_survived[age_index] = age_survived.index.astype(str)
plt.bar(age_survived[age_index], age_survived[生还人数], color=b, alpha=0.7)
plt.bar(age_survived[age_index], age_survived[未生还人数], bottom=age_survived[生还人数], color=lightblue)
plt.xticks(age_survived[age_index])
plt.title(按年龄获救情况)
plt.xlabel(年龄分布)
plt.ylabel(人数)                   
plt.grid(b=True, which=major, axis=y)

使用循环优化代码后:

#各个维度的生还率
bins = [0,10,20,30,40,50,60,70,80]
data[age_cut] = pd.cut(data[Age],bins,right=False)
dataframe = [sex_survived, pclass_survived, age_survived , embarked_survived]
columns = [Sex, Pclass, age_cut, Embarked]

for name in dataframe:
    for i in range(0,4):
        dataframe[i] = data.groupby(by=[columns[i]])[Survived].agg({总人数:np.size, 生还人数:np.sum})
        dataframe[i][未生还人数] = dataframe[i][总人数] - dataframe[i][生还人数]
        dataframe[i][生还率] = dataframe[i][生还人数] / dataframe[i][总人数]
print(dataframe)
  
#画图
plt.rcParams[font.sans-serif]=[SimHei]
plt.rcParams[axes.unicode_minus] =False
dataframe[2][age_index] = dataframe[2].index.astype(str) 
dataframe[2] = dataframe[2].set_index(dataframe[2][age_index])

for j in range(0,4):
    plt.subplot(2,2,j+1)  #将图形区域分成2行*2列,将图形设置在第1个位置
    plt.bar(dataframe[j].index, dataframe[j][生还人数], color=b, alpha=0.7)
    plt.bar(dataframe[j].index, dataframe[j][未生还人数], bottom=dataframe[j][生还人数], color=lightblue)
    plt.title(columns[j])
    plt.ylabel(人数) 
    plt.grid(b=True, which=major, axis=y)

得到如下的图形:(宝蓝色为获救)

技术分享图片

数据显示:女性生还率74.2%,男性生还率18.9%;1级乘客生还率最高;0-10岁生还率最高,60岁以上生还率最低;C港生还率最高,S港人数最多、生还率最低

得到结论:性别、年龄、乘客等级、登船港口都对是否获救有较大影响。

另:船票价格与乘客等级相关较强,但与生还率的关系不明显;堂兄弟、父母/小孩数量对生还结果没有明显影响。

 

2、数据处理

 1)年龄的缺失项

由于年龄对于是否生还的影响还是比较明显,且缺失较多(缺失177个,接近20%),所以不能直接忽略缺失项或对缺失项做简单的均值、中位数等替换。

这里考虑使用随机森林对年龄进行预测填补:

https://scikit-learn.org/dev/modules/generated/sklearn.ensemble.RandomForestRegressor.html(随机森林官方文档)

#对年龄缺失项做随机森林进行填补
age_data = data[[Age,Fare, Parch, SibSp, Pclass]]
fcolumns = [Fare, Parch, SibSp, Pclass]
tcolumns = [Age]

age_data_known = age_data[age_data.Age.notnull()]
age_data_unknown = age_data[age_data.Age.isnull()]

fdata = age_data_known[fcolumns]#特征变量
tdata = age_data_known[tcolumns]#目标变量

from sklearn.ensemble import RandomForestRegressor
rfrmodel = RandomForestRegressor(n_jobs=-1)
rfrmodel.fit(fdata, tdata )

predictedAges = rfrmodel.predict(age_data_unknown[fcolumns])
data.loc[data[Age].isnull(), Age] = predictedAges

#对登船港口的2个缺失项用众数进行填补
data.loc[data[‘Embarked‘].isnull(), ‘Embarked‘] = ‘S

2)非数值型特征的虚拟化

由于性别、登船港口还都是字符型数据,所以需要对这两个特征做虚拟变换

#设置训练集及虚拟变量
data_train = pd.DataFrame([])
data_train[[ID, age, pclass, sibsp, parch, fare, survived]] = data[[PassengerId, Age,Pclass,SibSp,Parch,Fare,Survived]]
#性别
data_train[[sex_female,sex_male]] = pd.get_dummies(data[Sex])
#登船港口
data_train[[embarked_C,embarked_Q,embarked_S]] = pd.get_dummies(data[Embarked])
data_train = data_train.set_index(ID)

3)数值特征标准化

由于年龄、船票价格两个特征跨度很大,所以对这两个特征做标准化处理

import sklearn.preprocessing as preprocessing
scaler = preprocessing.MinMaxScaler()
data_train[age] = scaler.fit_transform(np.array(data_train[age]).reshape(891,-891))
data_train[fare] = scaler.fit_transform(np.array(data_train[fare]).reshape(891,-891))

 

3、模型建立

首先使用逻辑回归模型

https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html(逻辑回归官方文档)

from sklearn import linear_model
lrModel = linear_model.LogisticRegression(penalty=l1)

inputcolumns = [age, pclass, sibsp, parch, fare, sex_female,
       sex_male, embarked_C, embarked_Q, embarked_S]
outpucolumns = [survived]

lrModel.fit(data_train[inputcolumns], data_train[outpucolumns])
lrModel.score(data_train[inputcolumns], data_train[outpucolumns])#模型评分0.8

 

4、测试集处理

data2 = pd.read_csv(rD:\kaggle\datafile\titanic\test.csv)
data2.info()#年龄缺失,船票价格存在一个缺失项
data2.loc[data2[Fare].isnull(), Fare] = data2[Fare].mean()
#年龄缺失项处理
age_data2 = data2[[Age,Fare, Parch, SibSp, Pclass]]
age_data2_known = age_data2[age_data2.Age.notnull()]
age_data2_unknown = age_data2[age_data2.Age.isnull()]

fdata2 = age_data2_known[fcolumns]#特征变量
tdata2 = age_data2_known[tcolumns]#目标变量

rfrmodel.fit(fdata2, tdata2)
predictedAges2 = rfrmodel.predict(age_data2_unknown[fcolumns])
data2.loc[data2[Age].isnull(), Age] = predictedAges2
#构建训练集
data_test = pd.DataFrame([])
data_test[[ID, age, pclass, sibsp, parch, fare]] = data2[[PassengerId, Age,Pclass,SibSp,Parch,Fare]]
#虚拟变量
data_test[[sex_female,sex_male]] = pd.get_dummies(data2[Sex])#性别
data_test[[embarked_C,embarked_Q,embarked_S]] = pd.get_dummies(data2[Embarked])#登船港口
#数值标准化
data_test[age] = scaler.fit_transform(np.array(data_test[age]).reshape(418,-418))
data_test[fare] = scaler.fit_transform(np.array(data_test[fare]).reshape(418,-418))
#得到测试集预测结果
predictions = lrModel.predict(data_test[inputcolumns])
result = pd.DataFrame({PassengerId:data_test[PassengerId], Survived:predictions})

 如此就能够得到初步预测的结果了,后续会更新后面的优化等。

kaggle—first play—Titanic

标签:等级   rest   csv   param   gis   小孩   sim   inpu   img   

原文地址:https://www.cnblogs.com/rix-yb/p/10126221.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!