kaggle题-房价预测(Pytorch),手把手教会,全文代码解释

房价预测

在这里插入图片描述

本题是经典的通过表格数据去预测最终值,主要分为几大步骤:
一.将数据集修改为可以代入到网络模型的数字,因为给的数据大部分都是str类型,是无法直接放到网络模型里跑的,例如下图,很多标签值为str类型,并不是数字,那么解决办法就是将这些标签分类,强制让其变为数字类型
在这里插入图片描述

二.创建神经网络模型

三.训练网络,最终预测测试集

一.数据集制作和修改(数据的预处理)

对于表格数据集来说,无非就两个操作,1.将标签值为数字的标准化,2.将标签值为str字符型的变为float类型

分析题目给的train_csv文件中标签值
在这里插入图片描述
发现第一个标签Id对于预测没用,那么在制作数据的时候首先需要去除第一个标签数据,可以使用.drop[‘id’],也可以用 iloc() 函数去除,直接筛选从第二个标签开始的值。

在这里插入图片描述

将train_csv文件拉到最后,发现最后一个标签值为SalePrice售价,我们本题要做的就是去预测售价,那么在train_csv文件中最后一个标签SalePrice就是我们训练集的label,因此在制作数据集时候,也不能要SalePrice标签,而前面除了Id的所有标签值就是我们训练集的数据,这个房子的各种属性值,比如房子修建时间,面积,或者是否挨着街道等,去用这些数据去预测它的房价。

import pandas                          #表格处理库
import torch                           #框架

#读取数据
train_csv=pd.read_csv('/kaggle/input/house-prices-advanced-regression-techniques/train.csv')        
test_csv=pd.read_csv('/kaggle/input/house-prices-advanced-regression-techniques/test.csv')

#重点:神经网络去训练数据必须都是Tensor张量模型,iloc将标签值分裂出来,转出来的数据类型为float32因为要统一数据类型,训练集数据也要转为f
#loat32,float会提高预测精度,直接读出数据为一维,而训练集的数据为二维,所以用reshape将label数据变为二维
train_label=torch.tensor(train_csv.iloc[:,-1],dtype=torch.float32).reshape(-1,1)
#将训练集和测试集的数据整合在一块处理,这样的好处就是在后面预测的时候,test_csv里面还是str类标签,还的再处理一次数据,整合起来一次性处理好
#再分离训练集和测试集数据,将训练集的Id和SalePrice标签去除,而test集只需要去除Id标签
all_feature=pd.concat((train_csv.iloc[:,1:-1],test_csv.iloc[:,1:]))

#将数字类标签进行标准化操作,也叫归一化处理,这样方便神经网络计算,简化,避免梯度爆炸
number=all_feature.dtypes[all_feature.dtypes!='object'].index         #将数字类型标签索引提取出来,因为归一化只对数字进行处理,str类型不需要管,这也就是上面说的两步中的第一步
all_feature[number]=all_feature[number].apply(
        lambda x: (x-x.mean())/(x.std())                  #标准化,就是把数据值变小了,让其正态分布
)
#因为csv文件里面经常有数据缺失,将空缺的NaN补为0,否则NaN无法在网络中计算
all_feature[number]=all_feature[number].fillna(0)
#将标签为str类型转换为数字型,具体原理如下图
all_feature=pd.get_dummies(all_feature,dummy_na=True)

请添加图片描述

标签的值有几种,它就拆为几个小标签,例如标签为生物种类class,那么标签值有狗,猫,人,鸟,牛,那么这个标签会变为class_人,class_狗,class_猫…
经过上面数据处理操作后,那么我们的DataFrame变为以下
在这里插入图片描述
数字类别标签已经标准化,str类标签也转化为数字表示,这里的False 和True在网络中会被自动识别为0和1,但此时这个表还只是DataFrame类型数据,并不是我们要的数据集

#分离数据,将训练集和测试集数据分离
train_n=train_csv.shape[0]                     #因为all_feature是train和test整合起来一块处理的所以得到训练集的数目
all_feature=all_feature.astype(np.float32)     #转换数据,将表中的值全变为float类型方便计算
train_data=torch.tensor(all_feature[:train_n].values,dtype=torch.float32)   #分离出训练集
test_data=torch.tensor(all_feature[train_n:].values,dtype=torch.float32)    #分离测试集

此时我们得到了训练集的数据,和标签,但需要整合起来,也就是一 一对应,每单个样本和其标签值,这篇文章我写了在pytorch中如何整合数据:
https://blog.csdn.net/qq_43767511/article/details/141924633?spm=1001.2014.3001.5501

#创建数据集
from torch.utils.data import Dataset       
from torch.utils.data import DataLoader
class data(Dataset):                    #创建单个数据单元
    def __init__(self,tensor1,tensor2):      #继承,下面要用到什么变量,这里就要声明什么变量
        super().__init__()              #模板
        self.tensor1=tensor1				
        self.tensor2=tensor2
    def __len__(self):
        return len(self.tensor1)        #模板随便写
    def __getitem__(self, idex):        #将单个数据和标签整合到一块的初始化函数
        train_one_data=self.tensor1[idex,:]     #通过idex得到单个数据
        label=self.tensor2[idex,-1]             #得到该数据的标签
        return train_one_data,label             #返回数据+标签,相当于捆绑
 
 #将所有的数据整合成为一个整体
 data_1=data(train_data,train_label)            #将上面的类实例化
 data_2=DataLoader(data_1,batch_size=32)        #进行整合,batch_size表示一组有几个单数据,为的是后面的分组训练

那么上面最后的得到的data_2就是我们最终的完整训练集了,既有数据,还有对应的标签,数据的预处理到此结束。

损失函数和网络模型

#损失函数定义
loss=nn.MSELoss()                    #这里用的是均方误差损失函数

in_feature=train_data.shape[1]       #根据单个数据的长度去创建模型

#创建网络,这里只是做了一个简单的全连接层,可以自己多去创建几层
def get_net():                       
    net=nn.Sequential(nn.Linear(in_feature,1))      #搭建模型,这里定义了  
    return net

损失函数运算原理,第一个y表示我们神经网络预测的y值,第二个y表示标签值:
在这里插入图片描述

#损失函数定义,这个函数和上面的损失函数不同,上面的是神经网络需要用到的,下面这个是用来matplotlib图来观察loss的走向的,让数据可视化,当然也可以不用,不会影响我们预测的结果

def loss_function(net,infeature,labels):           
    final_y=torch.clamp(net(infeature),1,float('inf'))        #让预测的值在1-99999之间,得到负数的直接扔掉            
    rmse=torch.sqrt(loss(torch.log(final_y),torch.log(labels)))   #下图公式  
    return rmse.item()              #将张量变为数值输出,不加item的话,输出的就是tensor张量了,我们要的是数值

请添加图片描述

训练函数

训练函数代码很长,不需要被吓到,一步一步解释,把逻辑理清就好了

#上面创建了网络框架,那么就将网络模型实例化,就一直用这个网络
net=get_net()

#定义训练函数,net参数就是我们的网络模型,第一第二个不说了,数据和标签
#num_epoch要进行几个训练来回,理应越大越好,就是一直不停的训练,但是容易过拟合
#learning_rate学习率,梯度下降时候要求导,w-dw*r 控制梯度下降时候,各个参数变化幅度
#weight_decay 主要用于在模型训练过程中对权重进行正则化,防止过拟合
def train(net,train_data,train_label,num_epoch,learning_rate,weight_decay):
    train_ls=[]                               #负责监控损失函数值变化,就是用到上面说的第二个损失函数
    optimer=Adam(net.parameters(),            #模板,梯度下降算法,优化算法,优化网络模型的参数
                 lr=learning_rate,            #上面说了,学习率主要控制梯度下降过程中参数的变化
                 weight_decay=weight_decay     
                )
    #开始训练,以下几步都是神经网络训练的经典模板,理解不了也没事
    for epoch in range(num_epoch):             #训练几个回合,先预测,后梯度下降算一个来回
        for x,y in data_2:                     #从我们上面做的训练数据集中,分别取出数据和标签
            optimer.zero_grad()               #将模型中所有参数的梯度清零,以便在下次迭代中进行正确的梯度计算和更新。
            loss_value=loss(net(x).squeeze(),y)   #利用第一个损失函数来进行梯度下降,这里为什么用squeeze,因为得到的x维度为[32,1,330],该函数会压缩,把1抹去,直接变为[32,330],而y维度为[32,1],要用损失函数时,切记要维度相同
            loss_value.backward()                 #损失函数对每个参数的变化率(梯度),以便根据梯度来更新参数
            optimer.step()                        #作用是根据计算得到的梯度来更新模型的参数
        train_ls.append(loss_function(net,train_data,train_label))    #用第二个损失函数记录跟踪损失值变化上面已经解释了,存不存在,不会影响我们预测结果
    return train_ls

#上面只是定义训练函数,那么下面就是正儿八经开始调用函数训练,初始参数可以自己调
train(net,train_data,train_label,100,learning_rate=0.1,weight_decay=1)

#上面训练后,那么net里面的w和b参数已经是训练好的参数,直接预测就可以

pred=net(test_data).detach().numpy()        #前面已经将训练集处理好了,这里直接放入net网络预测,detach()目的是将得出的结果与模型想隔离,numpy是将向量变为numpy数组,只有这样,才能把我们预测的数据存入到csv文件

#我们开始制作csv文件,因为要提交csv文件才能算通过

test_csv['SalePrice']=pd.Series(pred.reshape(1,-1)[0])         #在最开始读取test_cav的DataFrame里将‘SalePrice’赋值为我们的预测值,因为测试集里没有该标签,需要我们自己填入
submission=pd.concat((test_csv['Id'],test_csv['SalePrice']),axis=1)    #将文件中的id和SalePrice提取出来,重新构建一个csv文件,concat表示按列或者按行拼接,axis=1表示列,=0表示按行
submission.to_csv('submission.csv',index=False)                     #生成csv文件

生成的结果如下图所示

在这里插入图片描述

整篇代码

下面是整篇代码

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import torch
from torch.utils.data import Dataset 
from torch import nn
from torch.optim import Adam
from torch.utils.data import DataLoader

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename)

# 提取数据,处理数据

train_csv=pd.read_csv('/kaggle/input/house-prices-advanced-regression-techniques/train.csv')
test_csv=pd.read_csv('/kaggle/input/house-prices-advanced-regression-techniques/test.csv')
train_label=torch.tensor(train_csv.iloc[:,-1],dtype=torch.float32).reshape(-1,1)
all_feature=pd.concat((train_csv.iloc[:,1:-1],test_csv.iloc[:,1:]))

number=all_feature.dtypes[all_feature.dtypes!='object'].index
all_feature[number]=all_feature[number].apply(
        lambda x: (x-x.mean())/(x.std())
)
all_feature[number]=all_feature[number].fillna(0)
all_feature=pd.get_dummies(all_feature,dummy_na=True)

# 分离数据,

train_n=train_csv.shape[0]
all_feature=all_feature.astype(np.float32)     #转换数据
train_data=torch.tensor(all_feature[:train_n].values,dtype=torch.float32)
test_data=torch.tensor(all_feature[train_n:].values,dtype=torch.float32)

class data(Dataset):
    def __init__(self,tensor1,tensor2):
        super().__init__()
        self.tensor1=tensor1
        self.tensor2=tensor2

    def __len__(self):
        return len(self.tensor1)
    def __getitem__(self, idex):
        train_one_data=self.tensor1[idex,:]
        label=self.tensor2[idex,-1]  
        return train_one_data,label

 data_1=data(train_data,train_label)
 data_2=DataLoader(data_1,batch_size=32)


loss=nn.MSELoss()
in_feature=train_data.shape[1]
def loss_function(net,infeature,labels):
    final_y=torch.clamp(net(infeature),1,float('inf'))
    rmse=torch.sqrt(loss(torch.log(final_y),torch.log(labels)))
    return rmse.item()             #将张量变为数值输出
   
def get_net():
    net=nn.Sequential(nn.Linear(in_feature,1))
    return net

net=get_net()

def train(net,train_data,train_label,num_epoch,learning_rate,weight_decay):
    train_ls=[]
    optimer=Adam(net.parameters(),
                 lr=learning_rate,
                 weight_decay=weight_decay
                )
    for epoch in range(num_epoch):
        for x,y in data_2:
            optimer.zero_grad()
            loss_value=loss(net(x).squeeze(),y)
            loss_value.backward()
            optimer.step()
        train_ls.append(loss_function(net,train_data,train_label))
    return train_ls
train(net,train_data,train_label,100,learning_rate=0.1,weight_decay=1)

pred=net(test_data).detach().numpy()

test_csv['SalePrice']=pd.Series(pred.reshape(1,-1)[0])
submission=pd.concat((test_csv['Id'],test_csv['SalePrice']),axis=1)
submission.to_csv('submission.csv',index=False)

泰坦尼克号幸存者预测也和该文逻辑一样

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值