深度学习之房价预测——2020.3.4

     ⽐赛数据分为训练数据集和测试数据集。两个数据集都包括每栋房⼦的特征,如街道类型、建造年份、房顶类型、地下室状况等特征值。这些特征值有连续的数字、离散的标签甚⾄是缺失值“na”。只有训练数据集包括了每栋房⼦的价格,也就是标签。我们可以访问⽐赛⽹⻚,下载这些数据集。

一、导包

%matplotlib inline
import torch
import torch.nn as nn
import numpy as np
import pandas as pd
import sys
sys.path.append("..")
import d2lzh_pytorch as d2l

print(torch.__version__)
torch.set_default_tensor_type(torch.FloatTensor)

二、导入数据

# 导入数据
train_data = pd.read_csv('F:/CodeStore/DL_Pytorch/data/kaggle_house/train.csv')
test_data = pd.read_csv('F:/CodeStore/DL_Pytorch/data/kaggle_house/test.csv')

train_data.shape# 输出 (1460, 81)

test_data.shape# 输出 (1459, 80)

# 查看前4个样本的前4个特征、后2个特征和标签(SalePrice):
train_data.iloc[0:4, [0, 1, 2 , 3, -3, -2, -1]]

     输出结果:

三、预处理数据

# 合并有效特征
all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))
# 预处理数据
numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index
all_features[numeric_features] = all_features[numeric_features].apply(lambda x: (x - x.mean()) / (x.std()))
# 标准化后,每个特征的均值变为0,所以可以直接用0来替换缺失值
all_features = all_features.fillna(0)

# 将离散数值转成指示特征
# dummy_na=True将缺失值也当作合法的特征值并为其创建指示特征
all_features = pd.get_dummies(all_features, dummy_na=True)
all_features.shape

n_train = train_data.shape[0]
train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float)
test_features = torch.tensor(train_data.SalePrice.values, dtype=torch.float).view(-1, 1)

四、训练模型

# 训练模型
loss = torch.nn.MSELoss()

def get_net(feature_num):
    net = nn.Linear(feature_num, 1)
    for param in net.parameters():
        nn.init.normal_(param, mean=0, std=0.01)
    return net

     对数均⽅根误差的实现如下。

def log_rmse(net, features, labels):
    with torch.no_grad():
        # 将小于1的值设成1,使得取得对数时数值更稳定
        clipped_preds = torch.max(net(features), torch.tensor(1.0))
        rmse = torch.sqrt(2 * loss(clipped_preds.log(),labels.log()).mean())
        return rmse.item()
def train(net, train_features, train_labels, test_features, test_labels, num_epochs, learning_rate, weight_decay, batch_size):
    train_ls, test_ls = [],[]
    dataset = torch.utils.data.DataLoder(dataset, batch_size, shuffle=True)
    #这里使用了Adam算法
    optimizer = torch.optim.Adam(params=net.parameters(), lr=learning_rate, weight_decay=weight_decay)
    net = net.float()
    for epoch in range(num_epochs):
        for X, y in train_iter:
            l = loss(net(x.float()), y.float())
            optimazer.zero_grad()
            l.backward()
            optimazer.step()
            train_ls.append(log_rmse(net, test_features, test_labels))
            if test_labels is not None:
                test_ls.append(log_rmse(net, test_features, test_labels))
            return train_ls, test_ls
    

五、K折交叉验证

# K折交叉验证
def get_k_fold_data(k, i, x, y):
    assert k > 1
    fold_size = x.shape[0]
    x_train, y_train = None, None
    for j in range(k):
        idx = slice(j * fold_size, (j+1) * fold_size)
        x_part, y_part = x[idx, :],y[idx]
        if j==i:
            x_valid, y_valid = x_part, y_part
        elif x_train is None:
            x_train, y_train = x_part, y_part
        else:
            x_train = torch.cat((x_train, x_part), dim=0)
            y_train = torch.cat((y_train, y_part), dim=0)
        return x_train, y_train, x_valid, y_valid
posted @ 2020-03-04 22:50  Someday&Li  阅读(1365)  评论(0编辑  收藏  举报