赞
踩
本节课程地址:实战 Kaggle 比赛:预测房价_哔哩哔哩_bilibili
本节教材地址:4.10. 实战Kaggle比赛:预测房价 — 动手学深度学习 2.0.0 documentation (d2l.ai)
本节开源代码:...>d2l-zh>pytorch>chapter_multilayer-perceptrons>kaggle-house-price.ipynb
之前几节我们学习了一些训练深度网络的基本工具和网络正则化的技术(如权重衰减、暂退法等)。 本节我们将通过Kaggle比赛,将所学知识付诸实践。 Kaggle的房价预测比赛是一个很好的起点。 此数据集由Bart de Cock于2011年收集 (链接:Ames, Iowa: Alternative to the Boston Housing Data as an End of Semester Regression Project: Journal of Statistics Education: Vol 19, No 3 (tandfonline.com)), 涵盖了2006-2010年期间亚利桑那州埃姆斯市的房价。 这个数据集是相当通用的,不会需要使用复杂模型架构。 它比哈里森和鲁宾菲尔德的波士顿房价 数据集要大得多,也有更多的特征。
本节我们将详细介绍数据预处理、模型设计和超参数选择。 通过亲身实践,你将获得一手经验,这些经验将有益数据科学家的职业成长。
在整本书中,我们将下载不同的数据集,并训练和测试模型。 这里我们(实现几个函数来方便下载数据)。 首先,我们建立字典DATA_HUB
, 它可以将数据集名称的字符串映射到数据集相关的二元组上, 这个二元组包含数据集的url和验证文件完整性的sha-1密钥。 所有类似的数据集都托管在地址为DATA_URL
的站点上。
- import hashlib
- import os
- import tarfile
- import zipfile
- import requests
-
- #@save
- DATA_HUB = dict()
- DATA_URL = 'http://d2l-data.s3-accelerate.amazonaws.com/'
下面的download
函数用来下载数据集, 将数据集缓存在本地目录(默认情况下为../data
)中, 并返回下载文件的名称。 如果缓存目录中已经存在此数据集文件,并且其sha-1与存储在DATA_HUB
中的相匹配, 我们将使用缓存的文件,以避免重复的下载。
- def download(name, cache_dir=os.path.join('..', 'data')): #@save
- """下载一个DATA_HUB中的文件,返回本地文件名"""
- assert name in DATA_HUB, f"{name} 不存在于 {DATA_HUB}"
- url, sha1_hash = DATA_HUB[name]
- os.makedirs(cache_dir, exist_ok=True)
- fname = os.path.join(cache_dir, url.split('/')[-1])
- if os.path.exists(fname):
- sha1 = hashlib.sha1()
- with open(fname, 'rb') as f:
- while True:
- data = f.read(1048576)
- if not data:
- break
- sha1.update(data)
- if sha1.hexdigest() == sha1_hash:
- return fname # 命中缓存
- print(f'正在从{url}下载{fname}...')
- r = requests.get(url, stream=True, verify=True)
- with open(fname, 'wb') as f:
- f.write(r.content)
- return fname
我们还需实现两个实用函数: 一个将下载并解压缩一个zip或tar文件, 另一个是将本书中使用的所有数据集从DATA_HUB
下载到缓存目录中。
- def download_extract(name, folder=None): #@save
- """下载并解压zip/tar文件"""
- fname = download(name)
- base_dir = os.path.dirname(fname)
- data_dir, ext = os.path.splitext(fname)
- if ext == '.zip':
- fp = zipfile.ZipFile(fname, 'r')
- elif ext in ('.tar', '.gz'):
- fp = tarfile.open(fname, 'r')
- else:
- assert False, '只有zip/tar文件可以被解压缩'
- fp.extractall(base_dir)
- return os.path.join(base_dir, folder) if folder else data_dir
-
- def download_all(): #@save
- """下载DATA_HUB中的所有文件"""
- for name in DATA_HUB:
- download(name)
Kaggle是一个当今流行举办机器学习比赛的平台, 每场比赛都以至少一个数据集为中心。 许多比赛有赞助方,他们为获胜的解决方案提供奖金。 该平台帮助用户通过论坛和共享代码进行互动,促进协作和竞争。 虽然排行榜的追逐往往令人失去理智: 有些研究人员短视地专注于预处理步骤,而不是考虑基础性问题。 但一个客观的平台有巨大的价值:该平台促进了竞争方法之间的直接定量比较,以及代码共享。 这便于每个人都可以学习哪些方法起作用,哪些没有起作用。 如果我们想参加Kaggle比赛,首先需要注册一个账户(见 下图
)。
在房价预测比赛页面(如 下图 所示)的"Data"选项卡下可以找到数据集。我们可以通过下面的网址提交预测,并查看排名:
https://www.kaggle.com/c/house-prices-advanced-regression-techniques
注意,竞赛数据分为训练集和测试集。 每条记录都包括房屋的属性值和属性,如街道类型、施工年份、屋顶类型、地下室状况等。 这些特征由各种数据类型组成。 例如,建筑年份由整数表示,屋顶类型由离散类别表示,其他特征由浮点数表示。 这就是现实让事情变得复杂的地方:例如,一些数据完全丢失了,缺失值被简单地标记为“NA”。 每套房子的价格只出现在训练集中(毕竟这是一场比赛)。 我们将希望划分训练集以创建验证集,但是在将预测结果上传到Kaggle之后, 我们只能在官方测试集中评估我们的模型。 在 上图 中,"Data"选项卡有下载数据的链接。
开始之前,我们将[使用pandas
读入并处理数据], 这是我们在 2.2节 中引入的。 因此,在继续操作之前,我们需要确保已安装pandas
。 幸运的是,如果我们正在用Jupyter阅读该书,可以在不离开笔记本的情况下安装pandas
。
- # 如果没有安装pandas,请取消下一行的注释
- # !pip install pandas
-
- %matplotlib inline
- import numpy as np
- import pandas as pd
- import torch
- from torch import nn
- from d2l import torch as d2l
为方便起见,我们可以使用上面定义的脚本下载并缓存Kaggle房屋数据集。
- DATA_HUB['kaggle_house_train'] = ( #@save
- DATA_URL + 'kaggle_house_pred_train.csv',
- '585e9cc93e70b39160e7921475f9bcd7d31219ce')
-
- DATA_HUB['kaggle_house_test'] = ( #@save
- DATA_URL + 'kaggle_house_pred_test.csv',
- 'fa19780a7b011d9b009e8bff8e99922a8ee2eb90')
我们使用pandas
分别加载包含训练数据和测试数据的两个CSV文件。
- train_data = pd.read_csv(download('kaggle_house_train'))
- test_data = pd.read_csv(download('kaggle_house_test'))
输出结果:
正在从http://d2l-data.s3-accelerate.amazonaws.com/kaggle_house_pred_train.csv下载../data/kaggle_house_pred_train.csv...
正在从http://d2l-data.s3-accelerate.amazonaws.com/kaggle_house_pred_test.csv下载../data/kaggle_house_pred_test.csv...
训练数据集包括1460个样本,每个样本80个特征和1个标签, 而测试数据集包含1459个样本,每个样本80个特征。
- print(train_data.shape)
- print(test_data.shape)
输出结果:
(1460, 81)
(1459, 80)
让我们看看[前四个和最后两个特征,以及相应标签](房价)。
print(train_data.iloc[0:4, [0, 1, 2, 3, -3, -2, -1]])
输出结果:
Id MSSubClass MSZoning LotFrontage SaleType SaleCondition SalePrice
0 1 60 RL 65.0 WD Normal 208500
1 2 20 RL 80.0 WD Normal 181500
2 3 60 RL 68.0 WD Normal 223500
3 4 70 RL 60.0 WD Abnorml 140000
我们可以看到,(在每个样本中,第一个特征是ID,) 这有助于模型识别每个训练样本。 虽然这很方便,但它不携带任何用于预测的信息。 因此,在将数据提供给模型之前,(我们将其从数据集中删除)。
- # 删除train_data的第一列ID和最后一列房价;删除test_data的第一列索引
- all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))
如上所述,我们有各种各样的数据类型。 在开始建模之前,我们需要对数据进行预处理。 首先,我们[将所有缺失的值替换为相应特征的平均值。]然后,为了将所有特征放在一个共同的尺度上, 我们(通过将特征重新缩放到零均值和单位方差来标准化数据):
其中
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。