栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

从0开始的kaggle之旅小记——Getting Started competitions房价预测(二)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

从0开始的kaggle之旅小记——Getting Started competitions房价预测(二)

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import sklearn
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import KFold
import torch
from torch import nn
from torch.utils.data import Dataset,DataLoader
from torch.utils.data import TensorDataset

import warnings
def ignore_warn(*args, **kwargs):
    pass
warnings.warn = ignore_warn 


#load data
train = pd.read_csv('traindata.csv',index_col='Id')
test = pd.read_csv('testdata.csv',index_col='Id')

Xtrain = train.drop(labels='SalePrice',axis=1)
ytrain = train['SalePrice'].values

# normalization
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_n = scaler.fit_transform(Xtrain)
test_n = scaler.transform(test)
写在前面

接下来就是将预处理好的数据喂给机器学习的模型训练。需要说明的是,查阅了几个大佬的高分代码可以看出,比较好的方式是调包(划掉)训练多个机器学习模型并以stacking的方式组合。笔者复现类似的代码也得到了比单一模型要好得多的结果。不过做这个入门项目也不是追求预测准确度,原意是想借这一项目练习一下pytorch的最基础的一些用法,所以试一下用pytorch搭建神经网络(即使对于这个只有1455个样本的数据集用深度学习可以说是杀鸡用牛刀)

数据清洗和特征工程的步骤在上一篇文章里:(一)特征工程

数据集构建

X_train = torch.tensor(X_n).float()
y_train = torch.tensor(ytrain).view(-1, 1).float()

X_test = torch.tensor(test_n).float()


datasets = torch.utils.data.TensorDataset(X_train, y_train)
train_iter = torch.utils.data.DataLoader(datasets, batch_size=10, shuffle=True)

这里有两种办法实现dataset类,一是直接构造

# class HouseDataset(Dataset):
#     def __init__(self,X,y):
#         self.X = X
#         self.y = y

#     def __len__(self):
#         return len(self.X)

#     def __getitem__(self, idx):
#         return self.X[idx,:],self.y[idx]



# data_train = HouseDataset(X=X_train,y=y_train)
# data_loader = DataLoader(data_train, batch_size=5, shuffle=True)
         

二是使用 TensorDataset 来将数据包装成Dataset类,再使用dataloader

from torch.utils.data import Dataset,DataLoader
from torch.utils.data import TensorDataset
 
data = TensorDataset(X_train, y_train)
搭建神经网络

设置参数

# setting Hyperparameters
num_epochs = 400
learning_rate = 0.05
size_hidden1 = 600
size_hidden2 = 300
size_hidden3 = 300
size_hidden4 = 10
output_size = 1
input_size = Xtrain.shape[1]
K = 5
class HouseNet(nn.Module):
    def __init__(self,input_size, size_hidden1, size_hidden2,size_hidden3,output_size):
        super().__init__()
        self.lin1 = nn.Linear(input_size, size_hidden1)
        self.act1 = nn.ReLU()
        self.BatchNorm1d1 = nn.BatchNorm1d(size_hidden1, affine=False)
        self.drop1 = nn.Dropout(0.3)
        self.lin2 = nn.Linear(size_hidden1, size_hidden2)
        self.act2 = nn.ReLU()
        self.BatchNorm1d2 = nn.BatchNorm1d(size_hidden2, affine=False)
        self.drop2 = nn.Dropout(0.3)
        self.lin3 = nn.Linear(size_hidden2, size_hidden3)
        self.act3 = nn.ReLU()
        self.BatchNorm1d3 = nn.BatchNorm1d(size_hidden3, affine=False)
        self.drop3 = nn.Dropout(0.3)
        self.lin4 = nn.Linear(size_hidden3, size_hidden4)
        self.act4 = nn.ReLU()
        self.BatchNorm1d4 = nn.BatchNorm1d(size_hidden4, affine=False)
        self.lin5 = nn.Linear(size_hidden4,output_size)

    def forward(self, input):
        lin1_out = self.lin1(input)
        lin1_out = self.BatchNorm1d1(lin1_out)
        lin1_out = self.drop1(lin1_out)
        act1_out = self.act1(lin1_out)
        lin2_out = self.lin2(act1_out)
        lin2_out = self.BatchNorm1d2(lin2_out)
        lin2_out = self.drop2(lin2_out)
        act2_out = self.act2(lin2_out)
        lin3_out = self.lin3(act2_out)
        lin3_out = self.BatchNorm1d3(lin3_out)
        lin3_out = self.drop3(lin3_out)
        act3_out3 = self.act3(lin3_out)
        lin4_out = self.lin4(act3_out3)
        lin4_out = self.BatchNorm1d4(lin4_out)
        act4_out4 = self.act4(lin4_out)
        lin5_out = self.lin5(act4_out4)
        return lin5_out

初始化参数函数

def reset_weights(model):
  '''
    Try resetting model weights to avoid
    weight leakage.
  '''
  for layer in model.children():
    if hasattr(layer, 'reset_parameters'):
      layer.reset_parameters()
    

定义神经网络的训练函数

def trainnetwork(X):
    model = HouseNet(input_size, size_hidden1, size_hidden2,size_hidden3,output_size)
    model.train()
    model.apply(reset_weights)
    # Loss and optimizer
    criterion = nn.MSELoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
    Xloarder = torch.utils.data.DataLoader(X, batch_size=50,shuffle=True)
    total_step = len(Xloarder)
    losslist = pd.DataFrame({'loss' : [0.0]})
    
    for epoch in range(num_epochs):
        
        for i,(trainX,trainy) in enumerate(Xloarder):
            # Forward pass
            outputs = model(trainX)
            loss = criterion(outputs, trainy)

            # Backward and optimize
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            
            if (i+1) % total_step == 0:
                print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' 
                    .format(epoch+1, num_epochs, i+1, total_step, loss.item()))
                losslist.loc[str(epoch)] = loss.item()

    return model,losslist

测试函数,绘制一下学习曲线

model,losslist = trainnetwork(data)
Epoch [1/400], Step [30/30], Loss: 22.5647
Epoch [2/400], Step [30/30], Loss: 4.2579
Epoch [3/400], Step [30/30], Loss: 8.2732
Epoch [4/400], Step [30/30], Loss: 5.2298
Epoch [5/400], Step [30/30], Loss: 0.7501
Epoch [6/400], Step [30/30], Loss: 0.2774
Epoch [7/400], Step [30/30], Loss: 0.9184
Epoch [8/400], Step [30/30], Loss: 4.9067
Epoch [9/400], Step [30/30], Loss: 1.1154
Epoch [10/400], Step [30/30], Loss: 3.6600
Epoch [11/400], Step [30/30], Loss: 3.1540
Epoch [12/400], Step [30/30], Loss: 1.3145
...
Epoch [393/400], Step [30/30], Loss: 0.0221
Epoch [394/400], Step [30/30], Loss: 0.0039
Epoch [395/400], Step [30/30], Loss: 0.0204
Epoch [396/400], Step [30/30], Loss: 0.0253
Epoch [397/400], Step [30/30], Loss: 0.0529
Epoch [398/400], Step [30/30], Loss: 0.0701
Epoch [399/400], Step [30/30], Loss: 0.0187
Epoch [400/400], Step [30/30], Loss: 0.0368
losslist[1:].plot()
 

K折交叉验证

定义测试函数,输出为该model的rmse误差

def testmse(X,model):
    Xloarder = torch.utils.data.DataLoader(X, batch_size=10,shuffle=True,drop_last = True)
    rmse = 0.0
    with torch.no_grad():
        for i,(X,y) in enumerate(Xloarder):
            y_pre = model(X).numpy()
            y = y.numpy()
            rmse += sklearn.metrics.mean_squared_error(y, y_pre,squared=False)

    rmse = rmse/len(Xloarder)
    return rmse

算一下之前训练的网络的rmse误差

testmse(data,model)
0.21277317800398532

交叉验证主函数

kfold = KFold(n_splits=K,random_state=43, shuffle=True)
models = []
mses = []
for i, (train_idx, test_idx) in enumerate(kfold.split(data)):
    Ktrain = torch.utils.data.Subset(data, train_idx)
    Ktest = torch.utils.data.Subset(data,test_idx)

    model,_ = trainnetwork(Ktrain)
    models += [model]
    mse = testmse(Ktest,model)
    mses += [mse]

msesd = np.round(np.array(mses),decimals=4)
plt.bar([1,2,3,4,5],msesd, width = 0.5, align = 'center', label = 'rmse')
for a,b in zip([1,2,3,4,5],msesd):
    plt.text(a,b,b,ha = 'center', va = 'bottom', fontsize = 12)
    
plt.legend()


可以看到吻合得不是特别好但反正搭这个也不是为了排名所以我们下次努力吧

from numpy import *
mean_mse = mean(mses)
print(f'几个模型的误差为{mses}')
print(f'平均误差为{mean_mse}')
几个模型的误差为[0.20241131813361726, 0.19209420141474953, 0.19965740986939134, 0.2314058002726785, 0.2180823195597221]
平均误差为0.20873020985003174

最后做出预测,将K个模型的结果做一个平均,得出预测结果。

pre_num = np.zeros((len(test),K))
for i,model in enumerate(models):
    ypre = model(X_test)
    ypre = ypre.detach().numpy()
    pre_num[:,i] = ypre.ravel()

ypredic = mean(pre_num,axis=1)

提交数据~

ypredic = np.expm1(ypredic)
ypredic
array([121556.59045634, 158763.30902425, 183182.03429701, ...,
       155690.86633615, 113216.03077972, 201623.90664553])
submission = pd.DataFrame({'SalePrice':ypredic},index=test.index)

submission.to_csv('Sublib.csv')
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/997111.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号