数据:titanic3.xls

处理数据

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

  1. import pandas as pd
  2. import numpy as np
  3. all_data = pd.read_excel('titanic3.xls')

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

image.png

列名 含义
PassengerId 乘客编号
Survival 是否生还,0表示未生还,1表示生还
Pclass 船票种类,1表示上层,2表示中层,3表示底层
Sex 性别,男性为male,女性为female
Age 年龄,不满1岁的年龄为小数
SibSp 该乘客同船的兄弟姐妹及配偶的数量
Parch 该乘客同船的父母以及儿女的数量
Ticket 船票编号
Fare 买票的费用
Cabin 船舱编号
Embarked 代表在哪里上的船

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

  1. cols = ['survived', 'name', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'fare', 'embarked']
  2. #cols = ['survived', 'name', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'fare']
  3. all_data = all_data[cols]

embarked 这个列是字母,把它换成一位有效编码,用的是 get_dummies 这个方法

image.png

  1. OneHot_data = pd.get_dummies(data=data_train, columns=['embarked'])

image.png

正式处理数据:
我们取 80% 作为训练数据,剩下的作为测试数据

  1. msk = np.random.random(len(all_df)) < 0.8
  2. train_data = all_data[msk]
  3. test_data = all_data[~msk]

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

  1. def PreprocessData(raw_df):
  2. df = raw_df.drop(['name'], axis = 1)
  3. age_mean = df['age'].mean()
  4. df['age'] = df['age'].fillna(age_mean)
  5. fare_mean = df['fare'].mean()
  6. df['fare'] = df['fare'].fillna(fare_mean)
  7. df['sex'] = df['sex'].map({'female':0, 'male':1})
  8. ndarray = df.values
  9. Label = ndarray[:, 0]
  10. Features = ndarray[:, 1:]
  11. minmax_scale = preprocessing.MinMaxScaler((0,1))
  12. scaledFeatures = minmax_scale.fit_transform(Features)
  13. return scaledFeatures, Label

下面一个一个介绍是干啥的:
因为 name 列对于训练是没用的,只是后面拿来预测用,所以先把 name 列去除

  1. df = raw_df.drop(['name'], axis = 1)

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

  1. data_train.isnull().sum()

image.png

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

  1. age_mean = df['age'].mean()
  2. df['age'] = df['age'].fillna(age_mean)
  3. fare_mean = df['fare'].mean()
  4. df['fare'] = df['fare'].fillna(fare_mean)

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

  1. df['sex'] = df['sex'].map({'female':0, 'male':1})

再把数据转换为数组

  1. ndarray = df.values

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

  1. Label = ndarray[:, 0]
  2. Features = ndarray[:, 1:]

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

  1. minmax_scale = preprocessing.MinMaxScaler((0,1))
  2. scaledFeatures = minmax_scale.fit_transform(Features)

实际处理数据的时候就:

  1. train_Features,train_Label = PreprocessData(train_data)
  2. test_Features,test_Label = PreprocessData(test_data)

创建模型

  1. from keras.models import Sequential
  2. from keras.layers import Dense, Dropout
  3. model = Sequential()
  4. model.add(Dense(units = 200, input_dim=6, kernel_initializer='uniform', activation='relu'))
  5. model.add(Dense(units = 200, kernel_initializer='uniform', activation='relu'))
  6. model.add(Dense(units=1, kernel_initializer='uniform', activation='sigmoid'))
  7. model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

训练

  1. train_history = model.fit(train_Feature, train_Label, validation_split=0.2, epochs=50, batch_size=20, verbose=2)

验证模型准确率

  1. scores = model.evaluate(test_Feature, test_Label)
  2. print(scores)

添加人物信息

把想要预测的任务构建出来
比如想要预测 yichen:

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

是否生还这一项,预测的时候就不用了,无关紧要,但我还是写成了生还哈哈哈哈哈
我这肯定是最底层的船舱了,费用就取了个他们的平均数 32.7

  1. yichen_df = pd.DataFrame([list(yichen_data)], columns=['survived', 'name', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'fare'])

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

  1. yichen_Features,label = PreprocessData(yichen_df)

预测一下

  1. probability = model.predict(yichen_Features)

看看结果

  1. yichen_df.insert(len(yichen_df.columns), 'probability', probability)

我这生还率高得离谱!?

image.png

呸,不能这样算!!!!
它是按照那么多人有几个小艇可以走那样训练的,就一个人必存活呀
先把这个数据加在总的数据里面,这样生还率应该稍微比真实情况偏低一丁点,但是这样才是预测的正确姿势呀

  1. all_df = pd.concat([all_df, yichen_df])

image.png

呜呜呜,29% 的生还率

要是能买个 1 等的船舱就是 71% 啦

image.png

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

image.png

image.png