第5课
从零开始构建线性模型和神经网络
- 从零开始构建表格模型
- 回顾Titanic数据集和Excel中的两个模型
- 从Excel到Python
- 笔记的干净版本
- 笔记的干净版本是什么样的?
- 熟悉Paperspace Gradient
- 如何使用jupyterlab模式而不是默认模式?
- 如何在jupyterlab模式和jupyter notebook模式之间切换?
- 学习一些有用的键盘快捷键
- 使用干净笔记可以做的事情
- 使用课程笔记的干净版本,我们应该采取哪些步骤或做哪些事情?
- 非干净版本在哪里?
- 同一个笔记可以在Kaggle和任何地方运行
- 如何检查笔记是在Kaggle上运行还是在其他地方运行?
- 如何相应地获取正确的数据及其路径?
- 库和格式设置
- 在开始之前,我们需要了解多少这些库?
- 如何使单元格中的打印结果看起来更漂亮?
- 将train.csv读取为Dataframe
- 如何以pandas dataframe格式读取和显示csv文件?
- 使用pandas查找并计数缺失数据
- 如何检查每个单元格/行中的缺失数据?
- 如何汇总每列中的缺失数据?
- 为缺失数据选择众数
- 无论分类数据还是连续数据,替换缺失数据的最常见选择是什么? 众数
- 如果一列有两个众数可用,如何选择第一个众数?
- 主动保持好奇心
- 为什么Jeremy不可能解释所用每个库的每个常用函数?
- 你应该怎么做?
- 用众数替换缺失数据
- 如何用列的众数填充缺失数据,无论是否创建新的dataframe?
- 在力所能及的范围内保持简单
- 为什么使用世界上最简单的方法来填充缺失数据?
- 这种最简单的方法大部分时间都奏效吗?
- 我们总知道复杂的方法会有帮助吗?
- 不要扔掉行或列
- 那些填充的列有时对模型来说是否重要得多?
- fastai库如何帮助找出这一点?
- 描述你的数据或列
- 如何快速概览/描述你的数据?
- 我们在描述中寻找什么?
- 在直方图中查看你的列
- 如何处理有趣的列?
- 你能通过直方图找出什么?
- 列的长尾分布是什么?它看起来像什么?
- 对长尾列进行对数变换
- 哪些模型不喜欢数据中的长尾分布? #数据描述
- 将长尾分布变成中心分布的最简单方法是什么?
- 在哪里可以找到更多关于对数和对数曲线的信息?
- 用一句话概括对数的作用是什么? 17:11
- 如何避免log(0)的问题? 加1
- 对数变换后,列数据(直方图)看起来像什么?
- 最可能是长尾数据
- 哪些类型的数据最有可能需要对数变换的长尾数据?
- 描述非数值列
- 如何描述看似数值但实际是分类的列?
- 如何一起描述所有非数值列?
- 这种描述是什么样的? (它与数值数据有何不同)
- 对分类列应用系数
- 如何对分类列应用系数?
- 对分类列应用哑变量是什么意思?
- 获取哑变量的两种方法是什么?Jeremy对此有何看法?
- 分类变量的哑变量变换是什么样的?
- 名字列的秘密力量
- 仅基于名字列构建的模型能否在Titanic比赛中获得第一名?
- 在哪里可以找到更多关于它的信息?
- 本讲座不涵盖此技术
- 张量
- 为什么侧重于pytorch而不是numpy?
- pytorch需要什么数据格式?如何进行这种数据格式转换?
- 张量是什么?它从哪里来?
- 如何将所有独立列转换为一个大型张量?
- 张量需要的数字类型是什么? float
- 如何检查张量的形状?(行数和列数)
- 如何检查张量的秩/维度/轴?秩是什么?
- 向量、表格/矩阵或零的秩是多少?
- 创建随机系数
- 为什么我们在这里不需要像Excel那样的常数项?
- 我们需要多少系数?如何计算出来?
- 如何为系数创建一个随机数向量?
- 如何使系数值中心化?为什么这很重要?(后面解答)
- 系数的复现性
- 每次运行单元格时,如何为系数创建同一组随机数?
- 何时使用和不使用随机种子来使结果复现?
- 不使用随机种子如何帮助直观地理解模型?
- 广播:数据 * 系数 在GPU上的操作
- 广播是什么?它不就是矩阵和向量乘法吗?
- 它从哪里来?
- 使用广播有什么好处?
- 简单代码 vs 大量样板代码
- 使用C语言编码和优化,用于GPU计算
- 广播的规则是什么?在哪里可以找到更多相关信息?
- 一篇帮助理解广播的好博文
- 归一化:使每列的值具有相同的范围
- 当一列的值远大于其他列的值时,会发生什么?
- 为什么要使每列数据都具有相同的值范围?
- 如何使所有列值具有相同的范围?
- 进行归一化的两种主要方法是什么?
- Jeremy更喜欢哪一种?
- 求和得到预测
- 如何将每一行与系数相乘求和,并对所有行进行此操作?
- 求和得到的结果是每个人/每行数据的预测值吗?
- 损失函数的默认选择
- 如何使模型更好? 梯度下降
- 进行梯度下降需要什么? 损失函数
- 损失函数的作用是什么? 衡量系数的性能
- Jeremy默认/最喜欢的损失函数选择是什么?
- 为什么Jeremy在实验时总是手动写出损失函数?
- 使笔记在将来可读/易懂
- 何时将所有探索性步骤封装到几个函数中?
- 为什么要保留所有这些探索性步骤(不要删除它们)?
- 在Pytorch中使用梯度下降更新系数
- 如何要求PyTorch对系数进行梯度计算?
- 如何要求Pytorch更新同一个系数张量上的值(而不是创建新的)?
- 除了给出损失值之外,损失函数还做什么?它存储了什么?
- 运行哪个函数,结合损失来计算系数的梯度?
- 如何访问系数的梯度?以及如何解释这些梯度?
- 如何决定是减去还是加上梯度到系数?
- 如何选择学习率?
- 如何使用更新后的系数计算更新后的损失?
- 划分数据集
- 为什么Jeremy为Titanic数据集随机划分了训练集和验证集?
- 为什么要使用fastai的随机划分函数?
- 如何使用划分函数创建训练集和验证集?
- 封装模型训练函数
- Jeremy如何从上面的探索性步骤创建init_coeffs, update_coeffs, one_epoch, train_model等函数?
- 如何使用train_model函数查看模型的效果如何?
- Titanic数据集是一个很好的练手场
- 为什么这么说?
- 显示系数
- 如何显示最终系数?
- 如何解释它?
- 我们能理解里面的数值吗?
- 准确率作为指标
- 为什么不使用准确率作为损失函数?
- 我们可以用准确率函数做什么?
- Jeremy对生存使用了哪个阈值?
- 如何计算准确率并将其放入函数中?
- Sigmoid函数:简化系数优化
- 从预测中看到了什么,让你想到使用sigmoid函数?
- 为什么sigmoid函数确实可以使模型的优化更容易?
- 为什么函数两端的平台期有利于优化?(容忍非常大和非常小的预测值,而不是强制每个预测值都接近1或0)
- 为什么函数图的直线中间部分也是我们想要的? 48:58
- 如何用一行代码绘制任何函数?这是哪个库? sympy
- 如何在Jupyter中轻松地使用sigmoid函数更新calc_preds函数? 50:52
- 为什么在sigmoid函数之前要使预测值中心化在0?(Jeremy的回答)
- 你记得Jeremy是如何使预测值中心化在0的吗?(参见初始系数的定义方式,Kaggle上的一个单元格链接)
- 为什么允许预测值大或小可以使权重优化更容易?(Jeremy的回答)
- Python结合Jupyter如何使探索性工作如此容易?
- 为什么学习率在使用sigmoid之前从0.1跳到使用sigmoid之后变成2? 51:57
- 何时或多久(作为规则)应该对预测使用sigmoid函数? 52:23
- HF库是否指定他们是否使用sigmoid?(可能其他库也没有)
- 现在优化时需要关注的是输入和输出,而不是中间部分。这是为什么? 53:13
- 如果测试集有额外的列怎么办?
- 正常的后果会是什么?
- fastai如何完美地处理这个问题?
- 提交到Kaggle
- Jeremy如何以及为何用0替换了Fare的缺失值?
- 如何将上述数据清洗步骤应用于测试集?
- 如何准备Kaggle期望的输出列?
- 如何创建Kaggle期望的提交文件?
从线性模型到神经网络的关键步骤
- val_indep * coeffs 与 val_indep @ coeffs 的区别
- 我们知道val_indep * coeffs 意味着什么?它是按元素相乘吗?它是矩阵和向量相乘吗?
- 我们知道val_indep @ coeffs 意味着什么?它是矩阵-矩阵乘法吗?
- (val_indep * coeffs).sum(axis=1) 等于 val_indep @ coeffs 吗?
- 我们需要了解什么才能正确区分它们?
- 在 val_indep @ coeffs 中,当 coeffs 是一个矩阵时,我们需要指定其形状吗? 59:50
- 如何将系数初始化为一个单列矩阵而不是向量?
- 将现有向量转换为矩阵
- 如何将trns_dep和vald_dep从现有向量转换为与coeffs矩阵对应的矩阵?
构建神经网络
- 使线性模型和神经网络的输出具有可比性
- 如何根据多隐藏层内部创建一个层(或者一个系数矩阵而不是系数向量)?
- 为什么将多隐藏层的系数除以层数(或将系数矩阵除以列数)?
- 这是为了确保神经网络和之前的线性模型的输出具有可比性吗?
- 构建输出层
- 如何构建与前一层连接的具有正确形状的输出层系数?
- 如何决定这个输出层的输出数量?
- 尝试启动训练
- 为什么Jeremy将输出层的系数设置为减去0.3?
- 减去0.3可以启动训练是什么意思?
- (我猜Jeremy可能先尝试了-0.5,通过实验找到的)
- 添加常数项或不添加
- 为什么第1层不需要常数项(想想线性模型的常数项)?
- 为什么第2层必须有常数项?
- 第1层、第2层系数和常数项都需要各自的梯度初始化吗?
- 构建模型
- 元组是什么?如何用它来分组和分离三个系数?
- 如何通过将数据通过第1层和第2层,最终加上常数项来构建预测函数?
- 完成了一个神经网络,但非常麻烦
- 如何在一个循环中更新所有三个系数?
- 你注意到学习率又变了吗?(1.4,上次是2,之前是0.1)
- Jeremy说让这个模型工作非常麻烦,是什么意思?
框架:无需大量手动调整的深度学习笔记
- 为什么使用框架而不是从零开始
- 为什么在现实生活中应该使用库框架,而不是像上面那样自己构建?
- 何时应该从零开始?
- 框架能为我们做什么?
- 它可以自动化一些显而易见的事情,比如初始化、学习率、哑变量、归一化等吗?
- 我还能对不那么明显的事情做出选择吗?
- 使用pandas进行特征工程
- 使用pandas进行特征工程是什么样的?
- Jeremy建议如何以及在哪里深入研究pandas?
- 准备数据集时自动化显而易见的事情
- 框架如何自动化分类数据、填充缺失数据和归一化?
- 如何指定依赖列为类别?
- 用一行代码构建多隐藏层
- 如何只用两个数字指定两个隐藏层的形状?
- 你只需要指定准确率,而无需担心损失和激活函数吗?
- 自动化最佳学习率搜索
- fastai如何帮助你找到最佳学习率所在的范围?
- 你应该如何从该范围中选择学习率?
轻松预测和提交
- 用一行代码自动化测试集的转换
- 如何自动将对训练集和验证集完成的所有转换应用于测试集?
尝试集成
- 使用fastai进行集成很容易
- 框架是否节省了大量的调整工作,从而使尝试一些高级想法变得更容易?
- 集成是什么?
- 它是结合多个模型并组合它们的预测吗?
- 最简单的集成
- 一个简单的集成是什么样的?
- 如何轻松地构建、运行和预测5个模型?
- 这5个模型有多大区别?(只有初始系数不同)
- 如何组合它们的预测?
- 这个简单的集成能带来多少改进?
- 组合预测的方法
- 为什么不用众数而用均值?
- 组合预测的3种方法是什么?
- 其中一种比其他方法更好吗?
- Jeremy的建议是什么?
随机森林的实际工作原理
- 这里也是学习pandas和numpy的好地方吗?
- 为什么选择随机森林
- 随机森林和Jeremy的历史是什么?
- Jeremy对随机森林的看法是什么?
- 为什么随机森林如此简单且更好?
- 为什么看似简单的逻辑回归却很容易出错?
- pandas分类函数
- 如何一次性导入所有需要的库?
- 如何使用pandas进行fillna,使用numpy进行对数运算?
- panda分类函数为我们做了什么?
- 应用函数后的友好显示是什么?
- 底层实际的数据转换是什么?
- 需要强调的关键点:没有哑变量,Pclass不再需要被视为分类变量
- 二分分裂:随机森林的基础
- 基于性别的二分分裂
- 使用sklearn构建基于性别的二分分裂模型
- 使用sklearn构建基于票价的二分分裂模型
- 构建一个基于二分分裂(无论分类或连续)的评分机器
- 什么是一个好的分裂?
- 在每个组内,它们的依赖值相似是好的吗?
- 如何衡量组内值的相似性? std
- 如何适当地比较两组的标准差?(乘以组大小)
- 如何根据两组合并标准差的值计算评估分裂的得分?
- 自动化所有列的评分机器
- 如何通过尝试一列所有可能的分裂点来找到最佳二分分裂?
- 1R模型作为基线
- 随机森林是什么?随机森林又是什么?
- 1R模型是什么?
- 在90年代的机器学习世界里,它有多好?
- 我们总是应该追求复杂的模型吗?
- 对于我们的问题,我们总是应该从1r模型作为基线模型开始吗?