Kaggle 房价预测

 

目录

  • 任务背景
  • 某些API解释
  • 实现
  • 作业问题记录
  • 参考文献

一、任务背景

学习了Kaggle房价预测,做点记录。之前自己写过一个关于PM2.5数据清洗的代码,详见:

PM2.5数据的清洗,汇总与制作散点图(含源数据链接)

该任务情况:

目的:构建神经网络来预测房屋的价格,

工具:Pytorch

任务链接

二、某些API解释

1.pandas.loc 

作用:

Access a group of rows and columns by label(s) or a boolean array.

意思是通过标签或一个布尔型数组(e.g. [True, False, True])获取一系列行和列

详见pandas.DataFrame.loc

2.pandas.iloc

作用:

Purely integer-location based indexing for selection by position.

意思是根据位置索引获取数值

详见pandas.DataFrame.iloc

pandas.loc 与pandas.iloc具体对比:参考文档

3.pandas.concat

作用:将两个数组拼接

详见:pandas.concat

例子:

all_features = pd.concat((train.loc[:, 'MSSubClass':'SaleCondition'],
                          test.loc[:, 'MSSubClass':'SaleCondition']))

将train和test所有样本从MSSubClass到SaleCondition的数据拼接。

4.pandas.get_dummies

作用:

Convert categorical variable into dummy/indicator variables

译文:将类别变量转换为虚拟/指示变量

例子:

s1 = ['a', 'b', np.nan]
pd.get_dummies(s1)

输出:

   a  b
0  1  0
1  0  1
2  0  0
pd.get_dummies(s1, dummy_na=True)
   a  b  NaN
0  1  0    0
1  0  1    0
2  0  0    1

该房价预测函数相关代码为:

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

也就是把像MSZoning这些非数值特征转化成数值特征。

详见:pandas.get_dummies

5.pandas.DataFrame.fillna

作用:填写缺省值

例子:

all_features = all_features.fillna(all_features.mean())

对于缺省的数值(NAN),则将已有数据的平均值填入其中。

详见:pandas.DataFrame.fillna

三、实现

主要代码:

def get_model():
    net = nn.Sequential(
        nn.Linear(feat_dim, 1),
        nn.ReLU(),
        nn.Linear(1,1)
    )
    return net

net = get_model()
print(net)
batch_size = 128  #64 256
epochs = 500
lr = 0.01
wd = 0
use_gpu = False

net = get_model()
train_model(net, train_features, train_labels, valid_features, valid_labels, epochs, 
            batch_size, lr, wd, use_gpu)
def train_model(model, x_train, y_train, x_valid, y_valid, epochs, batch_size, lr, weight_decay, use_gpu):
    if use_gpu:
        model = model.cuda()
    metric_log = defaultdict(list)

    train_data = get_data(x_train, y_train, batch_size, True)
    if x_valid is not None:
        valid_data = get_data(x_valid, y_valid, batch_size, False)
    else:
        valid_data = None

    optimizer = torch.optim.Adam(model.parameters(), lr=lr, weight_decay=weight_decay)
    criterion = nn.MSELoss()

    for e in range(epochs):
        # 训练模型
        model.train()
        for data in train_data:
            x, y = data
            if use_gpu:
                x = x.cuda()
                y = y.cuda()
            # forward
            out = model(x)
            loss = criterion(out, y)
            # backward
            optimizer.zero_grad()
            loss.backward()
            # update all parameters after computing gradients
            optimizer.step()

        metric_log['train_rmse'].append(get_rmse(model, x_train, y_train, use_gpu))

        # 测试模型
        if x_valid is not None:
            metric_log['valid_rmse'].append(get_rmse(model, x_valid, y_valid, use_gpu))
            print_str = 'epoch: {}, train rmse: {:.3f}, valid rmse: {:.3f}' \
                .format(e + 1, metric_log['train_rmse'][-1], metric_log['valid_rmse'][-1])
        else:
            print_str = 'epoch: {}, train rmse: {:.3f}'.format(e + 1, metric_log['train_rmse'][-1])
        if (e + 1) % 10 == 0:
            print(print_str)
            print()

    # 可视化
    figsize = (10, 5)
    fig = plt.figure(figsize=figsize)
    plt.plot(metric_log['train_rmse'], color='red', label='train')
    if valid_data is not None:
        plt.plot(metric_log['valid_rmse'], color='blue', label='valid')
    plt.legend(loc='best')
    plt.xlabel('epochs')
    plt.ylabel('loss')
    plt.show()

在评估模型的时候,为了保证大的价格和小的价格对模型都有着近似相同的影响,我们不会直接使用前面定义的均方误差作为最后的评价函数,我们会对预测的价格和真实的价格取 log,然后计算他们之间均方误差的平方根来作为评价指标。

def get_rmse(model, feature, label, use_gpu):
    if use_gpu:
        feature = feature.cuda()
        label = label.cuda()
    model.eval()
    mse_loss = nn.MSELoss()
    with torch.no_grad():
        pred = model(feature)
    # clipped_pred = pred.clamp(1, float('inf'))
    rmse = (mse_loss(pred, label)).sqrt()
    return rmse.item()

保存成csv格式

def pred(net, test_data, test_features):
    net = net.eval()
    net = net.cpu()
    with torch.no_grad():
        preds = net(test_features)
    preds = np.exp(preds.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)

(感谢宇哥)

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值