import hashlib
import os
import tarfile
import zipfile
import requests
#这一段是用来下载数据集的————不用看
DATA_HUB = dict()
DATA_URL = 'http://d2l-data.s3-accelerate.amazonaws.com/'
def download(name, cache_dir=os.path.join('..', 'data')):
"""下载一个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
def download_extract(name, folder=None):
"""下载并解压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():
"""下载DATA_HUB中的所有文件。"""
for name in DATA_HUB:
download(name)
import numpy as np
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2l
DATA_HUB['kaggle_house_train'] = (
DATA_URL + 'kaggle_house_pred_train.csv',
'585e9cc93e70b39160e7921475f9bcd7d31219ce')
DATA_HUB['kaggle_house_test'] = (
DATA_URL + 'kaggle_house_pred_test.csv',
'fa19780a7b011d9b009e8bff8e99922a8ee2eb90')
#代码从这里开始阅读
#使用pandas读入并处理数据——读取数据并且预处理
train_data = pd.read_csv(download('kaggle_house_train'))
test_data = pd.read_csv(download('kaggle_house_test'))
#可以查看下数据的基本结构
#iloc可以查看csv文件具体内容
print(train_data.iloc[0:4, [0, 1, 2, 3, -3, -2, -1]])
#数据预处理
#pd.concat见函数解析:
all_features =pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))
#将所有缺失的值替换为相应特征的平均值。 通过将特征重新缩放到零均值和单位方差来标准化数据
#将非字符串的特征取出来放在numeric_features
numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index
#将数值特征的均值变成0方差变成1
#lambda函数见详解
all_features[numeric_features] = all_features[numeric_features].apply(
lambda x: (x - x.mean()) / (x.std()))
#将缺失值全部fill(填充)为0
all_features[numeric_features] = all_features[numeric_features].fillna(0)
#字符串特征的处理——“用one-hot编码”( pd.get_dummies)
all_features = pd.get_dummies(all_features, dummy_na=True)
# dummy_na对缺失值进行一个处理——如果有缺失值就再增加一个特征,缺失就填入1,不缺失就填入0
all_features.shape
#最后展现出来的是有331个特征,特征增加的主要原因是进行了one-hot编码(原本只有81个)
#前面是把训练集与数据集进行了统一的处理,现在我们要将其分开并且转换成tensor
n_train = train_data.shape[0] #取的是训练集中样本的个数————shape[0]取得是csv的行数
train_features = torch.tensor(all_features[:n_train].values, #all_features[:n_train].values是一个numpy的结构,现在要将其变成一个tensor
dtype=torch.float32)
test_features = torch.tensor(all_features[n_train:].values,
dtype=torch.float32)
print(train_data.SalePrice.iloc[0:2])
#reshape(-1,1)见函数详解
train_labels = torch.tensor(train_data.SalePrice.values.reshape(-1, 1),
dtype=torch.float32)
loss = nn.MSELoss() #在这里我们是一个回归的问题所于用的是均方误差
in_features = train_features.shape[1] #去特征数
#用了一个很简单的线性回归,这是一个单层的网络
def get_net():
net = nn.Sequential(nn.Linear(in_features, 1))
return net
我们更关心“相对误差” (