Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
CoolBran
d2l-zh
提交
80648bf9
D
d2l-zh
项目概览
CoolBran
/
d2l-zh
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
d2l-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
80648bf9
编写于
4月 14, 2021
作者:
G
goldmermaid
提交者:
GitHub
4月 14, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Revert "[slides] kaggle (#742)"
This reverts commit
dafe60db
.
上级
dafe60db
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
16 addition
and
15 deletion
+16
-15
chapter_multilayer-perceptrons/kaggle-house-price.md
chapter_multilayer-perceptrons/kaggle-house-price.md
+16
-15
未找到文件。
chapter_multilayer-perceptrons/kaggle-house-price.md
浏览文件 @
80648bf9
...
...
@@ -7,7 +7,7 @@
## 下载和缓存数据集
在整本书中,我们将在各种下载的数据集上训练和测试模型。在这里,我们
(
**实现几个函数来方便下载数据**
)
。首先,我们维护字典
`DATA_HUB`
,其将数据集名称的字符串映射到数据集相关的二元组上,这个二元组包含数据集的url和验证文件完整性的sha-1密钥。所有这样的数据集都托管在地址为
`DATA_URL`
的站点上。
在整本书中,我们将在各种下载的数据集上训练和测试模型。在这里,我们
实现了几个实用函数来方便下载数据
。首先,我们维护字典
`DATA_HUB`
,其将数据集名称的字符串映射到数据集相关的二元组上,这个二元组包含数据集的url和验证文件完整性的sha-1密钥。所有这样的数据集都托管在地址为
`DATA_URL`
的站点上。
```
{.python .input}
#@tab all
...
...
@@ -93,7 +93,7 @@ def download_all(): #@save
注意,竞赛数据分为训练集和测试集。每条记录都包括房屋的属性值和属性,如街道类型、施工年份、屋顶类型、地下室状况等。这些特征由各种数据类型组成。例如,建筑年份由整数表示,屋顶类型由离散类别表示,其他特征由浮点数表示。这就是现实让事情变得复杂的地方:例如,一些数据完全丢失了,缺失值被简单地标记为“NA”。每套房子的价格只出现在训练集中(毕竟这是一场比赛)。我们将希望划分训练集以创建验证集,但是在将预测结果上传到Kaggle之后,我们只能在官方测试集中评估我们的模型。在 :numref:
`fig_house_pricing`
中,"Data"选项卡有下载数据的链接。
开始之前,我们将
[
**使用`pandas`读入并处理数据**
]
,这是我们在 :numref:
`sec_pandas`
中引入的。因此,在继续操作之前,您需要确保已安装
`pandas`
。幸运的是,如果你正在用Jupyter阅读该书,你可以在不离开笔记本的情况下安装
`pandas`
。
开始之前,我们将
使用
`pandas`
读入并处理数据
,这是我们在 :numref:
`sec_pandas`
中引入的。因此,在继续操作之前,您需要确保已安装
`pandas`
。幸运的是,如果你正在用Jupyter阅读该书,你可以在不离开笔记本的情况下安装
`pandas`
。
```
{.python .input}
# 如果pandas没有被安装,请取消下一句的注释。
...
...
@@ -161,14 +161,14 @@ print(train_data.shape)
print(test_data.shape)
```
让我们看看
[
**前四个和最后两个特征,以及相应标签(房价)**
]
。
让我们看看
前四个和最后两个特征,以及前四个样本的标签(房价)
。
```
{.python .input}
#@tab all
print(train_data.iloc[0:4, [0, 1, 2, 3, -3, -2, -1]])
```
我们可以看到,
[
**在每个样本中,第一个特征是ID,**
]这有助于模型识别每个训练样本。虽然这很方便,但它不携带任何用于预测的信息。因此,在将数据提供给模型之前,[
**我们将其从数据集中删除**
]
。
我们可以看到,
在每个样本中,第一个特征是ID,这有助于模型识别每个训练样本。虽然这很方便,但它不携带任何用于预测的信息。因此,在将数据提供给模型之前,我们将其从数据集中删除
。
```
{.python .input}
#@tab all
...
...
@@ -177,7 +177,7 @@ all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))
## 数据预处理
如上所述,我们有各种各样的数据类型。在开始建模之前,我们需要对数据进行预处理。让我们从数字特征开始。首先,我们应用启发式方法,
[
**将所有缺失的值替换为相应特征的平均值。**
]然后,为了将所有特征放在一个共同的尺度上,我们(
**通过将特征重新缩放到零均值和单位方差来*标准化*数据**
)
:
如上所述,我们有各种各样的数据类型。在开始建模之前,我们需要对数据进行预处理。让我们从数字特征开始。首先,我们应用启发式方法,
将所有缺失的值替换为相应特征的平均值。然后,为了将所有特征放在一个共同的尺度上,我们通过将特征重新缩放到零均值和单位方差来
*标准化*
数据
:
$$x
\l
eftarrow
\f
rac{x -
\m
u}{
\s
igma}.$$
...
...
@@ -192,7 +192,7 @@ all_features[numeric_features] = all_features[numeric_features].apply(
all_features[numeric_features] = all_features[numeric_features].fillna(0)
```
接下来,我们
[
**处理离散值。**
]这包括诸如“MSZoning”之类的特征。(
**我们用一次独热编码替换它们**
)
,方法与前面将多类别标签转换为向量的方式相同(请参见 :numref:
`subsec_classification-problem`
)。例如,“MSZoning”包含值“RL”和“Rm”。将创建两个新的指示器特征“MSZoning_RL”和“MSZoning_RM”,其值为0或1。根据独热编码,如果“MSZoning”的原始值为“RL”,则:“MSZoning_RL”为1,“MSZoning_RM”为0。
`pandas`
软件包会自动为我们实现这一点。
接下来,我们
处理离散值。这包括诸如“MSZoning”之类的特征。我们用一次独热编码替换它们
,方法与前面将多类别标签转换为向量的方式相同(请参见 :numref:
`subsec_classification-problem`
)。例如,“MSZoning”包含值“RL”和“Rm”。将创建两个新的指示器特征“MSZoning_RL”和“MSZoning_RM”,其值为0或1。根据独热编码,如果“MSZoning”的原始值为“RL”,则:“MSZoning_RL”为1,“MSZoning_RM”为0。
`pandas`
软件包会自动为我们实现这一点。
```
{.python .input}
#@tab all
...
...
@@ -201,7 +201,7 @@ all_features = pd.get_dummies(all_features, dummy_na=True)
all_features.shape
```
你可以看到,此转换会将特征的数量从79个增加到331个。最后,通过
`values`
属性,我们可以
[
**从`pandas`格式中提取NumPy格式,并将其转换为张量表示**
]
用于训练。
你可以看到,此转换会将特征的数量从79个增加到331个。最后,通过
`values`
属性,我们可以
从
`pandas`
格式中提取NumPy格式,并将其转换为张量表示
用于训练。
```
{.python .input}
#@tab all
...
...
@@ -212,7 +212,7 @@ train_labels = d2l.tensor(
train_data.SalePrice.values.reshape(-1, 1), dtype=d2l.float32)
```
##
[**训练**]
##
训练
首先,我们训练一个带有损失平方的线性模型。毫不奇怪,我们的线性模型不会让我们在竞赛中获胜,但线性模型提供了一种健全性检查,以查看数据中是否存在有意义的信息。如果我们在这里不能做得比随机猜测更好,那么我们很可能存在数据处理错误。如果一切顺利,线性模型将作为基线模型,让我们直观地知道简单的模型离报告最好的模型有多近,让我们感觉到我们应该从更酷炫的模型中获得多少收益。
...
...
@@ -247,9 +247,9 @@ def get_net():
return net
```
对于房价,就像股票价格一样,我们关心的是相对数量,而不是绝对数量。因此,
[
**我们更关心相对误差$\frac{y - \hat{y}}{y}$,**
]
而不是绝对误差$y -
\h
at{y}$。例如,如果我们在俄亥俄州农村地区估计一栋房子的价格时,我们的预测偏差了10万美元,在那里一栋典型的房子的价值是12.5万美元,那么我们可能做得很糟糕。另一方面,如果我们在加州豪宅区的预测出现了这个数字的偏差,这可能是一个惊人的准确预测(在那里,房价均值超过400万美元)。
对于房价,就像股票价格一样,我们关心的是相对数量,而不是绝对数量。因此,
我们更关心相对误差$
\f
rac{y -
\h
at{y}}{y}$,
而不是绝对误差$y -
\h
at{y}$。例如,如果我们在俄亥俄州农村地区估计一栋房子的价格时,我们的预测偏差了10万美元,在那里一栋典型的房子的价值是12.5万美元,那么我们可能做得很糟糕。另一方面,如果我们在加州豪宅区的预测出现了这个数字的偏差,这可能是一个惊人的准确预测(在那里,房价均值超过400万美元)。
(
**解决这个问题的一种方法是用价格预测的对数来衡量差异**
)
。事实上,这也是比赛中官方用来评价提交质量的误差指标。即将 $
\d
elta$ for $|
\l
og y -
\l
og
\h
at{y}|
\l
eq
\d
elta$转换为$e^{-
\d
elta}
\l
eq
\f
rac{
\h
at{y}}{y}
\l
eq e^
\d
elta$。这使得预测价格的对数与真实标签价格的对数之间出现以下均方根误差:
解决这个问题的一种方法是用价格预测的对数来衡量差异
。事实上,这也是比赛中官方用来评价提交质量的误差指标。即将 $
\d
elta$ for $|
\l
og y -
\l
og
\h
at{y}|
\l
eq
\d
elta$转换为$e^{-
\d
elta}
\l
eq
\f
rac{
\h
at{y}}{y}
\l
eq e^
\d
elta$。这使得预测价格的对数与真实标签价格的对数之间出现以下均方根误差:
$$
\s
qrt{
\f
rac{1}{n}
\s
um_{i=1}^n
\l
eft(
\l
og y_i -
\l
og
\h
at{y}_i
\r
ight)^2}.$$
...
...
@@ -279,7 +279,8 @@ def log_rmse(y_true, y_pred):
tf.math.log(y_true), tf.math.log(clipped_preds))))
```
与前面的部分不同,[
**我们的训练函数将借助Adam优化器**
](我们将在后面更详细地描述它)。这个优化器的主要吸引力在于,尽管在提供无限资源进行超参数优化方面没有做得更好(有时更差),但人们发现它对初始学习率不那么敏感。
与前面的部分不同,我们的训练函数将依赖于Adam优化器(我们将在后面更详细地描述它)。这个优化器的主要吸引力在于,尽管在提供无限资源进行超参数优化方面没有做得更好(有时更差),但人们发现它对初始学习率不那么敏感。
```
{.python .input}
def train(net, train_features, train_labels, test_features, test_labels,
...
...
@@ -346,7 +347,7 @@ def train(net, train_features, train_labels, test_features, test_labels,
return train_ls, test_ls
```
##
[**$K$折交叉验证**]
##
$K$折交叉验证
你可能还记得,我们在讨论模型选择的部分( :numref:
`sec_model_selection`
)中介绍了$K$折交叉验证。这有助于模型选择和超参数调整。我们首先需要一个函数,在$K$折交叉验证过程中返回第$i$折的数据。它选择第$i$个切片作为验证数据,其余部分作为训练数据。注意,这并不是处理数据的最有效方法,如果我们的数据集大得多,我们肯定会做一些更聪明的改变。但是这种改变所增加的复杂性可能会使代码看起来更乱。在这里可以忽略这些改变,因为我们的问题很简单。
...
...
@@ -369,7 +370,7 @@ def get_k_fold_data(k, i, X, y):
return X_train, y_train, X_valid, y_valid
```
当我们在$K$折交叉验证中训练$K$次后,
[
**返回训练和验证误差的平均值**
]
。
当我们在$K$折交叉验证中训练$K$次后,
返回训练和验证误差的平均值
。
```
{.python .input}
#@tab all
...
...
@@ -392,7 +393,7 @@ def k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay,
return train_l_sum / k, valid_l_sum / k
```
##
[**模型选择**]
##
模型选择
在本例中,我们选择了一组未调优的超参数,并将其留给读者来改进模型。找到一个好的选择可能需要时间,这取决于一个人优化了多少变量。有了足够大的数据集和合理设置的超参数,$K$折交叉验证往往对多次测试具有相当的适应性。然而,如果我们尝试了不合理的大量选项,我们可能会发现验证效果不再代表真正的误差。
...
...
@@ -407,7 +408,7 @@ print(f'{k}-折验证: 平均训练log rmse: {float(train_l):f}, '
请注意,有时一组超参数的训练误差可能非常低,但$K$折交叉验证的误差要高得多。这表明我们过拟合了。在整个训练过程中,你将希望监控训练误差和验证误差这两个数字。较少的过拟合可能表明现有数据可以支撑一个更强大的模型。较大的过拟合可能意味着我们可以通过正则化技术来获益。
##
[**提交你的Kaggle预测**]
##
提交Kaggle的预测
既然我们知道应该选择什么样的超参数,我们不妨使用所有数据对其进行训练(而不是仅使用交叉验证中使用的$1-1/K$的数据)。然后,我们通过这种方式获得的模型可以应用于测试集。将预测保存在csv文件中可以简化将结果上传到Kaggle的过程。
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录