首页 > 其他分享 >实战Kaggle比赛:预测房价

实战Kaggle比赛:预测房价

时间:2022-10-30 17:11:37浏览次数:61  
标签:实战 features torch Kaggle train ls test data 比赛

引言

最近在看沐神《pytorch动手学深度学习》视频,本文记录一下自己跟着写的一个小实战。

内容

第一步:下载数据集

链接:https://pan.baidu.com/s/1YtH1FGIcraiDgJCmq84WKQ?pwd=l859

提取码:l859

我数据也是从别人那下的,自己没有去官网下。

第二步:导入所需要的包

numpy和pandas版本要和d2l的版本要正确对应,要不使用jupyter编写可能会出现内核中断问题。

%matplotlib inline
import numpy as np
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2l

第三步:读取数据集

读取数据

train_data = pd.read_csv("data/kaggle_house/train.csv")
test_data = pd.read_csv("data/kaggle_house/test.csv")
print("train_data.shape:",train_data.shape)
print("test_data.shape:",test_data.shape)

查看前四个和最后两个特征,以及相应标签(房价)

print(test_data.iloc[0:4,[0,1,2,3,-3,-2,-1]])

将第一个特征Id删除,并将训练集和测试集的特征数据结合起来(按行合并)。训练集不要最后的预测结果
all_features = pd.concat([train_data.iloc[:,1:-1], test_data.iloc[:,1:]],axis=0)
print(all_features.iloc[0:4,[0,1,2,3,-3,-2,-1]])

第四步:数据预处理

数据中有连续型数据和离散型数据,并且存在缺失值。

对应连续性数值,每列将所有缺失的值替换为相应特征的平均值。然后,为了将所有特征放在一个共同的尺度上, 我们通过将特征重新缩放到零均值和单位方差来标准化数据:

先看看all_features.dtypes和all_features.dtypes.index的输出

"""
若无法获得测试数据,则可根据训练数据计算均值和标准差
"""
# 获取all_features是数值的列下标
numeric_features = all_features.dtypes[all_features.dtypes != "object"].index
#每一列变为均值为0,方差为1
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)

而对于离散型数据,只需要把他转为one-hot格式。举个例子,比如地区一共有三个值[北京,上海,天津],此时地区特征就会变成三个特征,分别是北京,上海,天津。如果之前的值为北京,则北京列值为1,其他为0。相当于扩展了列个数。

#将离散数据转换为one-hot
# “Dummy_na=True”将“na”(缺失值)视为有效的特征值,并为其创建指示符特征
all_features = pd.get_dummies(all_features, dummy_na=True)
print("all_features.shape",all_features.shape)

最后,通过values属性,提取numpy格式数据,并转换成tensor

#通过values属性,提取到numpy格式,并转换成张量
# 训练集个数
n_train = train_data.shape[0]
# 转换为张量
train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float32)
test_features = torch.tensor(all_features[n_train:].values, dtype=torch.float32)
train_labels = torch.tensor(train_data.SalePrice.values.reshape(-1,1), dtype=torch.float32)

第五步:定义损失函数

使用的是均方误差损失函数。但是视频说可能存在绝对数量的影响。比如一个房子值10.5W,但预测是0.5万,此时差出10W就是很不理想的。但是如果一个房子值1100W,但是最后预测是1090W,那个这个预测就还行。为了解决这个问题,将数值取对数,如下图。emmm,有一点没搞懂就是定义了这个函数,在模型训练时,并没有使用该函数,用的是MSELoss(),对于log_rmse()只是记录了使用对数损失函数的损失值。

# 均方误差损失函数
# l = (y_hat - y)^2
loss = nn.MSELoss()
#避免绝对数量的影响
def log_rmse(net, features, labels, return_item=True):
    # 为了在取对数时进一步稳定该值,将小于1的值设置为1
    clipped_preds = torch.clamp(net(features),1,float('inf'))
    rmse = torch.sqrt(loss(torch.log(clipped_preds),torch.log(labels)))
    #是得到只有一个元素张量里面的元素值。
    if return_item:
        return rmse.item()
    else:
        #返回一个tensor
        return rmse

第六步:定义模型

模型使用的最简单的线性回归

## in_features_num = train_features.shape[1]
# 线性回归模型
def get_net(in_features_num):
    return nn.Sequential(nn.Linear(in_features_num, 1))

第七步:训练

训练很简单,前向传播->计算损失->计算梯度->更新参数。之前看吴恩达老师的课是自己实现反向传播,沐神这个课是调用现有的API即可。

def train(net, train_features, train_labels, test_features, test_labels, num_epochs, lr, wd, batch_size):
    train_ls, test_ls = [], []
    # 定义优化器:Adam优化器的主要吸引力在于它对初始学习率不那么敏感。
    optimizer = torch.optim.Adam(net.parameters(), lr=lr, weight_decay=wd)
    # 读取小批量数据
    train_iter = d2l.load_array((train_features, train_labels),batch_size)
    for epoch in range(num_epochs):
        for X, y in train_iter:
            # 将梯度设置为0,因为梯度会默认累加
            optimizer.zero_grad()
            y_hat = net(X)
            #l = get_rmse(net,X, y,False)
            l = loss(y_hat, 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

第八步:K折交叉验证(默认你知道K折交叉验证是什么意思)

实现K折交叉验证,需要我们编写一个在折交叉验证过程中返回第i折的数据。

#定义一个函数,在K折交叉验证过程中返回第i折的数据。
def get_k_fold_data(k, i, X, y):
    assert k > 1
    # 每一折数据量的大小
    fold_size = X.shape[0] // k
    X_train, y_train = None, None
    for j in range(k):
        idx = slice(i * fold_size, (i+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

K折交叉验证

# 定义交叉验证函数
def k_fold(k, X_train, y_train, num_epochs, lr, wd, batch_size):
    train_ls_sum, valid_ls_sum = 0, 0
    for i in range(k):
        # 获取数据
        data =get_k_fold_data(k, i, X_train, y_train)
        # 获取网络
        net = get_net(X_train.shape[1])
        #训练
        train_ls, valid_ls = train(net, *data, num_epochs, lr, wd, batch_size)
        train_ls_sum += train_ls[-1]
        valid_ls_sum += valid_ls[-1] 
        if i == 0:
            d2l.plot(list(range(1, num_epochs + 1)), [train_ls, valid_ls],
                     xlabel='epoch', ylabel='rmse', xlim=[1, num_epochs],
                     legend=['train', 'valid'], yscale='log')
        print(f'折{i + 1},训练log rmse{float(train_ls[-1]):f}, '
              f'验证log rmse{float(valid_ls[-1]):f}')
    return train_ls_sum / k, valid_ls_sum / k

最后:跑模型

主要是调了一下学习率的参数。

k, num_epochs, weight_decay, batch_size = 5, 100, 0, 64
for lr in np.arange(1,6,1):
    print("lr==%d时" % lr)
    train_l, valid_l = k_fold(k, train_features, train_labels, num_epochs, lr,
                              weight_decay, batch_size)
    print(f'{k}-折验证: 平均训练log rmse: {float(train_l):f}, '
          f'平均验证log rmse: {float(valid_l):f}')

标签:实战,features,torch,Kaggle,train,ls,test,data,比赛
From: https://www.cnblogs.com/yangxiao-/p/16841664.html

相关文章

  • HCIA-ICT实战基础02-VLAN与接口类型
    HCIA-ICT实战基础-VLAN与接口类型VLAN的基本概念VLAN的应用VLAN的配置示例1VLAN的基本概念1.1如何实现VLANSwitch1与Switch2同属一个企业,该企业统一规划了网络中......
  • HCIA-ICT实战基础05-OSPF基础
    HCIA-ICT实战基础-OSPF基础目录动态路由OSPF协议概述OSPF协议工作原理OSPF协议典型配置1动态路由1.1动态路由概述当网络规模越来越大时,使用手动配置静态获取路由......
  • HCIA-ICT实战基础04-DHCP原理与配置
    HCIA-ICT实战基础-DHCP原理与配置目录DHCP产生背景DHCP工作原理与配置DHCPRelay工作原理与配置1DHCP产生背景1.1手工配置网络参数存在一下问题:灵活性差容易出......
  • HCIA-ICT实战基础03-跨VLAN间通信
    HCIA-ICT实战基础-跨VLAN间通信技术背景使用路由器(物理接口、子接口)实现VLAN间通信使用VLANIF技术实现VLAN间通信三层通信过程解析1技术背景1.1VLAN间通信实际网......
  • HCIA-ICT实战基础10-广域网技术PPP
    HCIA-ICT实战基础-广域网技术PPP目录早期广域网技术概述PPP协议原理与配置1早期广域网技术概述1.1什么是广域网广域网是连接不同地区局域网的网络,通常所覆盖的范......
  • HCIA-ICT实战基础09-远程接入安全管理
    HCIA-ICT实战基础-远程接入安全管理目录AAA概述AAA配置实现telnet原理与配置Stelnet(华为ssh的另一种称呼)配置1AAA概述1.1基本概念AAA是Authentication(认证)、......
  • HCIA-ICT实战基础08-访问控制列表ACL原理与配置
    HCIA-ICT实战基础-访问控制列表ACL原理与配置目录ACL技术概述ACL的基本概念及其工作原理ACL的基础配置及应用ACL技术概述技术背景:需要一个工具实现流量过滤ACL是......
  • HCIA-ICT实战基础07-访问控制列表ACL进阶
    HCIA-ICT实战基础-访问控制列表ACL进阶目录二层ACL技术及配置高级ACL的扩展使用方法及使用场景1二层ACL技术及配置1.1二层ACL概念使用报文的以太网帧头来定义规则,......
  • HCIA-ICT实战基础06-传统生成树
    HCIA-ICT实战基础-传统生成树目录生成树的技术概述STP的基本概念及工作原理STP的基础配置1生成树的技术概述技术背景:二层交换机加入冗余性的同时也产生了环路1.......
  • HCIA-ICT实战基础12-网络设备安全特性
    HCIA-ICT实战基础-网络设备安全特性目录常见设备安全加固策略网络设备安全加固部署示例本机防攻击配置1常见设备安全加固策略1.1为什么需要网络设备安全网络安全......