动手学深度学习(Pytorch版)代码实践 -深度学习基础-13Kaggle竞赛:2020加州房价预测

13Kaggle竞赛:2020加州房价预测

# 导入所需的库
import numpy as np
import pandas as pd
import torch
import hashlib
import os
import tarfile
import zipfile
import requests
from torch import nn
from d2l import torch as d2l

# 读取训练和测试数据
train_data = pd.read_csv('../data/california-house-prices/train.csv')
test_data = pd.read_csv('../data/california-house-prices/test.csv')

# 打印数据形状
# print(train_data.shape)
# print(test_data.shape)
# (47439, 41)
# (31626, 40)

# 打印前4行的部分列
# print(train_data.iloc[0:4, [0, 1, 2, 3, 4, 5, 6, -3, -2, -1]])

# 合并训练和测试数据,用于特征工程
all_features = pd.concat((train_data.iloc[:, train_data.columns != 'Sold Price'], test_data.iloc[:, 1:]))
# all_features.info()
# print(all_features.shape)
# (79065, 40)

# 去除ID列
all_features = all_features.iloc[:, 1:]

# 将字符型日期列转化为日期型
all_features['Listed On'] = pd.to_datetime(all_features['Listed On'], format="%Y-%m-%d")
all_features['Last Sold On'] = pd.to_datetime(all_features['Last Sold On'], format="%Y-%m-%d")

# 标准化数值特征
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()))
all_features[numeric_features] = all_features[numeric_features].fillna(0)

# 打印每个字符型特征的唯一值数量
# for in_object in all_features.dtypes[all_features.dtypes == 'object'].index:
#     print(in_object.ljust(20), len(all_features[in_object].unique()))
"""
in_object.ljust(20):将列名左对齐,并填充空格使其长度至少为20个字符,这样打印时更整齐。
len(all_features[in_object].unique()):计算该列中唯一值的数量。
便于后续的独热编码,防止内存爆炸
"""

# 选择需要的特征
features = list(numeric_features)
features.extend(['Type'])
all_features = all_features[features[:]]

# 独热编码
all_features = pd.get_dummies(all_features, dummy_na=True, dtype=float)
# print(all_features.shape)
# (79065, 195)

# 查看全部特征的数据类型
# print(all_features.dtypes.unique())

# 从pandas格式中提取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['Sold Price'].values.reshape(-1, 1),
    dtype=torch.float32
)

# 是否使用GPU训练
if not torch.cuda.is_available():
    print('CUDA is not available. Training on CPU ...')
else:
    print('CUDA is available. Training on GPU ...')
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# 将特征和标签移到设备上
train_features = train_features.to(device)
test_features = test_features.to(device)
train_labels = train_labels.to(device)

# 定义均方误差损失函数
loss = nn.MSELoss()

# 输入特征的数量
in_features = train_features.shape[1]
# print(in_features)
# 195

# 定义神经网络模型
dropout1, dropout2, dropout3 = 0.2, 0.3, 0.5

def get_net():
    net = nn.Sequential(
        nn.Flatten(),
        nn.Linear(in_features, 128), nn.ReLU(),
        # nn.Dropout(dropout1),

        nn.Linear(128, 64), nn.ReLU(),
        # nn.Dropout(dropout2),

        nn.Linear(64, 32), nn.ReLU(),
        # nn.Dropout(dropout3),

        nn.Linear(32, 1))
    return net.to(device)  # 使用GPU

# 计算对数均方根误差
def log_rmse(net, features, labels):
    """
    使用 torch.clamp 函数将预测值的下限限制在 1,确保所有预测值至少为 1。
    这是为了避免在取对数时出现负值或零值,因为对数在这些点上未定义或会导致数值问题。
    """
    clipped_preds = torch.clamp(net(features), 1, float('inf'))
    rmse = torch.sqrt(loss(torch.log(clipped_preds), torch.log(labels)))

    # 将 PyTorch 张量转换为 Python 标量
    return rmse.item()

# 训练模型函数
def train(net, train_features, train_labels, test_features, test_labels,
          num_epochs, learning_rate, weight_decay, batch_size):
    
    train_ls, tets_ls = [], []  # 用于存储每个epoch的训练和测试损失
    train_iter = d2l.load_array((train_features, train_labels), batch_size)  # 创建训练数据迭代器
    optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate,
                                 weight_decay=weight_decay)  # 定义Adam优化器
    # weight_decay: 权重衰减,用于L2正则化。

    for epoch in range(num_epochs):
        for X, y in train_iter:
            X, y = X.to(device), y.to(device)  # 确保批次数据在GPU上
            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:
            # 计算并记录测试集上的对数均方根误差
            tets_ls.append(log_rmse(net, test_features, test_labels))

    return train_ls, tets_ls

# 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(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], 0)
            y_train = torch.cat([y_train, y_part], 0)
    return X_train.to(device), y_train.to(device), X_valid.to(device), y_valid.to(device)  # 确保在GPU上

# 在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]
        # 将 train_ls 列表中的最新值(即当前 epoch 的训练损失)累加到 train_l_sum 变量中。
        valid_l_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_l_sum / k, valid_l_sum / k

# 定义训练参数
k, num_epochs, lr, weight_decay, batch_size = 5, 100, 0.01, 0, 256

# 进行K折交叉验证
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}')

d2l.plt.show() 

# 提交Kaggle预测
def train_and_pred(train_features, test_features, train_labels, test_data,
                   num_epochs, lr, weight_decay, batch_size):
    net = get_net()
    train_ls, _ = train(net, train_features, train_labels, None, None,
                        num_epochs, lr, weight_decay, batch_size)
    d2l.plot(np.arange(1, num_epochs + 1), [train_ls], xlabel='epoch',
             ylabel='log rmse', xlim=[1, num_epochs], yscale='log')
    print(f'训练log rmse:{float(train_ls[-1]):f}')
    # 将网络应用于测试集,并将结果从GPU转移到CPU再转换为NumPy数组
    preds = net(test_features).detach().cpu().numpy()
    # 将其重新格式化以导出到Kaggle
    test_data['Sold Price'] = pd.Series(preds.reshape(1, -1)[0])
    submission = pd.concat([test_data['Id'], test_data['Sold Price']], axis=1)
    submission.to_csv('../data/california-house-prices/submission.csv', index=False)

# 训练模型并进行预测
train_and_pred(train_features, test_features, train_labels, test_data,
               num_epochs, lr, weight_decay, batch_size)

d2l.plt.show()

运行结果:

1,训练log rmse0.356748, 验证log rmse0.3316662,训练log rmse0.337252, 验证log rmse0.3418753,训练log rmse0.317294, 验证log rmse0.3245164,训练log rmse0.337175, 验证log rmse0.3606255,训练log rmse0.356537, 验证log rmse0.379667
5-折验证: 平均训练log rmse: 0.341001, 平均验证log rmse: 0.347670
训练log rmse:0.307162

在这里插入图片描述
在这里插入图片描述

竞赛得分:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/720196.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GIT回滚

1. 使用 git revert git revert 命令会创建一个新的提交,这个提交会撤销指定提交的更改。这通常用于公共分支(如 main 或 master),因为它不会重写历史。 git revert HEAD # 撤销最近的提交 # 或者指定一个特定的提交哈希值 …

【电子数据取证】如何快速在CSV中找到涉案手机号码

文章关键词:电子数据取证、聊天记录恢复、数据恢复、手机取证、介质取证 一、前言 在最近的取证工作中,我们遇到很多需要从大量的聊天记录数据中提取特定的信息,例如手机号码,银行号码,交易码。由于数据通常以数据库…

成熟制程新周期:华虹半导体股价飙升,大摩超配背后的逻辑是何?

半导体全线异动,新周期确定已到? 今年以来,在众多利好消息驱动下,华虹半导体(01347.HK)、中芯国际(00981.HK)、复旦微电(01385.HK)等港股芯片概念标的&#…

分享一个自己写的PC版的Ai指令保存工具

今天给大家分享下我用非常古老的VB写的一个小工具。纯粹是每次电脑使用指令太麻烦了,所以写了一个小工具。这个工具支持5条指令,作为一般的应该够用了。使用场景:比如你要经常使用指令,但是觉得复制指令麻烦,那么你可以…

Thinkphp校园新闻发布系统源码 毕业设计项目实例

Thinkphp校园新闻发布系统源码 毕业设计项目实例 校园新闻发布系统模块: 用户模块:注册,登陆,查看个人信息,修改个人信息,站内搜索,新闻浏览等功能, 后台管理员模块:会员…

月薪没到20K,必啃的WebGIS系统技术栈,你练到哪一步了?

WebGIS(网络地理信息系统)是目前地理信息系统(GIS)开发的主流,它利用互联网技术来发布、共享和交互地理空间数据。 一个完整的WebGIS项目通常涉及以下几个主要环节:具备一定的理论知识,数据生产…

Spring是如何设计IOC容器的?BeanFactory ApplicationContext

BeanFactory是Spring框架中最底层的接口,用于实例化、配置和管理bean。它使用控制反转(IOC)模式,将对象的创建、管理和装配的职责从应用程序代码中转移给Spring容器。这样,应用程序代码就无需关心对象如何创建和装配&a…

【区块链】POS(Proof of Stake)权益证明算法深度解析

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 POS(Proof of Stake)权益证明算法深度解析引言1. POS基本…

基于Matlab的细胞计数图像处理系统(GUI界面有报告) 【含Matlab源码 MX_003期】

简介: 本文旨在解决生物血细胞数目统计的挑战,提出了基于图像处理的综合方案。通过MATLAB平台,我们设计并实现了一套完整的细胞图像处理与分析流程。在预处理阶段,采用图像增强和阈值分割等方法,有效地提高了细胞图像的…

Linux---rpm/yum包管理器

文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 一.RPM概述 RPM(Red Hat Package Manager)是Linux中的一种软件包管理格式也可以称为软件包管理器;它可以将软件包以二进制形式打包,并提供工具来安…

Conmi的正确答案——Vue默认加载方式设置为Yarn后怎么修改

Vue版本:3 1和2主要是搜索文件所在位置,Windows的这个文件一般在“C:\Users\{当前用户}”下,linux的非root情况下一般在“/home/{当前用户}”下。 1、打开“Everything”; 2、搜索“vuerc”; 3、打开“.vuerc”&#…

vue 和 js写屏幕自适应

实现屏幕自适应的方式有很多种,可以通过插件本身提供的方法,可以通过flex布局等,今天我们来写写通过js实现屏幕自适应。 以下是在vue中实现的屏幕自适应 首先在data中定义一下屏幕的默认大小和缩放比例 然后在mounted中获取窗口的内置宽高&a…

jrt从量变到质变

又是一个加班的周末,上周把台式机代码和数据库环境弄好了,这周进行大数据测试,直接把标本、标本医嘱、报告、报告结果、药敏结果等数据插入到1亿的规模,跑了一天一夜插入了5000多万个标本,后面接着补剩下的到一亿。 演…

生命在于学习——Python人工智能原理(3.5)

三、深度学习 9、常见神经网络 常见的神经网络有卷积神经网络(AlexNet、VGGNet)、循环神经网络(RNN) 长短时记忆网络(LSTM)。 (1)AlexNet AlexNet于2012年由Hinton学生Alex提出&a…

shell脚本编程(概念、编程和语句)

一、shell脚本概述 1、shell脚本概念 Shell 脚本是利用 shell 的功能所写的一个程序。这个程序是使用纯文本文件,将一些 shell 的语法与命令(含外部命令)写在里面,搭配正则表达式、管道命令与数据流重定向等功能。 2、Shell 脚…

使用vscode插件du-i18n处理前端项目国际化翻译多语言

前段时间我写了一篇关于项目国际化使用I18n组件的文章,Vue3 TS 使用国际化组件I18n,那个时候还没真正在项目中使用,需求排期还没有定,相当于是预研。 当时就看了一下大概怎么用,改了一个简单的页面,最近需…

嵌入式实训day6

1、 from machine import Pin from neopixel import NeoPixel import timeif __name__"__main__"#创建RBG灯带控制对象,包含5个像素(5个RGB LED)rgb_led NeoPixel(Pin(4,Pin.OUT),5)#定义RGB颜色RED(255,0,0)GREEN(0,2…

SOLIDWORKS 2024正版软件:新增功能介绍

随着科技的飞速发展,计算机辅助设计(CAD)软件在工业设计领域扮演着越来越重要的角色。SOLIDWORKS作为3D CAD软件提供商,其每一次版本更新都带来了一系列创新功能和改进,旨在为用户提供更有效、更智能、更协同的设计体验…

传输层udp和tcp协议格式

UDP协议 UDP协议端格式 udp的前八个字节是报头,后面部分就是有效载荷。而目的端口号就保证了udp向应用层交付的问题。 而针对于报头和有效载荷分离是根据固定八字结的报头长度。数据的长度就是取决于报头中udp长度字段的大小来确定udp报文长度,因此也可…

006 spring事务支持

文章目录 事务回顾事务介绍事务并发问题(隔离性导致)事务隔离级别 Spring框架事务管理相关接口Spring框架事务管理的分类编程式事务管理(了解)声明式事务管理(重点) 事务管理之XML方式业务层持久层单元测试代码配置事务管理的AOP 事务管理之混合方式事务管理之基于AspectJ的纯注…