IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 边境的悍匪—Kaggle—泰坦尼克号生还预测详细教程 -> 正文阅读

[人工智能]边境的悍匪—Kaggle—泰坦尼克号生还预测详细教程

前言

最近在学习机器学习,想要把学习到的知识运用到实践中,找了很多地方终决定使用kaggle上的数据集。文章主要描述第一次加入到kaggle中完整的完成对泰坦尼克号数据挖掘、分析到预测,最后上传到平台获取分数的一个过程。

该项目是博主的第一个kaggle项目,记录下来用作学习和分享,全文有任何疑点欢迎立刻联系并指出我的错误,不喜勿喷。

项目介绍

泰坦尼克号的沉没是历史上最臭名昭著的沉船之一。
1912年4月15日,人们普遍认为“永不沉没”的皇家邮轮“泰坦尼克”号在处女航中撞上冰山后沉没。不幸的是,船上没有足够的救生艇供所有人使用,导致2224名乘客和船员中有1502人死亡。
虽然生存中有一些运气因素,但似乎有些人比其他人更有可能生存下来。
在这个挑战中,我们要求你建立一个预测模型来回答这个问题:“什么样的人更有可能活下来?”使用乘客数据(如姓名、年龄、性别、社会经济阶层等)。

前期准备

在这里插入图片描述
图中红框部分就是泰塔尼克号项目,点击进入即可参加。
在这里插入图片描述
点击data获取下载分析数据。

加载数据

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.pipeline import Pipeline, make_pipeline
from sklearn.model_selection import GridSearchCV, cross_val_score
from sklearn.feature_selection import SelectKBest

# 加载数据
train = pd.read_csv("./data/train.csv")
test = pd.read_csv("./data/test.csv")

all_data = pd.concat([train, test])
# 获取测试集的id
passenger_id = test["PassengerId"]

初步分析

我们简单的打印一个数据详情和一部分数据,检查数据的基本情况。我们可以看到这组数据一共有12个特征,其中Age特征缺失263条数据,Fare缺失一条数据,Cabin缺失1014条数据,Embarked缺失2条数据,整个数据集有1309条数据,其中891条是训练集,418条是训练集。

# 特征含义:
# PassengerId(ID)
# Survived (标志是否存活)
# Pclass(客舱等级)
# Name(乘客姓名)
# Sex(性别)
# Age(年龄)
# SibSp(兄弟姐妹数/配偶数)
# Parch(父母数/子女数)
# Ticket(船票编号)
# Fare(票价)
# Cabin(客舱编号)
# Embarked(上船的港口)

print(all_data.info())
print(all_data.head())
print(all_data.isnull().sum())

在这里插入图片描述
在这里插入图片描述

数据清洗

我们接下来的任务需要把数据中缺失的部分用各种方式补全,竟可能的让数据完整统一,看上去更清晰。
首选把性别换位数字

# 把男性设置成 1 女性设置成 0
all_data["Sex"] = all_data["Sex"].apply(lambda x: 0 if x == "female" else 1)

接下来从缺失最多的Cabin下手,我们以重新创建一个特征的方式来补全Cabin。这里使用编号的第一个字母来做为甲板号,缺失的定义为U(unknown),修改完查看每个甲板号的生存率。

# 补全客舱编号特征,此处用Deck来替代客舱编号,编号为空的用unknown U 来替代
all_data["Deck"] = all_data["Cabin"].apply(lambda x: "U" if x is np.nan else str(x)[0])
sns.barplot(x="Deck", y="Survived", data=all_data)
plt.show()

在这里插入图片描述
然后把甲板号改为数字

deck_dict = {"U": 1, "C": 2, "B": 3, "D": 4, "E": 5, "A": 6, "F": 7, "G": 8, "T": 9}
all_data["Deck"] = all_data["Deck"].map(deck_dict)

补全年龄需要根据名字中的特殊标识分类人们的标签,有的是男士有的是妇女有的是士官。完成之后选择年龄(Age),标签(Title),船舱等级(Pclass)性别(Sex)特征来使用RandomForestRegressor训练预测填充缺失值。

# 补全年龄
# 按照标签给这些人分类
all_data["Title"] = all_data["Name"].apply(lambda x: x.split(",")[1].split(".")[0].strip())
# print(all_data["Title"].value_counts())
title_dict = {}
title_dict.update(dict.fromkeys(['Capt', 'Col', 'Major', 'Dr', 'Rev'], "Officer"))
title_dict.update(dict.fromkeys(['Don', 'Sir', 'the Countess', 'Dona', 'Lady'], "Royalty"))
title_dict.update(dict.fromkeys(['Mme', 'Ms', 'Mrs'], 'Mrs'))
title_dict.update(dict.fromkeys(['Mlle', 'Miss'], 'Miss'))
title_dict.update(dict.fromkeys(['Mr'], 'Mr'))
title_dict.update(dict.fromkeys(['Jonkheer', "Master"], 'Master'))
all_data["Title"] = all_data["Title"].map(title_dict)

# 选择性别 标签 客舱等级来预测补全年龄数据
replenish_age = all_data[["Age", "Title", "Pclass", "Sex"]]
replenish_age = pd.get_dummies(replenish_age)
unknown_age = replenish_age[replenish_age["Age"].isnull()].values
known_age = replenish_age[replenish_age["Age"].notnull()].values
X = known_age[:, 1:]
y = known_age[:, 0]
rfr = RandomForestRegressor(n_estimators=100, random_state=0, n_jobs=1)
rfr.fit(X, y)
predict_age = rfr.predict(unknown_age[:, 1:])
all_data.loc[(all_data["Age"].isnull()), "Age"] = predict_age

最后两个根据特征对应的中位数来补全数据

# 补全Fare 与 Embarked
# 查看那一条Fare为空的数据, 根据上船的港口和仓位来查看价格
print(all_data.loc[(all_data["Fare"].isnull())])

fare = all_data.loc[(all_data["Pclass"] == 3) & (all_data["Embarked"] == "S")].Fare.median()
all_data["Fare"] = all_data["Fare"].fillna(fare)

# 查看那两条Embarked为空的数据
print(all_data[["PassengerId", "Pclass", "Fare", "Embarked"]].loc[(all_data["Embarked"].isnull())])
print(all_data.groupby(["Pclass", "Embarked"])["Fare"].median())
all_data.loc[(all_data["Embarked"].isnull()), "Embarked"] = "C"

至此,所有数据清理工作完成。

数据分析

# 查看相关性矩阵图
sns.heatmap(all_data.corr(), cmap="Blues", vmax=1, annot=True)
plt.show()
# 初步确认了有关特征为 甲板号(Deck) 票价(Fare) 性别(Sex) 船舱等级(Pclass)

在这里插入图片描述
根据相关性矩阵图初步确认了有关特征为 甲板号(Deck) 票价(Fare) 性别(Sex) 船舱等级(Pclass),后续就是逐个验证每个特征与存活的关系,会有很多图片这里就不一一呈现。

# 验证甲板号与存活的关系
sns.barplot(x="Deck", y="Survived", data=all_data)
plt.show()

# 验证票价和存活的关系(可升级为价格区间)
face = sns.FacetGrid(all_data, hue="Survived", aspect=2)
face.map(sns.kdeplot, "Fare", shade=True)
face.set(xlim=(0, 100))
face.add_legend()
plt.xlabel("Fare")
plt.ylabel("density")
plt.show()

# 验证性别与存活的关系
sns.barplot(x="Sex", y="Survived", data=all_data)
plt.show()

# 验证船舱等级与存活的关系
sns.barplot(x="Pclass", y="Survived", data=all_data)
plt.show()

# 验证年龄与存活的关系(同样可以升级为年龄区间)
face = sns.FacetGrid(all_data, hue="Survived", aspect=2)
face.map(sns.kdeplot, "Age", shade=True)
face.set(xlim=(0, train["Age"].max()))
face.add_legend()
plt.xlabel("Age")
plt.ylabel("density")
plt.show()

# 验证兄弟姐妹数/配偶数与存活的关系
sns.barplot(x="SibSp", y="Survived", data=all_data)
plt.show()

# 验证父母数/子女数与存活的关系
sns.barplot(x="Parch", y="Survived", data=all_data)
plt.show()

特征转换

在验证了已有特征完成后我还需要生成一些新的特征或者是对原有的特征做一些转换。后续代码主要完成了以下几个事情:

  1. 验证船票编号相同数和生存率的关系。
  2. 生成一个姓的特征家庭数量并对家庭数量进行分类。
  3. 对年龄、票价根据上一步分析的结果进行分类。
 特征转换并验证特征与存活的关系
# 验证船票编号相同数和生存率的关系(初步设想可以分为编号为纯属数字与有字母的分类)
ticket_dict = dict(all_data["Ticket"].value_counts())
all_data["TicketList"] = all_data["Ticket"].apply(lambda x: ticket_dict[x])
print(all_data["TicketList"].value_counts())
sns.barplot(x="TicketList", y="Survived", data=all_data)
plt.show()

# 生成一个家庭人员数据
all_data["FamilySize"] = all_data["SibSp"] + all_data["Parch"] + 1

print(all_data["FamilySize"].value_counts())
sns.barplot(x="FamilySize", y="Survived", data=all_data)
plt.show()

# 对家庭人数进行分类
def family_size_class(num):
    if 2 <= num <= 4:
        return 1
    elif num == 1 or 4 < num <= 8:
        return 2
    elif num > 8:
        return 3

all_data["FamilySizeClass"] = all_data["FamilySize"].apply(family_size_class)

sns.barplot(x="FamilySizeClass", y="Survived", data=all_data)
plt.show()

# 对票价进行分类
def fare_class(f):
    if f <= 30:
        return 1
    elif 30 <= f <= 200:
        return 2
    elif f > 200:
        return 3

all_data["FareClass"] = all_data["Fare"].apply(fare_class)

print(all_data["FareClass"].value_counts())
sns.barplot(x="FareClass", y="Survived", data=all_data)
plt.show()

# 对年龄进行分类
def age_class(a):
    if a <= 20:
        return 1
    elif 20 < a < 35:
        return 2
    elif a >= 35:
        return 3

all_data["AgeClass"] = all_data["Age"].apply(age_class)
print(all_data["AgeClass"].value_counts())
sns.barplot(x="AgeClass", y="Survived", data=all_data)
plt.show()

建模与调优

# 选取特征,划分训练集与测试集
all_data = all_data[["Survived", "Pclass", "Sex", "Embarked", "Deck", "Title", "TicketList",
                     "FamilySizeClass", "FareClass", "AgeClass"]]
all_data = pd.get_dummies(all_data)
train = all_data[all_data["Survived"].notnull()].values
test = all_data[all_data["Survived"].isnull()].drop("Survived", axis=1).values
X = train[:, 1:]
y = train[:, 0]

# 建模和优化
pipe = Pipeline([("select", SelectKBest()),
                 ("classify", RandomForestClassifier(random_state=7, max_features="sqrt"))])

param_test = {"classify__n_estimators": list(range(20, 50, 2)),
              "classify__max_depth": list(range(3, 60, 3))}

gsc = GridSearchCV(estimator=pipe, param_grid=param_test, scoring="roc_auc", cv=10)
gsc.fit(X, y)
print(gsc.best_params_, gsc.best_score_)

模型训练与预测

# 训练模型
select = SelectKBest()
rfc = RandomForestClassifier(random_state=7, max_features="sqrt", n_estimators=42, max_depth=6, warm_start=True)
pipe = make_pipeline(select, rfc)
pipe.fit(X, y)
# 交叉验证
cv_score = cross_val_score(pipe, X, y, cv=10)
print(f"CV Score : Mean - {np.mean(cv_score)} | Std - {np.std(cv_score)}")

# 预测
predictions = pipe.predict(test)
submission = pd.DataFrame({"PassengerId": passenger_id, "Survived": predictions.astype(np.int32)})
submission.to_csv("./data/submission_v0.1.csv", index=False)

总结

最后把生成的csv上传到kaggle即可,泰坦尼克号已经有很多很多的队伍参加,实现的方法大同小异,这个算法最后的结果也并没有达到很完美,还需要很多的改进。如果你有什么好的思路或者是想要和博主一起学习机器学习,可以与我取得联系。邮箱2579779624@qq.com。感谢阅读,祝你好运。

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-08-30 12:03:49  更:2021-08-30 12:04:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/1 12:25:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码