【深度学习】Kaggle房价预测总结回顾

0.导包

        导入本次比赛所需要用到所有包。

import numpy as np
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2l

1.获取数据

        先从Kaggle上下载对应的数据包(trian和test),然后利用pd.read_csv读取所需要的数据信息。

train_data = pd.read_csv("C:\\Users\\97332\\Desktop\\kaggle数据集\\house_datas\\house_train.csv")
test_data = pd.read_csv("C:\\Users\\97332\\Desktop\\kaggle数据集\\house_datas\\house_test.csv")

2.数据清洗(处理数据)

2.1合并特征

        把训练集和测试集的特征全部取出来,并去掉“Id”和训练集里的“label”。

all_features = pd.concat((train_data.iloc[:,1:-1],test_data.iloc[:,1:]))

2.2数据处理

        在本次比赛中,决定房子最终售价的因素有很多,数据表格中有数值,类别等等,所以在建立我们的训练模型之前,我们需要对数据进行预处理。

        对于数值类的特征,我们统一将其缩放为零均值和单位方差来标准化数据。缺失值用0来代替。

        对于文本类别的特征,采用one-hot编码将其转变为数值变量。缺失值利用“Dummy_na = True”将缺失值视为有效的特征值,并为其创建指示符特征。【这里我还不太理解,就是感觉用了这个就可以把缺失值处理好了】

#把全部特征中的数字特征提取出来
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补全
all_features[numeric_features] = all_features[numeric_features].fillna(0)
#处理文本类的那些离散值和缺失值
all_features = pd.get_dummies(all_features,dummy_na= True)

2.3修改数据类型

        把训练特征值,训练目标值以及测试特征值的数据从Pandas格式中提取Numpy格式,并将其转换为张量(Tensor)表示用于训练。

num_train = train_data.shape[0]
train_features = torch.tensor(all_features[:num_train].values,dtype = torch.float32)
test_features = torch.tensor(all_features[num_train:].values,dtype = torch.float32)
train_labels = torch.tensor(train_data.SalePrice.values.reshape(-1,1),dtype = torch.float32)

3.建立训练模型

        我们所建立的模型,主要包括两点:1.损失函数——用于对比预测值和真实值,从而对我们的权重和偏差进行更新。2.用什么样的一个模型来装我们所要训练的特征值(输入)。

#损失函数,用nn自带的MSELoss
loss = nn.MSELoss()

#Sequential是一个特殊的容器,这里的代码指的是容器里就只有一个线性回归层用于训练
def get_net():
    net = nn.Sequential(nn.Linear(test_features.shape[1],1))
    return net

4.设定误差算法

        对于我们最后训练出来的模型,我们需要有一个标准去衡量这个模型到底是训练的好还是坏。在这里采用价格预测的对数来衡量差异(Kaggle也用的这个方法哦)。

#返回一个模型的误差(高精度)
def log_rmse(net, features, labels):
    clipped_preds = torch.max(net(features), torch.tensor(1.0))
    rmse = torch.sqrt(loss(clipped_preds.log(), labels.log()))
    return rmse.item()

5.训练方法的设定

        模型:神经网络(net)

        训练内容:训练集特征(train_features)、训练集标签(train_labels)、测试集特征(test_features)、测试集标签(test_labels)

        参数:训练周期(num_epochs)、学习率(learning_rate)、权重衰减(weight_decay)、单次数据大小(batch_size)

        将训练误差和测试误差先设为0(这里就是空集合),按设定好的batch_size大小将数据集传入train_iter中,然后利用Adam优化算法(一种平滑的SGD)对数据进行更新。利用损失,梯度求导不断更新权重和偏差。最后将训练好的模型进行误差计算输出。

#返回训练集的误差和测试集误差
def train(net, train_features, train_labels, test_features, test_labels,
          num_epochs, learning_rate, weight_decay, batch_size):
    train_ls, test_ls = [], []
    train_iter = d2l.load_array((train_features,train_labels),batch_size)
    # 这里使用了Adam优化算法
    optimizer = torch.optim.Adam(params=net.parameters(), lr=learning_rate, weight_decay=weight_decay) 
    for epoch in range(num_epochs):
        for X, y in train_iter:
            optimizer.zero_grad()
            l = loss(net(X), y)
            l.backward()
            optimizer.step()
        train_ls.append(log_rmse(net, train_features, train_labels))
        if test_labels is not None:
            test_ls.append(log_rmse(net, test_features, test_labels))
    return train_ls, test_ls

6.K折交叉验证

6.1设定划分比例

        这里写的算法逻辑我实在没有看懂(看视频的时候大家都说沐沐大神的代码写的太漂亮了),最后反正就返回了当前这一折的训练集和验证集。

def get_k_fold_data(k, i, X, y):
    # 返回第i折交叉验证时所需要的训练和验证数据
    assert k > 1
    fold_size = X.shape[0] // k
    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

6.2计算每折的误差并求平均

        划分好了训练集和验证集之后,就利用之前设定好的模型对每一折的训练集和验证集进行训练,最后分别计算训练集和验证集的误差平均值。

        值得一提的是,我们这里最关注的还是平均验证误差。

#返回k折训练集误差的均值和k折验证集误差的均值
def k_fold(k, X_train, y_train, num_epochs,learning_rate, weight_decay, batch_size):
    train_l_sum, valid_l_sum = 0, 0
    for i in range(k):
        data = get_k_fold_data(k, i, X_train, y_train)
        net = get_net()
        train_ls, valid_ls = train(net, *data, num_epochs, learning_rate,weight_decay, batch_size)
        train_l_sum += train_ls[-1]
        valid_l_sum += valid_ls[-1]
        print(f"折{i+1}:训练误差:{float(train_ls[-1]):f}," f"验证误差:{float(valid_ls[-1]):f}")
    return train_l_sum / k, valid_l_sum / k

7.实例化模型训练

7.1利用K折交叉验证调整参数

        这一步,我们需要确定上述定义模型中的那些超参数具体要取值多少(这些超参数的取值就决定了你模型的精度)。然后根据所得到的误差值我们又反过去调整超参数的设置,直至调至自己觉得最优的结果,此时所设定的超参数就是本次模型的参数。

        注:在这里的训练我们只涉及训练集,不去考虑测试集。

k,num_epochs,lr,weight_decay,batch_size = 6,100,5,0,64
train_l, valid_l = k_fold(k,train_features,train_labels,num_epochs,lr,weight_decay,batch_size)
print(f"{k}折交叉验证:平均训练误差:{float(train_l):f}," f"平均验证误差:{float(valid_l):f}")

7.2利用定好的参数再次训练训练集

net = get_net()
    train_ls, _ =train(net, train_features, train_labels, None,None,
          num_epochs, lr, weight_decay, batch_size)
    print(f"训练误差:{float(train_ls[-1]):f}")  

8.训练测试集

        将训练好的网络应用于测试集,得到测试集每一个房子最终的卖价,并将结果转换成csv格式,储存在文件中,方便提交至Kaggle。

preds = net(test_features).detach().numpy()
    test_data["SalePrice"] = pd.Series(preds.reshape(1,-1)[0])
    submission = pd.concat([test_data["Id"],test_data["SalePrice"]],axis = 1)
    submission.to_csv("submission.csv", index = False)

 9.最终成绩(完结撒花)

        

 

  • 2
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值