DAY 22 复习日
复习日
仔细回顾一下之前21天的内容,没跟上进度的同学补一下进度。
作业:
自行学习参考如何使用kaggle平台,写下使用注意点,并对下述比赛提交代码
一、Kaggle 基础使用步骤
注册与登录
- 访问 Kaggle 官网 ,通过 Google 账号或邮箱注册。
- 验证邮箱后完成账户激活。
熟悉界面
- Competitions(竞赛):参与数据科学竞赛,赢取奖金或提升技能。
- Datasets(数据集):搜索或上传公开数据集。
- Notebooks(代码笔记本):基于 Jupyter Notebook 的在线编程环境,支持 Python/R。
- Discussions(论坛):与社区交流问题或分享经验。
创建/运行 Notebook
- 点击
New Notebook
创建代码环境,支持 GPU/TPU 加速。 - 挂载数据集:通过
Add Data
添加数据集到 Notebook。
- 点击
提交竞赛结果
- 在竞赛页面下载数据,训练模型后生成预测结果文件(如 CSV)。
- 通过竞赛页面的
Submit Predictions
上传结果,查看排名。
二、使用注意点
1. 数据隐私与合规
- 避免敏感数据:上传数据集时,确保不包含个人信息或受版权保护的内容。
- 竞赛数据保密:禁止在竞赛期间将数据集分享到外部平台。
2. 资源限制
- GPU/TPU 使用:免费账户每周有约 30 小时的 GPU 和 20 小时的 TPU 配额,超限后需等待重置。
- 会话时长:Notebook 无操作 20 分钟后会自动停止,需手动重启。
- 存储限制:每个 Notebook 最大存储 20GB(含数据集)。
3. 代码与 Notebook 优化
- 依赖安装:在 Notebook 中通过
!pip install
安装库时,建议在代码开头一次性安装。 - 开启 GPU:在 Notebook 设置中手动启用 GPU/TPU,否则默认使用 CPU。
- 数据路径:挂载数据集后,数据路径通常为
/kaggle/input/[数据集名称]/
。 - 版本保存:定期点击
Save Version
备份代码,避免丢失进度。
4. 竞赛注意事项
- 规则阅读:仔细阅读竞赛规则,避免因提交格式错误或违规被取消资格。
- 团队合作:允许组队参赛,但需在提交前合并团队。
- 公平性:禁止多账号刷分或使用非公开数据。
5. 社区互动
- 提问技巧:在论坛提问时,提供清晰的背景、代码错误信息和尝试过的解决方法。
- 引用来源:使用他人代码或数据时,注明来源并遵守许可证(如 CC0、MIT 等)。
6. 性能与效率
- 大数据处理:使用
pandas
时优先选择分块读取(chunksize
)或高效格式(如parquet
)。 - 内存管理:避免在 Notebook 中加载超大数据,可使用
dtype
优化或del
释放内存。 - 缓存中间结果:将预处理后的数据保存为文件,减少重复计算。
三、其他实用技巧
- 学习资源:利用 Kaggle Learn(短期免费课程)和公开 Notebook 学习模型构建技巧。
- Kaggle API:通过命令行工具批量下载数据集或提交结果(需生成 API Token)。
- 参与社区活动:关注 Kernels(优质代码)、Datasets 和 Discussions 的 Trending 内容,学习最新方法。
常见问题解决
- 数据集加载失败:检查路径是否正确,或通过
ls /kaggle/input
查看已挂载数据。 - GPU 未生效:在 Notebook 设置中确认已开启 GPU,并检查是否安装了 GPU 版本的库(如
tensorflow-gpu
)。 - 内存不足:减少批量大小(batch size)或使用更轻量级的模型。
Kaggle 的比赛如何运作
- 加入比赛
阅读挑战赛描述,接受比赛规则并访问比赛数据集。 - 开始工作
下载数据,在本地或 Kaggle Notebooks(我们的免设置、可自定义的 Jupyter Notebooks 环境,带有免费 GPU)上构建模型,并生成预测文件。 - 提交 将您的预测作为提交
上传到 Kaggle 并获得准确率分数。 - 查看排行榜
查看您的模型在我们的排行榜上与其他 Kaggler 的排名。 - 提高你的分数
查看论坛,找到来自其他竞争对手的大量教程和见解。
本次挑战——泰坦尼克号 - 从灾难中学习机器学习
泰坦尼克号的沉没是历史上最臭名昭著的沉船事件之一。
1912 年 4 月 15 日,在她的处女航中,被广泛认为“永不沉没”的 RMS 泰坦尼克号在与冰山相撞后沉没。不幸的是,船上的每个人都没有足够的救生艇,导致 1502 名乘客和船员中有 2224 人死亡。
虽然生存下来有一些运气因素,但似乎某些群体比其他人更有可能生存下来。
在本次挑战赛中,我们要求您构建一个预测模型,使用乘客数据(即姓名、年龄、性别、社会经济阶层等)回答“什么样的人更有可能生存”这个问题。
我将在本次比赛中使用哪些数据?
在本次比赛中,您将可以访问两个类似的数据集,其中包括乘客信息,如姓名、年龄、性别、社会经济阶层等。一个数据集的标题为,另一个数据集的标题为 。train.csv
test.csv
Train.csv
将包含机上乘客子集(准确地说是 891 人)的详细信息,重要的是,将揭示他们是否幸存,也称为“基本事实”。
该数据集包含类似的信息,但没有透露每位乘客的 “真实情况”。预测这些结果是你的工作。test.csv
使用您在数据中找到的模式,预测机上其他 418 名乘客(在 中找到)是否幸存下来。train.csv
test.csv
查看 “Data” 选项卡以进一步探索数据集。一旦您认为您已经创建了一个有竞争力的模型,请将其提交给 Kaggle,以查看您的模型在我们的排行榜上与其他 Kaggler 的排名。
数据集描述
概述
数据已分为两组:
- 训练集 (train.csv)
- 测试集 (test.csv)
训练集应用于构建机器学习模型。对于训练集,我们提供每位乘客的结果(也称为“真实值”)。您的模型将基于乘客的性别和舱位等“特征”。您还可以使用特征工程来创建新特征。
应该使用测试集来查看模型在看不见的数据上的表现。对于测试集,我们不会提供每位乘客的 Ground Truth。预测这些结果是你的工作。对于测试集中的每个乘客,使用您训练的模型来预测他们是否在泰坦尼克号沉没后幸存下来。
我们还包括 gender_submission.csv,这是一组假设所有且只有女性乘客幸存的预测,作为提交文件应该是什么样子的示例。
数据字典
变量 | 定义 | 钥匙 |
---|---|---|
生存 | 生存 | 0 = 否,1 = 是 |
p类 | 机票舱位 | 1 = 第 1 个,2 = 第 2 个,3 = 第 3 个 |
性 | 性 | |
年龄 | 年龄(岁) | |
国际生物安全指数 | # 泰坦尼克号上的兄弟姐妹/配偶 | |
帕奇 | # 泰坦尼克号上的父母/孩子 | |
票 | 票号 | |
票价 | 乘客票价 | |
舱 | 舱位号 | |
登船 | 登船港口 | C = 瑟堡,Q = 皇后镇,S = 南安普敦 |
变量注释
pclass:社会经济地位 (SES)
的代理 1st = 上
2nd = 中
3rd = 下
年龄:如果年龄小于 1,则年龄为分数。如果年龄是估计的,是不是以 xx.5
sibsp 的形式:数据集是这样定义家庭关系的......
兄弟姐妹 = 兄弟、姐妹、继兄弟、继姐妹
配偶 = 丈夫、妻子(情妇和未婚夫被忽略)
parch:数据集以这种方式定义家庭关系......
父母 = 母亲,父亲
孩子 = 女儿、儿子、继女、继子
有些孩子只与保姆一起旅行,因此他们 parch=0。
具体步骤
总览
[加载数据] → [预处理] → [特征工程] → [训练模型]
↓ ↑
[获取已训练预处理器] → [提取特征名称] → [合并分析]
具体代码
1. 环境准备
# ========== 1. 环境准备 ==========
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split, GridSearchCV, StratifiedKFold
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import OneHotEncoder, RobustScaler
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from imblearn.over_sampling import SMOTE
from imblearn.pipeline import make_pipeline as imb_make_pipeline
import warnings
warnings.filterwarnings('ignore')
2. 数据加载与清洗
# ========== 2. 数据加载与清洗 ==========
def load_data(path):
"""加载并初步处理数据"""
df = pd.read_csv(path)
# 删除无关特征 [改进1:增加特征删除说明]
df.drop(['PassengerId', 'Name', 'Ticket', 'Cabin'], axis=1, inplace=True)
return df
train = load_data('train.csv')
test = load_data('test.csv')
3. 数据预处理管道
# ========== 3. 数据预处理管道 ==========
# [改进2:增加鲁棒缩放器]
cat_features = ['Sex', 'Embarked']
num_features = ['Pclass', 'Age', 'SibSp', 'Parch', 'Fare']
preprocessor = ColumnTransformer(
transformers=[
('num', Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('scaler', RobustScaler()) # 新增特征缩放
]), num_features),
('cat', Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')),
('encoder', OneHotEncoder(handle_unknown='ignore'))
]), cat_features)
])
4. 特征工程增强
# ========== 4. 特征工程增强 ==========
def feature_engineering(df):
"""自定义特征工程 [改进3:增加新特征]"""
# 基础特征
df['FamilySize'] = df['SibSp'] + df['Parch'] + 1
df['IsAlone'] = (df['FamilySize'] == 1).astype(int)
# 新增票价分段特征
df['FareCategory'] = pd.cut(df['Fare'],
bins=[0, 10, 50, 100, 600],
labels=[0, 1, 2, 3]).astype(float)
# 新增年龄分段特征
df['AgeGroup'] = pd.cut(df['Age'],
bins=[0, 12, 18, 60, 100],
labels=['Child', 'Teen', 'Adult', 'Elderly']).astype(object)
return df
train = feature_engineering(train)
test = feature_engineering(test)
5. 数据集划分策略优化
# ========== 5. 数据集划分策略优化 ==========
# [改进4:使用分层抽样]
X = train.drop('Survived', axis=1)
y = train['Survived']
X_train, X_val, y_train, y_val = train_test_split(
X, y,
test_size=0.2,
stratify=y, # 新增分层抽样
random_state=42
)
6. 构建增强管道
# ========== 6. 构建增强管道 ==========
# [改进5:优化网格搜索参数]
pipeline = imb_make_pipeline(
preprocessor,
SMOTE(random_state=42),
RandomForestClassifier(random_state=42)
)
param_grid = {
'randomforestclassifier__n_estimators': [100, 200, 300], # 扩展参数范围
'randomforestclassifier__max_depth': [5, 7, 9, None],
'randomforestclassifier__min_samples_split': [2, 3, 5],
'randomforestclassifier__max_features': ['sqrt', 'log2'], # 新增参数
'smote__k_neighbors': [3, 5] # 优化SMOTE参数
}
7. 模型训练与调参优化
# ========== 7. 模型训练与调参优化 ==========
# [改进6:使用分层交叉验证]
grid_search = GridSearchCV(
estimator=pipeline,
param_grid=param_grid,
scoring='f1',
cv=StratifiedKFold(n_splits=5, shuffle=True, random_state=42), # 优化交叉验证
n_jobs=-1,
verbose=1 # 新增训练过程显示
)
grid_search.fit(X_train, y_train)
8. 模型评估增强
# ========== 8. 模型评估增强 ==========
best_model = grid_search.best_estimator_
val_pred = best_model.predict(X_val)
print("\n=== 最优参数 ===")
print(grid_search.best_params_)
print("\n=== 验证集评估 ===")
print(f"准确率: {accuracy_score(y_val, val_pred):.2f}")
print(f"精确率: {precision_score(y_val, val_pred):.2f}")
print(f"召回率: {recall_score(y_val, val_pred):.2f}")
print(f"F1分数: {f1_score(y_val, val_pred):.2f}")
9. 测试集处理
# ========== 9. 测试集处理 ==========
# [改进7:确保测试集处理一致性]
test_passenger_ids = pd.read_csv('test.csv')['PassengerId']
test_pred = best_model.predict(test)
10. 结果保存与特征分析
# ========== 10. 结果保存与特征分析 ==========
submission = pd.DataFrame({
'PassengerId': test_passenger_ids,
'Survived': test_pred
})
submission.to_csv('titanic_submission.csv', index=False)
# 特征重要性分析(修正版)
try:
# 获取训练好的预处理器
fitted_preprocessor = best_model.named_steps['columntransformer']
# 数值特征(包含新增特征)
num_feats = num_features + ['FamilySize', 'IsAlone', 'FareCategory']
# 分类特征编码后的名称
cat_pipeline = fitted_preprocessor.named_transformers_['cat']
encoded_cat_feats = cat_pipeline.named_steps['encoder'].get_feature_names_out(cat_features)
# 合并所有特征名称
all_feature_names = np.concatenate([num_feats, encoded_cat_feats])
# 获取重要性
importances = best_model.named_steps['randomforestclassifier'].feature_importances_
# 创建DataFrame
importance_df = pd.DataFrame({
'Feature': all_feature_names,
'Importance': importances
}).sort_values('Importance', ascending=False)
print("\n=== 特征重要性 Top 10 ===")
print(importance_df.head(10))
except Exception as e:
print(f"特征分析失败: {str(e)}")
print("可能原因:")
print("- sklearn版本过低(需>=1.0),请升级:pip install --upgrade scikit-learn")
print("- 预处理器未正确训练")
print("\n=== 提交文件已生成 ===")
最终提交
您的提交应为包含 418 行和标题的 CSV 文件。您可以上传 zip/gz/7z 存档。