【实验笔记】Kaggle房价预测经验总结

记录一下在做kaggle房价预测时的一些实践经验

目录

一.总体流程

1.官网下载房价数据集

2.预处理数据集

3.构造模型

4.训练模型

二.总结报错


一.总体流程

1.官网下载房价数据集

地址:House Prices - Advanced Regression Techniques | Kaggle

下载好的数据集包含4个文件:

 ‘train.csv’:训练数据
 ‘test.csv’:测试数据
 ‘data_description.txt’:说明各个特征的文档
 ‘sample_submission.csv’:预测结果提交的示例

这里我自己学习就用到了train.csv

2.预处理数据集

1)用pd读取train.csv文件,得到的数据类型是pandas.core.frame.DataFrame类型,size为1460x81,最后一列SalePrice是要进行预测的(即labels),其余列是影响这个房价的一些因素(即features)

2)将features和labels分离,用到的函数是iloc[],得到inputs.shape是1460x80,outputs,shape是1460x1

3)由于特征列数较多,且有许多离散值数据列,在后期训练时可能会梯度爆炸,因此在这里用drop()函数丢掉一些相关性较弱的列

inputs = inputs.drop('Street', axis=1)
#‘Street’表示要drop掉的这一列的名字
#axis=1表示对这一列drop掉,axis=0表示对这一行drop掉

4)数据表中有一些数值列中存在nan值的,这里需要重新赋值:将这一列的均值赋过去:

inputs=inputs.fillna(inputs.mean())

     数据表中有一些非数值列中存在nan值的,这里需要将“NaN”视为一个类别 这里利用pandas库里面的get_dummies(inputs,dummy_na=True)建0,1矩阵,转换后的inputs.shape变为1460x169

inputs=pd.get_dummies(inputs,dummy_na=True)

5)将inputs,outputs转换成tensor,在之后投入到网络里训练时出现了报错:说两个数据类型不匹配,因此这里将转换成tensor的x,y再统一float类型,都为float32的

#定义x,y为全局变量,这样在调用函数时,也可以在局部进行修改
global x
global y
#转换成tensor类型
x=torch.tensor(inputs.values)
y=torch.tensor(outputs.values)
#统一float32,当x,y是tensor类型时才能用,不然会报错
x= x.to(torch.float32)
y= y.to(torch.float32)
3.构造模型

1)定义网络,之前x.shape是1460x169,y.shape是1460x1,因此net[1]的输入是169维,net[10]的输出是1维

net=nn.Sequential(nn.Flatten(),nn.Linear(169,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))

2)定义损失函数,使用均方误差。当比较真实值和估计值用的--->是平方损失;当预测种类时一般使用交叉熵损失

loss = nn.MSELoss()

3)“对于房价,就像股票价格一样,我们更关心的是相对数量而不是绝对数量。更具体地说,我们往往更关心相对误差,而不是绝对误差𝑦-𝑦̂”,这里使用log_rmse来计算损失

def log_rmse(net,features,labels):
    # 为了进一步稳定取对数时的数值,将小于1的数值设为1
    clipped_preds = torch.clamp(net(features), 1, float('inf'))
    rmse = torch.sqrt( torch.mean(loss(torch.log(clipped_preds),torch.log(labels))))  # 计算预测和实际的RMSE值
    return rmse.item()

4)定义优化器,使用Adam,加上了权重衰退

trainer= torch.optim.Adam(net.parameters(),lr= 0.03, weight_decay=3)

5)定义小批量迭代器,用于训练时的迭代遍历

def data_iter(batch_size,features,labels):
    num_examples=len(features)
    #range() 函数可创建一个整数列表,包含0-->n-1个数
    """
    range(star,stop,step)
    star: 计数从star开始.默认是从0开始.
    stop: 计数到stop结束,但不包括stop.
    step: 步长,默认为1.
    """
    #list()函数可将任何迭代数据转换成list列表形式,并返回列表
    indices=list(range(num_examples))
    #random.shuffle()将indicates列表的顺序随机打乱,而不会产生新的列表
    random.shuffle(indices)
    for i in range(0,num_examples,batch_size):
        batch_indices=torch.tensor(indices[i:min(i+batch_size,num_examples)])
        #yield意思是不断返回操作后的features[batch_indices],labels[batch_indices]
        #一直到循环结束为止
        yield features[batch_indices],labels[batch_indices]  

6)初始化权重参数

def init_weight(m):
    if type(m)==nn.Linear:
        nn.init.normal_(m.weight,std=0.1)
        
net.apply(init_weight)
4.训练模型

1)初始化一些变量

dropout1,dropout2,dropout3,weight_decay=0.2,0.5,0.7,3
num_epochs,batch_size=100,256

2)训练:训练后的每一轮的loss都存放在train_ls中,可以通过查看train_ls的loss来调参,让模型训练的更好一点,一般调lr,weight_decay,dropout,num_epochs,batch_size这些都可以试试 

def train():
    train_ls=[]
    for epoch in range(num_epochs):
        for X,Y in data_iter(256,x,y):
            with torch.enable_grad():
                trainer.zero_grad()
                l=loss(net(X),Y)
            l.sum().backward()
            trainer.step()
        train_ls.append(log_rmse(net,X,Y))
    return train_ls
train_l=train()
train_l

二.总结报错

1.自己写的时候优化器用的是SGD,损失函数用的是均方误差,没有使用log_rmse,训练模型100个epoch,进行lr学习率调参,结果误差就一直过大,稍微将学习率调大一点loss就变成了nan,不知道哪里出了问题。但使用Adam优化器和log_rmse作为损失后,loss就变得正常。

2.在def train()函数中有一个语句,之前写的是 for x,y in data_iter(256,x,y):,运行的时候一直报错:

UnboundLocalError: local variable 'x' referenced before assignment

这是因为函数内部对变量赋值进行修改后,该变量就会被Python解释器认为是局部变量而非全局变量。
解决方式: 在函数内部,给变量添加global修饰符,声明此变量为全局变量,并且尽量让两个变量名不一致,改成:for X,Y in data_iter(256,x,y):

3.对一个DataFrame类型数据不能直接to(torch.float32), 这样会报错说:

AttributeError: 'DataFrame' object has no attribute 'to'

因此需要把DataFrame类型数据先转换成tensor类型,再转成float32格式

4.x,y数据的浮点数类型得一致,不然就会报错:

RuntimeError:mat1 and mat2 must have the same dtype

因此需要x.to(torch.float32),y.to(torch.float32)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值