机器学习 - Kaggle项目实践(1)Titanic

Titanic - Machine Learning from Disaster | Kaggle 题目

Titanic Data Science Solutions | Kaggle 参考题解

notebookbe6ed1ba33 | Kaggle 下面项目我在Kaggle上的呈现

Titanic数据集 主要任务是表格数据处理 给定train.csv数据 预测test.csv中乘客的生还情况。

每个乘客有是否生还的标签,以及Pclass、Age、Sex等11项信息,我们可以

  1. 先对表格特征做一些基本分析/可视化 有初步了解。

  2. 再进行数据清洗,把空缺数据、字符串数据转化为易于机器学习模型处理的数值数据。

  3. 最后尝试一些机器学习模型,进行模型评估与答案预测。

目录

[1. 数据分析](#1. 数据分析)

[2. 数据清洗](#2. 数据清洗)

[3. 模型调用与预测](#3. 模型调用与预测)


1. 数据分析

Pandas 中的导入为 DataFrame; 再用 .head() .info() .describe() 得到一些基本信息

python 复制代码
import pandas as pd

#kaggle导入 复制右侧路径
train_df = pd.read_csv('/kaggle/input/titanic/train.csv') 
test_df = pd.read_csv('/kaggle/input/titanic/test.csv')
print(train_df.columns.values) #列的种类

train_df.head() #前五个
train_df.tail() #后五个

train_df.info()
print('_'*40)
test_df.info()  # 列名、非空值数量、数据类型、内存占用 信息

train_df.describe() # 数值型列的 描述性统计量

train_df.describe(include=['O']) # 非数值型列(object/字符串) 的描述性统计量

对于每一列 分为每一类别 求平均存活率 再降序排列

python 复制代码
train_df[['Pclass', 'Survived']].groupby(['Pclass'], as_index=False).mean().sort_values(by='Survived', ascending=False)

train_df[["Sex", "Survived"]].groupby(['Sex'], as_index=False).mean().sort_values(by='Survived', ascending=False)

train_df[["SibSp", "Survived"]].groupby(['SibSp'], as_index=False).mean().sort_values(by='Survived', ascending=False)

train_df[["Parch", "Survived"]].groupby(['Parch'], as_index=False).mean().sort_values(by='Survived', ascending=False)

三种Pclass下 幸存/死亡 3*2种情况下的年龄分布图

三种Embarked下 不同性别在三种Pclass下的 幸存/死亡率图

python 复制代码
# 两个变量
grid = sns.FacetGrid(train_df, col='Survived', row='Pclass', height=2.2, aspect=1.6)
grid.map(plt.hist, 'Age', alpha=.5, bins=20)


# 三个变量
grid = sns.FacetGrid(train_df, row='Embarked', height=2.2, aspect=1.6)
grid.map(sns.pointplot, 'Pclass', 'Survived', 'Sex', palette='deep')
grid.add_legend() #图例

2. 数据清洗

一些字符串列 有的没作用 有的需要提取转换为数字形式

我们在describe中知道 Ticket是票的编号(对分类没有帮助)Cabin有很多缺失值 遂踢除

python 复制代码
train_df = train_df.drop(['Ticket', 'Cabin', 'PassengerId'], axis=1)
test_df = test_df.drop(['Ticket', 'Cabin'], axis=1)
combine = [train_df, test_df]

Name那列 只有中间的 Mr Miss 这样的中间的位置对分类有帮助 提取出来更换标签

python 复制代码
for dataset in combine:
    dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+)\.', expand=False)

pd.crosstab(train_df['Title'], train_df['Sex'])

把Title和Sex两两比对 可以分为Master Miss Mr Mrs 和 Rare 五类分别对应1~5

python 复制代码
title_map = {
    'Mr': 1,
    'Miss': 2, 'Mlle': 2, 'Ms': 2,
    'Mrs': 3, 'Mme': 3,
    'Master': 4,
    'Lady': 5, 'Countess': 5, 'Capt': 5, 'Col': 5, 'Don': 5, 
    'Dr': 5, 'Major': 5, 'Rev': 5, 'Sir': 5, 'Jonkheer': 5, 'Dona': 5
}

for dataset in combine:
    dataset['Title'] = dataset['Title'].map(title_map).astype('int8')
train_df.head()

Name 列已经转换为 Title列 ; 把Sex中的 female -> 1 male -> 0

python 复制代码
train_df = train_df.drop(['Name'], axis=1)
test_df = test_df.drop(['Name'], axis=1)
combine = [train_df, test_df]
for dataset in combine:
    dataset['Sex'] = dataset['Sex'].map( {'female': 1, 'male': 0} ).astype(int)

然后Age中还有缺失值; 可以拿全体人员的平均数填充; 也可以通过分类别填充中位数

根据Pclass 和 Sex 3*2=6类别 先对不缺失的算出中位数 再填充。

再以 16,32,48,64 为界限把连续型的年龄划分为5类

python 复制代码
# 1. 计算各分组的年龄中位数
guess_ages = np.zeros((2, 3))
for dataset in combine:
    for i in range(2):  # 性别: 0=男,1=女
        for j in range(3):  # 舱等: 1,2,3
            guess_df = dataset[(dataset['Sex'] == i) & (dataset['Pclass'] == j+1)]['Age'].dropna()
            age_guess = guess_df.median()
            guess_ages[i, j] = int(age_guess/0.5 + 0.5) * 0.5

# 2. 定义分段条件和标签
age_bins = [0, 16, 32, 48, 64, np.inf]
age_labels = [0, 1, 2, 3, 4]

# 3. 填充缺失值并分段
for dataset in combine:
    # 填充缺失值
    for i in range(2):
        for j in range(3):
            mask = (dataset['Age'].isnull()) & (dataset['Sex'] == i) & (dataset['Pclass'] == j+1)
            dataset.loc[mask, 'Age'] = guess_ages[i, j]
    
    # 年龄分段
    dataset['Age'] = pd.cut(dataset['Age'], bins=age_bins, labels=age_labels).astype(int)

# 验证结果
print("年龄分布:")
print(train_df['Age'].value_counts().sort_index())
print("\n各年龄段生存率:")
print(train_df.groupby('Age')['Survived'].mean())

SibSp 和 Parch 兄弟姐妹父母子女的信息 可以统一归类为 是否独自一个人 'IsAlone'

python 复制代码
for dataset in combine:
    dataset['IsAlone'] = 1
    dataset.loc[dataset['SibSp'] + dataset['Parch'] > 0, 'IsAlone'] = 0
train_df = train_df.drop(['Parch', 'SibSp'], axis=1)
test_df = test_df.drop(['Parch', 'SibSp'], axis=1)

Embarked 港有两个缺失值 我们可以用.mode() 得到众数填充,然后有 S C Q三类转化为0 1 2。

python 复制代码
freq_port = train_df.Embarked.dropna().mode()[0]
combine = [train_df, test_df]
for dataset in combine:
    dataset['Embarked'] = dataset['Embarked'].fillna(freq_port)
 
train_df[['Embarked', 'Survived']].groupby(['Embarked'], as_index=False).mean().sort_values(by='Survived', ascending=False)

for dataset in combine:
    dataset['Embarked'] = dataset['Embarked'].map( {'S': 0, 'C': 1, 'Q': 2} ).astype(int)

Fare 乘客花费 test中有一个缺失均值填充 -> qcut 转化为区间 划分为4类 -> 转化为0~3

python 复制代码
train_df['FareBand'] = pd.qcut(train_df['Fare'], 4)
train_df[['FareBand', 'Survived']].groupby(['FareBand'], as_index=False, observed=True).mean().sort_values(by='FareBand', ascending=True)

for dataset in combine:
    # 中位数填充缺失值
    dataset['Fare'] = dataset['Fare'].fillna(dataset['Fare'].dropna().median())
    # 然后进行分箱操作
    dataset.loc[dataset['Fare'] <= 7.91, 'Fare'] = 0
    dataset.loc[(dataset['Fare'] > 7.91) & (dataset['Fare'] <= 14.454), 'Fare'] = 1
    dataset.loc[(dataset['Fare'] > 14.454) & (dataset['Fare'] <= 31), 'Fare'] = 2
    dataset.loc[dataset['Fare'] > 31, 'Fare'] = 3
    # 转换为整数类型
    dataset['Fare'] = dataset['Fare'].astype(int)

train_df = train_df.drop(['FareBand'], axis=1)
combine = [train_df, test_df]
print(train_df.head(10))

清洗后的最终数据变成了这样 均为不超过5个类别的 0~5的整数

小结之前的操作:变成现在的8类

Survived 保持0-1死活 Pclass 为1 2 3等 Sex男女换为0-1

Age 划分了5个年龄段 Fare票价分为了4段 Embarked的Q S C三个类别转换为0 1 2

Name中称谓信息转换为5个Title Sibsp和Parch 转化为是否一个人 IsAlone

3. 模型调用与预测

先准备好训练集X_train Y_train 和测试集 X_test

python 复制代码
X_train = train_df.drop("Survived", axis=1)
Y_train = train_df["Survived"]
X_test  = test_df.drop("PassengerId", axis=1).copy()
X_train.shape, Y_train.shape, X_test.shape

LogisticRegression 逻辑回归

python 复制代码
from sklearn.linear_model import LogisticRegression
m1 = LogisticRegression()
m1.fit(X_train, Y_train)
Y_pred = m1.predict(X_test)
print(round(m1.score(X_train, Y_train) * 100, 2))

还可以输出回归中每个量的系数

python 复制代码
coeff_df = pd.DataFrame(train_df.columns.delete(0))
coeff_df.columns = ['Feature']
coeff_df["Correlation"] = pd.Series(m1.coef_[0])

coeff_df.sort_values(by='Correlation', ascending=False)

以下为一些模型的选用

python 复制代码
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC, LinearSVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import Perceptron, SGDClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier

# 创建模型列表,每个元素是(模型名称,模型实例)的元组
models = [
    ("LogisticRegression", LogisticRegression()),
    ("SVC", SVC()),
    ("KNN", KNeighborsClassifier(n_neighbors=3)),
    ("GaussianNB", GaussianNB()),
    ("Perceptron", Perceptron()),
    ("LinearSVC", LinearSVC()),
    ("SGDClassifier", SGDClassifier()),
    ("DecisionTree", DecisionTreeClassifier()),
    ("RandomForest", RandomForestClassifier(n_estimators=100))
]

results = []
for name, model in models:
    model.fit(X_train, Y_train)
    acc = round(model.score(X_train, Y_train) * 100, 2)
    results.append((name, acc))

# 输出结果:模型名称 + 准确率
results = sorted(results, key=lambda x: x[1], reverse=True)
for name, acc in results:
    print(f"{name}模型准确率: {acc}%")

我们用随机森林预测之后 进行submission文件的生成和提交

python 复制代码
model= RandomForestClassifier(n_estimators=100)
model.fit(X_train, Y_train)
Y_pred = model.predict(X_test)
submission = pd.DataFrame({
        "PassengerId": test_df["PassengerId"],
        "Survived": Y_pred
    })
submission.to_csv('submission.csv', index=False)
相关推荐
NAGNIP10 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab11 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab11 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP15 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年15 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼15 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS15 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区17 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈17 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang17 小时前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx