深度学习(五) 深度学习的基础 实战:预测房价 pytorch新手入门及常见问题解决

##实战房价预测
import hashlib
import os
import tarfile
import zipfile
import requests
import pandas as pd
import numpy as np
import torch
from torch import nn
from d2l import torch as d2l

data_hub = dict()#数据集名称的字符串映射到数据集相关的二元组上
#这个二元组包含数据集的url和验证文件完整性的sha-1密钥
data_url = "<http://d2l-data.s3-accelerate.amazonaws.com/>"
##下载数据集
def download(name,xiazialujin =os.path.join('..','data')):
    #在没完善一个程序之前,我们不知道程序在哪里会出错,与其让它在运行时崩溃,不如在出现错误条件时就崩溃。
    assert name in data_hub,f"{name}不存在于{data_hub}"
    #  我们经常用浏览器访问各种网页,也经常会在浏览器的地址栏中输入网址,也叫地址。这里经常说的“网址”“地址”,其实叫URL更准确。
    url,ha1_harh = data_hub[name]
    os.makedirs(xiazialujin,exist_ok=True)#用于新建文件夹 exist_ok=True若文件夹存在则不会再建
    #os.path.join()函数用于路径拼接文件路径,可以传入多个路径。
    fname = os.path.join(xiazialujin,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:
                    break
                sha1.update(data)
        if sha1.hexdigest() ==ha1_harh:#返回摘要,作为十六进制数据字符串值
            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
##下载解压zip文件
def xiazaiyasuo(name,floder =None):
    fname = download(name)
    base = os.path.dirname(fname)#去掉文件名,返回目录
    data,est = os.path.splitext(fname)#将文件名和扩展名分开
    if est == '.zip':
        fp = zipfile.ZipFile(fname,'r')
    elif est in ('.tar','.gz'):
        fp = tarfile.open(fname,'r')
    else:
        assert False
    fp.extractall(base)
    return  os.path.join(base,floder) if floder else  data
##下载所有数据集.
def xiazaishujuzji():
    for name in data_hub:
        download(name)

data_hub['kaggle_house_train'] = (  #@save
    data_url + 'kaggle_house_pred_train.csv',
    '585e9cc93e70b39160e7921475f9bcd7d31219ce')

data_hub['kaggle_house_test'] = (  #@save
    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'))
#pandas.concat()通常用来连接DataFrame对象。默认情况下是对两个DataFrame对象进行纵向连接,
# 当然通过设置参数,也可以通过它实现DataFrame对象的横向连接。
#第一个特征是ID, 这有助于模型识别每个训练样本。 虽然这很方便,但它不携带任何用于预测的信息。 因此,在将数据提供给模型之前,我们将其从数据集中删除。
suoyoutezheng = pd.concat((train_data.iloc[:,1:-1],test_data.iloc[:,1:]))

###数据预处理

# 若无法获得测试数据,则可根据训练数据计算均值和标准差
n_tezhen = suoyoutezheng.dtypes[suoyoutezheng.dtypes != 'object'].index
#我们将所有缺失的值替换为相应特征的平均值。
# 为了将所有特征放在一个共同的尺度上, 我们通过将特征重新缩放到零均值和单位方差来标准化数据:
suoyoutezheng[n_tezhen] = suoyoutezheng[n_tezhen].apply(lambda x:(x-x.mean())/(x.std()))
suoyoutezheng[n_tezhen] = suoyoutezheng[n_tezhen].fillna(0)

#独热编码(One-Hot Encoding),又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,
# 每个状态都有它独立的寄存器位,并且在任意时候,其中只有一位有效。即,只有一位是1,其余都是零值。
# 独热编码 是利用0和1表示一些参数,使用N位状态寄存器来对N个状态进行编码。
#<https://blog.csdn.net/yanghaoji/article/details/123734304?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168206911516800188531668%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168206911516800188531668&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-123734304-null-null.142^v86^koosearch_v1,239^v2^insert_chatgpt&utm_term=%E7%8B%AC%E7%83%AD%E7%BC%96%E7%A0%81&spm=1018.2226.3001.4187>
## “Dummy_na=True”将“na”(缺失值)视为有效的特征值,并为其创建指示符特征
suoyoutezheng = pd.get_dummies(suoyoutezheng,dummy_na=True)

n_train = train_data.shape[0]
train_tezhen = torch.tensor(suoyoutezheng[:n_train].values,dtype= torch.float32)
test_tezhen = torch.tensor(suoyoutezheng[n_train:].values,dtype=torch.float32)
train_biaoqian = torch.tensor(train_data.SalePrice.values.reshape(-1,1),dtype=torch.float32)

##训练
loss = nn.MSELoss()
in_tezhen = train_tezhen.shape[1]
def get_net():
    net = nn.Sequential(nn.Linear(in_tezhen,1))
    return net

def quduishu(net,tezhen,biaoqian):
    #将输入input张量每个元素的夹紧到区间 [min,max][min,max],并返回结果到一个新张量。
    #小于1的会被置为1
    preds = torch.clamp(net(tezhen),1,float('inf'))
    rmse = torch.sqrt(loss(torch.log(preds),torch.log(biaoqian)))
    return rmse.item()

def train(net,train_tezhen,train_biaoqian,test_tezhen,test_biaoqian,xunliancishu,
          xuexilv,shuaijianzhishu,batch):
    train_s,test_s =[],[]
    train_iter = d2l.load_array((train_tezhen,train_biaoqian),batch)
    youhuaqi = torch.optim.Adam(net.parameters(),lr=xuexilv,weight_decay=shuaijianzhishu)
    for cishu in range(xunliancishu):
        for x,y in train_iter:
            youhuaqi.zero_grad()
            l =loss(net(x),y)
            l.backward()
            youhuaqi.step()
        train_s.append(quduishu(net,train_tezhen,train_biaoqian))
        if test_biaoqian is not None:
            test_s.append(quduishu(net,test_tezhen,test_biaoqian))
    return train_s,test_s

#k则交叉验证

def Kzejiaochayanzheng(k,i,x,y):
    assert k>1
    fold_size = x.shape[0]//k
    x_train,y_train = None,None
    for 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_part
        elif x_train is None:
            x_train,y_train = x_part,y_part
        else:
            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折交叉验证中训练k次后,返回训练和验证误差的平均值。
def K_fold(k,x_train,y_train,xunliancishu,xuexilv,shuaijianzhishu ,batch):
    train_l_sum,test_l_sum = 0,0
    for i in range(k):
        data = Kzejiaochayanzheng(k,i,x_train,y_train)
        net = get_net()
        train_s,valid_s = train(net,*data,xunliancishu,xuexilv,shuaijianzhishu,batch)
        train_l_sum +=train_s[-1]
        test_l_sum  +=valid_s[-1]
        if i == 0:
            d2l.plot(list(range(1,xunliancishu+1)),[train_s,valid_s],
                     xlabel='cishu',ylabel='rmse',xlim=[1,xunliancishu],
                     legend=['train','valid'],yscale='log')
        print(f'折{i + 1},训练log rmse{float(train_s[-1]):f}, '
              f'验证log rmse{float(valid_s[-1]):f}')
    return train_l_sum/k,test_l_sum/k
##模型选择
k,xunliancishu,xuexilv,shuaijianquanzhon,batch = 10,300,5,0,64
train_l,valid_l = K_fold(k,train_tezhen,train_biaoqian,xunliancishu,xuexilv,shuaijianquanzhon,batch)

print(f'{k}-折验证: 平均训练log rmse: {float(train_l):f}, '
      f'平均验证log rmse: {float(valid_l):f}')
d2l.plt.show()

第二和第七:10行代码战胜90%数据科学家?_哔哩哔哩_bilibili

第三h2o:AutoML(Using h2o) | Kaggle

第四 随机森林:The 4th place approach (Random Forest) | Kaggle

automal:(10条消息) 机器学习实战 | AutoML自动化机器学习建模_automl安装-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值