【Kaggle】Titanic - Machine Learning from Disaster
文章目录
- 1. 前言
- 2. 题目描述
- 3. 解答
- 4. 代码学习
- 4.1 数据集处理
- 1. 分析字段Embarked
- 2. 分析字段Fare
- 3. 分析字段Age
- 4. 分析字段Cabin
- 5. 分析字段Parch & SibSp
- 6. 分析字段Sex
- 7. 分析字段Pclass
- 4.2 模型搭建
- 4.3 总结
1. 前言
准备再学习学习TensorFlow
,感觉最好的学习途径就是刷一些题目,故而这里就来尝试做做一些简单的题目。
2. 题目描述
可以直接查看原文:https://www.kaggle.com/competitions/titanic
其流程也就是下载数据集,然后拷贝到项目目录中。然后对数据进行处理,包括缺失值、无效字段等。首先需要搞懂的就是各个字段的含义,然后自己决定哪些字段是无效的,然后进行程序处理即可。比如数据格式为:
最终需要提交的东西也给了说明,也就是两个字段的csv
文件,即:
这里直接进入正题。
3. 解答
最直接的方式就是搭建一个序列模型,然后进行预测。也就是:
def train(feature, label, epochs=10):model = tf.keras.Sequential()model.add(tf.keras.layers.Dense(512, input_shape=(6, ), activation='relu'))model.add(tf.keras.layers.Dense(128, activation='relu'))model.add(tf.keras.layers.Dense(64, activation='relu'))model.add(tf.keras.layers.Dense(1, activation='sigmoid'))model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])model.summary()history = model.fit(feature, label, epochs=epochs, batch_size=64)plot_loss_and_accuracy(history)return model
最终我们需要根据实验效果来调整神经网络层数、epochs
大小等参数,以达到最终目的。在第一次提交的时候,结果为0.75
:
然后,为了观测loss
和accuracy
这里绘制了一下图片:
def plot_loss_and_accuracy(history):"""绘制loss和accuracy的图像"""history_loss = history.history['loss']history_accuracy = history.history['accuracy']plt.plot(history_loss, label="loss")plt.plot(history_accuracy, label="accuracy")plt.grid(True, linestyle='--', alpha=0.5)plt.legend()plt.show()
比如:
很明显,这里loss
出现了波动,且较大,所以可能发生了过拟合,所以这里可以将epoch
调小一些,然后再继续尝试修改模型参数等。观察提交的面板,大家的提交很多都达到了1
的准确率,比如:
这里就考虑看看别人怎么写的。当然,记录下自己的代码:
"""by: 梦否date: 2022-4-11
"""
import pandas as pd
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as pltdef get_raw_data(dataset_name):train_data = pd.read_csv(dataset_name)return train_datadef get_train_data(dataset_name):raw_data = get_raw_data(dataset_name)# 删除Name列,返回删除后副本drop_data = raw_data.drop(['Name'], axis=1)# 替换Sex中的male为0,female为1,inplace=True表示原地替换drop_data.replace('male', 0, inplace=True)drop_data.replace('female', 1, inplace=True)# Age缺失值填充为平均值drop_data.fillna(0, inplace=True)average_age = round(drop_data['Age'].mean())drop_data['Age'] = drop_data['Age'].apply(lambda age: average_age if age == 0 else age)# 删除ticket/cabin/embarked# 删除Name列,返回删除后副本drop_data = drop_data.drop(['Ticket'], axis=1)drop_data = drop_data.drop(['Cabin'], axis=1)drop_data = drop_data.drop(['Embarked'], axis=1)drop_data = drop_data.drop(['PassengerId'], axis=1)# 转为numpy数据类型train_feature = drop_data.iloc[:, 1:].to_numpy()train_label = drop_data.iloc[:, 0].to_numpy()return train_feature, train_labeldef get_test_data(dataset_name):raw_data = get_raw_data(dataset_name)# 删除Name,Ticket,Cabin,Embarkeddrop_data = raw_data.drop(['Name'], axis=1)drop_data = drop_data.drop(['Ticket'], axis=1)drop_data = drop_data.drop(['Cabin'], axis=1)drop_data = drop_data.drop(['Embarked'], axis=1)# 替换Sex中的male为0,female为1,inplace=True表示原地替换drop_data.replace('male', 0, inplace=True)drop_data.replace('female', 1, inplace=True)# Age缺失值填充为平均值drop_data.fillna(0, inplace=True)average_age = round(drop_data['Age'].mean())drop_data['Age'] = drop_data['Age'].apply(lambda age: average_age if age == 0 else age)# 转为numpy数据类型identify = drop_data.iloc[:, 0].to_numpy()feature = drop_data.iloc[:, 1:].to_numpy()return identify, featuredef train(feature, label, epochs=10):model = tf.keras.Sequential()model.add(tf.keras.layers.Dense(512, input_shape=(6, ), activation='relu'))model.add(tf.keras.layers.Dense(128, activation='relu'))model.add(tf.keras.layers.Dense(64, activation='relu'))model.add(tf.keras.layers.Dense(1, activation='sigmoid'))model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])model.summary()history = model.fit(feature, label, epochs=epochs, batch_size=64)plot_loss_and_accuracy(history)return modeldef plot_loss_and_accuracy(history):"""绘制loss和accuracy的图像"""history_loss = history.history['loss']history_accuracy = history.history['accuracy']plt.plot(history_loss, label="loss")plt.plot(history_accuracy, label="accuracy")plt.grid(True, linestyle='--', alpha=0.5)plt.legend()plt.show()def predict_model(model, feature):predict = model.predict(feature)predict[predict < 0.5] = 1predict[predict >= 0.5] = 0return predictif __name__ == '__main__':train_x, train_y = get_train_data("./dataset/train.csv")print(train_x)identify, feature = get_test_data("./dataset/test.csv")model = train(train_x, train_y, epochs=500)predict = predict_model(model, feature)submission = pd.DataFrame({"PassengerId": identify,"Survived": predict[:, 0].astype(int)})submission.to_csv('result.csv', index=False)
4. 代码学习
简单搜索可以发现,大家解决这个问题都是使用RandomForestClassifier
,也就是使用传统机器学习的方式来解决了这个问题。这里来简单学习和理解下大佬的解题思路。
4.1 数据集处理
删除了明显逻辑无关字段PassengerId
、Name
、Ticket
字段;对其余字段进行简单统计分析,分析是否是影响因素。
1. 分析字段Embarked
对字段缺失值处理,Embarked
使用出现较多的S
来填充,然后简单绘制了一下分布图:
这里可以看出,虽然三类数据数量不同,但是由于存活或者死亡,S
、C
、Q
均有,且无明显区分,并不能将其作为区分标准,故而可以将其直接删除。
2. 分析字段Fare
这里作者的缺失值处理比较值得记录:
test_df["Fare"].fillna(test_df["Fare"].median(), inplace=True)
直接使用原本数据平均值进行填充,在我的代码中却分为了几步:
# Age缺失值填充为平均值
drop_data.fillna(0, inplace=True)
average_age = round(drop_data['Age'].mean())
drop_data['Age'] = drop_data['Age'].apply(lambda age: average_age if age == 0 else age)
同样的,作者在分析该字段的时候,也考虑了和Survived
的关系统计,处理为:
# get fare for survived & didn't survive passengers
fare_not_survived = titanic_df["Fare"][titanic_df["Survived"] == 0]
fare_survived = titanic_df["Fare"][titanic_df["Survived"] == 1]
然后,求其平均值和标准差:
# get average and std for fare of survived/not survived passengers
avgerage_fare = DataFrame([fare_not_survived.mean(), fare_survived.mean()])
std_fare = DataFrame([fare_not_survived.std(), fare_survived.std()])
然后将平均值进行绘制条状图,将标准差作为误差线,即:
# pandas.plot
avgerage_fare.plot(yerr=std_fare,kind='bar',legend=False)
结果:
也就是该字段和Survived
相关,应该保留。
3. 分析字段Age
同样该字段存在缺失值,这里的处理为:
generate random numbers between (mean - std) & (mean + std)
首先,统计:
# get average, std, and number of NaN values in titanic_df
average_age_titanic = titanic_df["Age"].mean()
std_age_titanic = titanic_df["Age"].std()
count_nan_age_titanic = titanic_df["Age"].isnull().sum()
然后,生成对应的随机数:
# generate random numbers between (mean - std) & (mean + std)
rand_1 = np.random.randint(average_age_titanic - std_age_titanic, average_age_titanic + std_age_titanic, size = count_nan_age_titanic)
进行空白值的填充:
# fill NaN values in Age column with random values generated
titanic_df["Age"][np.isnan(titanic_df["Age"])] = rand_1
test_df["Age"][np.isnan(test_df["Age"])] = rand_2
然后,转为int
类型,因为numpy
中默认是float
类型:
# convert from float to int
titanic_df['Age'] = titanic_df['Age'].astype(int)
然后还是统计一下和survived
的关系:
观察上图可以知道,无论是存活还是死亡,年龄数据分布类似,无法区分。故而作者做了一个统计:
统计了各个年龄中存活的人数,这里可以看到是相关的,即年幼或者年长比较容易存活。也就是相关的。
4. 分析字段Cabin
由于其缺失值过多,直接排除。
5. 分析字段Parch & SibSp
由于其表示的意义相同,也就是家庭关系,这里可以进行简单相加进行分析即可。分析的因素为存在家庭成员与否是否和最终survived
相关。即:
titanic_df['Family'] = titanic_df["Parch"] + titanic_df["SibSp"]
为了方便处理,直接转换为:
titanic_df['Family'].loc[titanic_df['Family'] > 0] = 1
然后绘制一下二者的关系:
family_perc = titanic_df[["Family", "Survived"]].groupby(['Family'],as_index=False).mean()
sns.barplot(x='Family', y='Survived', data=family_perc, order=[1,0], ax=axis2)
观察可知,没家庭的大约比有家庭的存活率低0.2。大部分人都没家庭,故而可能有家庭的存活率更高。也就是相关的。
6. 分析字段Sex
作者简单分为三类:男人、女人和孩子。孩子定义为年龄小于16岁,故而和上面类似需要将Age
和Sex
联合处理:
def get_person(passenger):age,sex = passengerreturn 'child' if age < 16 else sextitanic_df['Person'] = titanic_df[['Age','Sex']].apply(get_person,axis=1)
test_df['Person'] = test_df[['Age','Sex']].apply(get_person,axis=1)
然后同样绘制其关系:
# average of survived for each Person(male, female, or child)
person_perc = titanic_df[["Person", "Survived"]].groupby(['Person'],as_index=False).mean()
sns.barplot(x='Person', y='Survived', data=person_perc, ax=axis2, order=['male','female','child'])
比较突出的是,孩子人数最少,但是存活率比较高;女人人数比较少,但存活率也远高于男人,极性差比较大,故而这个因素比较重要。
7. 分析字段Pclass
作者直接使用sns.factorplot
来绘制二维变量的关系:
也是相关的。
4.2 模型搭建
数据处理完毕后,直接使用了逻辑回归模型:
logreg = LogisticRegression()
logreg.fit(X_train, Y_train)
Y_pred = logreg.predict(X_test)
logreg.score(X_train, Y_train)
精确率达到0.81144781144781142
使用随机森林:
random_forest = RandomForestClassifier(n_estimators=100)
random_forest.fit(X_train, Y_train)
Y_pred = random_forest.predict(X_test)
random_forest.score(X_train, Y_train)
精确率达到0.96745230078563416
最后保存输出结果数据:
submission = pd.DataFrame({"PassengerId": test_df["PassengerId"],"Survived": Y_pred})
submission.to_csv('titanic.csv', index=False)
4.3 总结
可以看出数据分析和处理至关重要,不是随机直观分析的。最后模型的选择也比较重要,需要尝试。明天打算继续使用tf2
来继续解决。
【Kaggle】Titanic - Machine Learning from Disaster相关推荐
- 【Kaggle】Titanic - Machine Learning from Disaster(二)
文章目录 1. 前言 2. 预备-环境配置 3. 数据集处理 3.1 读取数据集 3.2 查看pandas数据信息 3.2.1 查看总体信息 3.2.2 数据集空值统计 3.3. 相关性分析 3.3. ...
- 【Kaggle】Intermediate Machine Learning(XGBoost + Data Leakage)
文章目录 6. XGBoost 7. Data Leakage 数据泄露 上一篇:[Kaggle]Intermediate Machine Learning(管道+交叉验证) 6. XGBoost 参 ...
- 【Kaggle】Intermediate Machine Learning(管道+交叉验证)
文章目录 4. Pipelines 管道 5. Cross-Validation 交叉验证 上一篇:[Kaggle]Intermediate Machine Learning(缺失值+文字特征处理) ...
- 【Kaggle】Intermediate Machine Learning(缺失值+文字特征处理)
文章目录 1. Introduction 2. Missing Values 缺失值处理 3. Categorical Variables 文字变量处理 from https://www.kaggle ...
- 【kaggle入门题一】Titanic: Machine Learning from Disaster
原题: Start here if... You're new to data science and machine learning, or looking for a simple intro ...
- 机器学习案例学习【每周一例】之 Titanic: Machine Learning from Disaster
下面一文章就总结几点关键: 1.要学会观察,尤其是输入数据的特征提取时,看各输入数据和输出的关系,用绘图看! 2.训练后,看测试数据和训练数据误差,确定是否过拟合还是欠拟合: 3.欠拟合的话,说明模 ...
- Kaggle | Titanic - Machine Learning from Disaster【泰坦尼克号生存预测】 | baseline及优秀notebook总结
文章目录 一.数据介绍 二.代码 三.代码优化方向 一.数据介绍 Titanic - Machine Learning from Disaster是主要针对机器学习初学者开展的比赛,数据格式比较简 ...
- 小白的机器学习之路(1)---Kaggle竞赛:泰坦尼克之灾(Titanic Machine Learning from Disaster)
我是目录 前言 数据导入 可视化分析 Pclass Sex Age SibSp Parch Fare Cabin Embarked 特征提取 Title Family Size Companion A ...
- 大数据第一课(满分作业)——泰坦尼克号生存者预测(Titanic - Machine Learning from Disaster)
大数据第一课(满分作业)--泰坦尼克号生存者预测(Titanic - Machine Learning from Disaster) 1 项目背景 1.1 The Challenge 1.2 What ...
- Kaggle——泰坦尼克号(Titanic: Machine Learning from Disaster)详细过程
一.简介 1.数据 (1)训练集(train.csv) (2)测试集(test.csv) (3)提交文件示例(gender_submission.csv) 对于训练集,我们为每位乘客提供结果.模型将基 ...
最新文章
- 配置scp在Linux或Unix之间传输文件无需密码
- 如何在Python中捕获SIGINT?
- 关于longlong与位运算
- 《深入浅出MFC》第六章 MFC程序的生死因果
- REVERSE-COMPETITION-GeekChallenge2021
- java实现系列化的jdk_Java反序列化之与JDK版本无关的利用链挖掘
- 由李飞飞领导,斯坦福以人为本AI学院正式成立,比尔·盖茨来捧场
- 从头搭建drbd+openfiler+corosync (二)
- 32 位的有符号整数_「js基础」JavaScript逻辑和位运算符归纳
- 4种实例 advice aop_JAVA动态代理 和 Spring AOP 4种通知的简单实现
- 三菱PLC和卓岚串口服务器使用方法
- 各种常用的默认端口号 总结
- Blinky.c(171): warning: #1-D: last line of file ends without a newline
- Linux查看端口命令:netstat -tln
- 我国电子商务发展的进化策略
- matlab 函数前加,matlab fopen函数的用法在程序前添加代码:addp
- PHP开发常见面试题目
- 天猫双12爬虫(福利:266万条商品数据免费下载)
- LT8618SX 是龙迅的低功耗版本 HDMI 发射器,其基于 ClearEdgeTM 技术
- linux下ImageMagick convert命令