使用 PyTorch 和 Pandas 进行 Kaggle 房价预测

文章目录

    • 1、环境设置
    • 2、数据下载
    • 3、数据预处理
    • 4、模型构建
    • 5、训练和验证
    • 6、训练模型并生成预测结果
    • 7、完整代码


在本篇博文中,我们将探索如何使用 PyTorch 和 Pandas 库,构建一个用于 Kaggle 房价预测的模型。我们将详细讨论数据加载、预处理、模型构建、训练、验证及最终预测的全过程。

1、环境设置

我们首先需要导入所需的库,包括用于数据处理的 pandasnumpy,以及用于深度学习的 torch

import hashlib
import os
import requests
import numpy as np
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2l

2、数据下载

为了下载数据,我们需要定义一个下载函数,并在其中实现数据缓存机制以避免重复下载。

# 保存DATA_HUB字典以便下载数据
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:breaksha1.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

接下来,我们在 DATA_HUB 中注册 Kaggle 房价预测的训练和测试数据集,并下载这些数据。

# 在DATA_HUB中注册Kaggle房价预测的训练和测试数据集
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')# 下载并加载数据
train_data = pd.read_csv(download('kaggle_house_train'))
test_data = pd.read_csv(download('kaggle_house_test'))

3、数据预处理

我们首先查看数据集的形状和部分内容。

# 查看数据集的形状和部分内容
print(train_data.shape)
print(test_data.shape)
print(train_data.iloc[0:4, [0, 1, 2, 3, -3, -2, -1]])

然后,我们合并所有特征以进行统一预处理,并标准化数值特征,填充缺失值为0,处理离散数值特征。

# 合并所有特征以进行预处理
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
all_features[numeric_features] = all_features[numeric_features].fillna(0)# 处理离散数值特征(dummy_na=True包括缺失值)
all_features = pd.get_dummies(all_features, dummy_na=True)# 确保所有特征都是数值类型
all_features = all_features.astype(np.float32)

将数据转换为 tensor 格式,以便 PyTorch 使用。

# 将数据转换为tensor格式
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)

4、模型构建

我们定义一个简单的线性回归模型,并设置损失函数。

# 定义损失函数和获取网络结构
loss = nn.MSELoss()
in_features = train_features.shape[1]def get_net():net = nn.Sequential(nn.Linear(in_features, 1))return net

5、训练和验证

为了更好地评估模型,我们定义了 K 折交叉验证和训练函数。

# 定义log_rmse函数
def log_rmse(net, features, labels):clipped_preds = torch.clamp(net(features), 1, float('inf'))rmse = torch.sqrt(loss(torch.log(clipped_preds), torch.log(labels)))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 = [], []train_iter = d2l.load_array((train_features, train_labels), batch_size)optimizer = torch.optim.Adam(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# 获取k折交叉验证的数据
def get_k_fold_data(k, i, X, y):assert k > 1fold_size = X.shape[0] // kX_train, y_train = None, Nonefor 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_partelif X_train is None:X_train, y_train = X_part, y_partelse:X_train = torch.cat([X_train, X_part], 0)y_train = torch.cat([y_train, y_part], 0)return X_train, y_train, X_valid, y_valid# 定义k折交叉验证函数
def k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay, batch_size):train_l_sum, valid_l_sum = 0, 0for 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]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}, 验证log rmse{float(valid_ls[-1]):f}')return train_l_sum / k, valid_l_sum / k

6、训练模型并生成预测结果

我们定义了最终的训练和预测函数,并训练模型生成预测结果。

# 定义超参数并进行k折交叉验证
k, num_epochs, lr, weight_decay, batch_size = 5, 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}-折验证: 平均训练log rmse: {float(train_l):f}, 平均验证log rmse: {float(valid_l):f}')# 定义最终的训练和预测函数
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}')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)# 训练模型并生成预测结果
train_and_pred(train_features, test_features, train_labels, test_data, num_epochs, lr, weight_decay, batch_size)

通过上述步骤,我们成功地使用 PyTorch 和 Pandas 实现了一个简单的线性回归模型,用于 Kaggle 房价预测任务。这篇博文涵盖了数据下载、预处理、模型构建、训练、验证及预测的全过程,为类似任务提供了一个完整的参考。

7、完整代码

import hashlib
import os
import tarfile
import zipfile
import requests
import numpy as np
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2l# 保存DATA_HUB字典以便下载数据
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:breaksha1.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# 在DATA_HUB中注册Kaggle房价预测的训练和测试数据集
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')# 下载并加载数据
train_data = pd.read_csv(download('kaggle_house_train'))
test_data = pd.read_csv(download('kaggle_house_test'))# 查看数据集的形状和部分内容
print(train_data.shape)
print(test_data.shape)
print(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
all_features[numeric_features] = all_features[numeric_features].fillna(0)# 处理离散数值特征(dummy_na=True包括缺失值)
all_features = pd.get_dummies(all_features, dummy_na=True)# 确保所有特征都是数值类型
all_features = all_features.astype(np.float32)# 将数据转换为tensor格式
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)# 定义损失函数和获取网络结构
loss = nn.MSELoss()
in_features = train_features.shape[1]def get_net():net = nn.Sequential(nn.Linear(in_features, 1))return net# 定义log_rmse函数
def log_rmse(net, features, labels):clipped_preds = torch.clamp(net(features), 1, float('inf'))rmse = torch.sqrt(loss(torch.log(clipped_preds), torch.log(labels)))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 = [], []train_iter = d2l.load_array((train_features, train_labels), batch_size)optimizer = torch.optim.Adam(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# 获取k折交叉验证的数据
def get_k_fold_data(k, i, X, y):assert k > 1fold_size = X.shape[0] // kX_train, y_train = None, Nonefor 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_partelif X_train is None:X_train, y_train = X_part, y_partelse:X_train = torch.cat([X_train, X_part], 0)y_train = torch.cat([y_train, y_part], 0)return X_train, y_train, X_valid, y_valid# 定义k折交叉验证函数
def k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay, batch_size):train_l_sum, valid_l_sum = 0, 0for 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]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}, 验证log rmse{float(valid_ls[-1]):f}')return train_l_sum / k, valid_l_sum / k# 定义超参数并进行k折交叉验证
k, num_epochs, lr, weight_decay, batch_size = 5, 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}-折验证: 平均训练log rmse: {float(train_l):f}, 平均验证log rmse: {float(valid_l):f}')# 定义最终的训练和预测函数
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}')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)# 训练模型并生成预测结果
train_and_pred(train_features, test_features, train_labels, test_data, num_epochs, lr, weight_decay, batch_size)

提示:更多内容可以访问Clang’s Blog:https://www.clang.asia

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue注册自定义指令

在 Vue 中,可以通过全局或局部注册自定义指令。下面是一个简单的示例,演示如何在 Vue 中注册一个自定义指令。 首先,我们需要定义一个自定义指令。在 Vue 中,自定义指令可以通过全局或局部注册,并在元素上绑定特定的行…

LaTeX 2022软件安装教程(附软件下载地址)

软件简介: 软件【下载地址】获取方式见文末。注:推荐使用,更贴合此安装方法! LaTeX 2022是基于ΤΕΧ的一种排版系统,特别适用于生成科技和数学文档的高质量打印。它可用于各种文档类型,从简单信函到完整…

Java进阶学习笔记2——static

static: 叫静态,可以修饰成员变量、成员方法。 成员变量按照有无static修饰,分为两种: 类变量:有static修饰,属于类,在计算机中只有一份,会被类的全部对象共享。静态成员变量。 实…

即时通讯ICQ将于2024年6月26日起关闭

即时通讯鼻祖ICQ 将于2024年6月26日起停止服务。 背景 ICQ则是由以色列的Mirabilis公司开发,ICQ发布后不久,腾讯发布了中国版QQ,当时界面和概念上非常类似ICQ,同时期还有微软MSN。 那个时候很多人都认为QQ肯定竞争不过ICQ和MSN&…

慢性乙型肝炎肝脏剪切波弹性成像的深度学习放射学显著改善了肝纤维化的诊断性能 | 文献速递-深度学习结合影像组学

慢性乙型肝炎肝脏剪切波弹性成像的深度学习放射学显著改善了肝纤维化的诊断性能 | 文献速递-深度学习结合影像组学 麦田医学 美好事物中转站 2024-05-21 11:03 Title 题目 Deep learning Radiomics of shear wave elastography significantly improved diagnostic performa…

面试准备-项目【面试准备】

面试准备-项目【面试准备】 面试准备自我介绍:项目介绍: 论坛项目功能总结简介数据库表设计注册功能登录功能显示登录信息功能发布帖子评论私信点赞功能关注功能通知搜索网站数据统计热帖排行缓存 论坛项目技术总结Http的无状态cookie和session的区别为什…

《我的阿勒泰》观后感(二、返璞归真也是一种美)

看了李娟的小说《我的阿勒泰》逐渐悟到一个道理,返璞归真也是一种美,没必要每个人的人生三十年的年华,都去追求房子,车子等逐渐贬值的东西。人究竟应该追求怎样的一种活法? 什么是城市化?这是我听到的最好…

UniApp 2.0可视化开发工具:引领前端开发新纪元

一、引言 在移动互联网迅猛发展的今天,移动应用开发已经成为前端开发的重要方向之一。为了简化移动应用开发流程,提高开发效率,各大开发平台不断推出新的工具和框架。UniApp作为一款跨平台的移动应用开发框架,自诞生以来就备受开…

山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(十八)- JUC(4)

线程安全分析 成员变量和静态变量是否线程安全? 如果它们没有共享,则线程安全 如果它们被共享了,根据它们的状态是否能够改变,又分两种情况 如果只有读操作,则线程安全如果有读写操作,则这段代码是临界区…

Java之设计模式

概述 设计模式就是经过我们开发人员通过长时间的开发实践得出的一种开发模式,目的就是在开发过程中降低代码耦合度,提高代码可复用性/扩展/维护。目前主要有23种设计模式,分为创建型模式、行为型模式、结构型模式。本文列举了实际项目中使用到的设计模式,包括单例模式、策略模…

分布式和集群区别

分布式 分布式的主要工作是分解任务,将职能拆解,多个人在一起做不同的事 集群 集群主要是将同一个业务,部署在多个服务器上 ,多个人在一起做同样的事

GPT-3:自然语言处理的预训练模型

自然语言处理(NLP)领域近年来取得了显著的进步,特别是预训练模型的引入,彻底改变了我们与计算机交互和处理自然语言的方式。在这些模型中,GPT-3(Generative Pre-trained Transformer 3)无疑是最…

Spring常见注解

Spring常见注解 1. 概述2. DI(依赖注⼊)相关注解2.1 Autowired2.2 Bean2.3 Qualifier2.4 Required (很少使用)2.5 Value2.6 Lazy2.7 Profile 1. 概述 我们都知道Spring最核心的特性就是IOC(控制反转) AOP&…

PySODEvalToolkit 使用笔记

1. 克隆仓库 首先,克隆PySODEvalToolkit仓库到你的本地机器: git clone https://github.com/lartpang/PySODEvalToolkit.git2. 创建虚拟环境 cd PySODEvalToolkit conda create -n pysodeval python3.73. 安装依赖 pip install -r requirements.txt4…

[算法] 优先算法(一): 双指针算法(上)

🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏:🍕 Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 🧀Java …

SpringBoot2.0.x旧版集成Swagger UI报错Unable to infer base url...解决办法

一、问题描述 1.1项目背景 SpringBoot2.0.9的旧版项目维护开发,集成Swagger-ui2.9.2无法访问的问题。不用想啊,这种老项目是各种过滤器拦截器的配置,访问不到,肯定是它们在作妖。懂得都懂啊,这里交给大家一个排错的办…

Flutter设计模式全面解析:单例模式

谈到设计模式这个“古老”的话题,大家先别急着划走哈,虽然对它再熟悉不过,几乎是最初开始学习编程到现在伴随着我们整个编程生涯,最早 Java、C 语言实现的各种设计模式到现在还会经常有所接触,面试中也是必问的环节&am…

Adobe Camera Raw 11 for Mac/win:摄影后期处理的革命性飞跃

在数字摄影的世界里,RAW格式以其未压缩的原始数据特性,为摄影师提供了更大的后期处理空间。而Adobe Camera Raw 11,作为这一领域的翘楚,以其卓越的性能和创新的功能,为摄影师们带来了前所未有的创作体验。 Adobe Came…

LeetCode450删除二叉搜索树中的节点

题目描述 给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。一般来说,删除节点可分为两个步骤&#xff1…