处理数据
首先要把 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()
就是取平均值
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 之间
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]