泰坦尼克号生还率预测

2021-03-10 20:29:49 浏览数 (1)

处理数据

首先要把 xls 文件中的数据读进来,使用 pandas 库的 read_excel():

代码语言:javascript复制
import pandas as pd
import numpy as np
all_data = pd.read_excel('titanic3.xls')

读进来的数据可以用 all_data[:2] 查看前两行

列名

含义

PassengerId

乘客编号

Survival

是否生还,0表示未生还,1表示生还

Pclass

船票种类,1表示上层,2表示中层,3表示底层

Sex

性别,男性为male,女性为female

Age

年龄,不满1岁的年龄为小数

SibSp

该乘客同船的兄弟姐妹及配偶的数量

Parch

该乘客同船的父母以及儿女的数量

Ticket

船票编号

Fare

买票的费用

Cabin

船舱编号

Embarked

代表在哪里上的船

有些东西不会影响生还率,比如:姓名、船票编号、船舱编号、在哪里上船等,但是要用姓名来进行预测,所以要保留,而在哪里上船(embarked)也暂时保留,用它学个新知识,正常训练删掉就可

可以先把要保留的字段做成一个列表,然后再把列表保留出来

代码语言:javascript复制
cols = ['survived', 'name', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'fare', 'embarked']
#cols = ['survived', 'name', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'fare']
all_data = all_data[cols]
代码语言:javascript复制
embarked 这个列是字母,把它换成一位有效编码,用的是 get_dummies 这个方法
代码语言:javascript复制
OneHot_data = pd.get_dummies(data=data_train, columns=['embarked'])

正式处理数据:

我们取 80% 作为训练数据,剩下的作为测试数据

代码语言:javascript复制
msk = np.random.random(len(all_df)) < 0.8
train_data = all_data[msk]
test_data = all_data[~msk]

写一个函数综合处理一下:

代码语言:javascript复制
def PreprocessData(raw_df):
    df = raw_df.drop(['name'], axis = 1)
    age_mean = df['age'].mean()
    df['age'] = df['age'].fillna(age_mean)   
    fare_mean = df['fare'].mean()
    df['fare'] = df['fare'].fillna(fare_mean)
    df['sex'] = df['sex'].map({'female':0, 'male':1})
    ndarray = df.values
    Label = ndarray[:, 0]
    Features = ndarray[:, 1:]
    minmax_scale = preprocessing.MinMaxScaler((0,1))
    scaledFeatures = minmax_scale.fit_transform(Features)
    return scaledFeatures, Label

下面一个一个介绍是干啥的:

因为 name 列对于训练是没用的,只是后面拿来预测用,所以先把 name 列去除

代码语言:javascript复制
df = raw_df.drop(['name'], axis = 1)
代码语言:javascript复制

有个问题,有些列中存在空值,我们可以看一下有多少

代码语言:javascript复制
data_train.isnull().sum()
代码语言:javascript复制

对于这些存在空值的列,可以把他们填充为这一列的平均值,mean() 就是取平均值

代码语言:javascript复制
age_mean = df['age'].mean()
df['age'] = df['age'].fillna(age_mean)   
fare_mean = df['fare'].mean()
df['fare'] = df['fare'].fillna(fare_mean)
代码语言:javascript复制

对于性别这一列,使用 map 方法,将 female 设置为 0,male 设置为 1

代码语言:javascript复制
df['sex'] = df['sex'].map({'female':0, 'male':1})
代码语言:javascript复制

再把数据转换为数组

代码语言:javascript复制
ndarray = df.values
代码语言:javascript复制

取第一列的数据作为标签 Label,剩下的是特征 Features

代码语言:javascript复制
Label = ndarray[:, 0]
Features = ndarray[:, 1:]
代码语言:javascript复制

接下来把数据进行归一化,但是这里的数据跟图片的数据不一样了,他不是一定落在 0-255 之间,所以没法直接除 255,MinMaxScaler() 方法用于产生标准化刻度,参数设置为(0~1),表示将数据标准化后全部落在 0~1 之间

代码语言:javascript复制
minmax_scale = preprocessing.MinMaxScaler((0,1))
scaledFeatures = minmax_scale.fit_transform(Features)
代码语言:javascript复制

实际处理数据的时候就:

代码语言:javascript复制
train_Features,train_Label = PreprocessData(train_data)
test_Features,test_Label = PreprocessData(test_data)
代码语言:javascript复制

创建模型

代码语言:javascript复制
from keras.models import Sequential
from keras.layers import Dense, Dropout
model = Sequential()
model.add(Dense(units = 200, input_dim=6, kernel_initializer='uniform', activation='relu'))
model.add(Dense(units = 200, kernel_initializer='uniform', activation='relu'))
model.add(Dense(units=1, kernel_initializer='uniform', activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

训练

代码语言:javascript复制
train_history = model.fit(train_Feature, train_Label, validation_split=0.2, epochs=50, batch_size=20, verbose=2)
代码语言:javascript复制

验证模型准确率

代码语言:javascript复制
scores = model.evaluate(test_Feature, test_Label)
print(scores)
代码语言:javascript复制

添加人物信息

把想要预测的任务构建出来

比如想要预测 yichen:

代码语言:javascript复制
#'survived:是否生还', 'name', 'pclass:船票种类(1>2>3)', 'sex', 'age', 'sibsp:兄弟姐妹数', 'parch:父母孩子数', 'fare:买票的费用'
yichen_data = [1,'yichen','3','male',22,0,2,32.7]
代码语言:javascript复制

是否生还这一项,预测的时候就不用了,无关紧要,但我还是写成了生还哈哈哈哈哈

我这肯定是最底层的船舱了,费用就取了个他们的平均数 32.7

代码语言:javascript复制
yichen_df = pd.DataFrame([list(yichen_data)], columns=['survived', 'name', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'fare'])

然后用写好的函数处理一下

代码语言:javascript复制
yichen_Features,label = PreprocessData(yichen_df)

预测一下

代码语言:javascript复制
probability = model.predict(yichen_Features)
代码语言:javascript复制

把预测的结果 probability 加在原来的数据中

代码语言:javascript复制
yichen_df.insert(len(yichen_df.columns), 'probability', probability)
代码语言:javascript复制
看看结果,我这生还率高得离谱!?

呸,不能这样算!!!!

它是按照一艘船有那么多人,几人可以生还那样训练的,就一个人必存活呀,我这还低了呐

先把这个数据加在总的数据里面,这样生还率应该稍微比真实情况偏低一丁点,但是这样才是预测的正确姿势呀

代码语言:javascript复制
all_df = pd.concat([all_df, yichen_df])
代码语言:javascript复制

呜呜呜,29% 的生还率,要是能买个 1 等的船舱就是 71% 啦

然而为啥花的钱少生存率还能高啊?

可以后台留言你的信息,帮你预测一下生还率

按照这个格式:

代码语言:javascript复制
#'survived:是否生还', 'name', 'pclass:船票种类(1>2>3)', 'sex', 'age', 'sibsp:兄弟姐妹数', 'parch:父母孩子数', 'fare:买票的费用'
yichen_data = [1,'yichen','3','male',22,0,2,32.7]

0 人点赞