中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

淘寶上做網站國際新聞直播

淘寶上做網站,國際新聞直播,張家界做網站的,wordpress媒體1m以上目錄 下載和緩存數據集訪問和讀取數據集總代碼 數據預處理訓練K折交叉驗證模型選擇總代碼提交你的Kaggle預測提交Kaggle 下載和緩存數據集 import hashlib import os import tarfile import zipfile import requests# download傳遞的參數分別是數據集的名稱、緩存文件夾的路徑…

目錄

  • 下載和緩存數據集
  • 訪問和讀取數據集
    • 總代碼
  • 數據預處理
  • 訓練
  • K折交叉驗證
  • 模型選擇
  • 總代碼
  • 提交你的Kaggle預測
  • 提交Kaggle

下載和緩存數據集

import hashlib
import os
import tarfile
import zipfile
import requests# download傳遞的參數分別是數據集的名稱、緩存文件夾的路徑
def download(name, cache_dir=os.path.join('..', 'data')):  # @save"""下載一個DATA_HUB中的文件,返回本地文件名"""# 檢查變量name是否存在于名為DATA_HUB的字典中,如果是異常則給出消息提示assert name in DATA_HUB, f"{name} 不存在于 {DATA_HUB}"# 檢查與name相對應的元組并解包賦值給url和sha1_hashurl, sha1_hash = DATA_HUB[name]os.makedirs(cache_dir, exist_ok=True)# 緩存的路徑和目標目錄,[-1]:url指向文件名fname = os.path.join(cache_dir, url.split('/')[-1])if os.path.exists(fname): # 檢查文件是否存在sha1 = hashlib.sha1() # 計算文件的哈希值,初始化哈希對象# with確保文件在使用后正確關閉with open(fname, 'rb') as f: # 讀取文件內容while True: # 循環(huán)讀取文件內容并更新哈希對象data = f.read(1048576) # 讀取1MB到dataif not data: # 為真跳出break# 將讀取到的數據塊更新到哈希對象中sha1.update(data)# 檢查計算出的哈希值是否與預期的哈希值匹配if sha1.hexdigest() == sha1_hash:return fname  # 命中緩存print(f'正在從{url}下載{fname}...')# 發(fā)送get請求并設置stream=True支持流式傳輸r = requests.get(url, stream=True, verify=True)with open(fname, 'wb') as f: # 寫入模式f.write(r.content)return fname# folder=None是指解壓后數據應存放的文件名,如未指定則默認使用去除擴展名后的文件名作為文件夾名
def download_extract(name, folder=None):  # @save"""下載并解壓zip/tar文件"""# 下載文件,并返回下載的完整路徑fnamefname = download(name)# 獲取下載文件所在的基本目錄base_dir = os.path.dirname(fname)# 從文件名中分離出擴展名exe和數據目錄data_dir, ext = os.path.splitext(fname)# 根據文件類型打開文件if ext == '.zip':fp = zipfile.ZipFile(fname, 'r')elif ext in ('.tar', '.gz'):fp = tarfile.open(fname, 'r')else:assert False, '只有zip/tar文件可以被解壓縮'# 使用extractall方法將文件解壓到基本目錄,如果指定了folder參數,則返回base_dir和folder組合的路徑# 否則返回去除擴展名后的文件名作為路徑fp.extractall(base_dir)return os.path.join(base_dir, folder) if folder else data_dirdef download_all():  # @save"""下載DATA_HUB中的所有文件"""for name in DATA_HUB:download(name)# @save
DATA_HUB = dict() # 這是一個字典,用來存儲數據集的信息。
DATA_URL = 'http://d2l-data.s3-accelerate.amazonaws.com/' # 指向一個存儲了多個數據集文件的服務器



訪問和讀取數據集

import numpy as np
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2l

下載并緩存Kaggle房屋數據集

DATA_HUB['kaggle_house_train'] = (  #@saveDATA_URL + 'kaggle_house_pred_train.csv','585e9cc93e70b39160e7921475f9bcd7d31219ce')DATA_HUB['kaggle_house_test'] = (  #@saveDATA_URL + 'kaggle_house_pred_test.csv','fa19780a7b011d9b009e8bff8e99922a8ee2eb90')

使用pandas分別加載包含訓練數據和測試數據的兩個CSV文件

train_data = pd.read_csv(download('kaggle_house_train'))
test_data = pd.read_csv(download('kaggle_house_test'))

輸出:

在這里插入圖片描述


訓練數據集包括1460個樣本,每個樣本80個特征和1個標簽, 而測試數據集包含1459個樣本,每個樣本80個特征。
print(train_data.shape)
print(test_data.shape)

輸出:
在這里插入圖片描述


查看前四個最后兩個特征,以及相應標簽(房價)。

print(train_data.iloc[0:4, [0, 1, 2, 3, -3, -2, -1]])

輸出:
在這里插入圖片描述

在每個樣本中,第一個特征是ID, 這有助于模型識別每個訓練樣本。 雖然這很方便,但它不攜帶任何用于預測的信息。 因此,在將數據提供給模型之前,(我們將其從數據集中刪除)。

# 刪除train_data的第一列ID和最后一列房價;刪除test_data的第一列索引
all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))
# 查看一下
print(all_features)

輸出:

在這里插入圖片描述




總代碼

import hashlib
import os
import tarfile
import zipfile
import requests
import pandas as pd# download傳遞的參數分別是數據集的名稱、緩存文件夾的路徑
def download(name, cache_dir=os.path.join('..', 'data')):  # @save"""下載一個DATA_HUB中的文件,返回本地文件名"""# 檢查變量name是否存在于名為DATA_HUB的字典中,如果是異常則給出消息提示assert name in DATA_HUB, f"{name} 不存在于 {DATA_HUB}"# 檢查與name相對應的元組并解包賦值給url和sha1_hashurl, sha1_hash = DATA_HUB[name]os.makedirs(cache_dir, exist_ok=True)# 緩存的路徑和目標目錄,[-1]:url指向文件名fname = os.path.join(cache_dir, url.split('/')[-1])if os.path.exists(fname): # 檢查文件是否存在sha1 = hashlib.sha1() # 計算文件的哈希值,初始化哈希對象# with確保文件在使用后正確關閉with open(fname, 'rb') as f: # 讀取文件內容while True: # 循環(huán)讀取文件內容并更新哈希對象data = f.read(1048576) # 讀取1MB到dataif not data: # 為真跳出break# 將讀取到的數據塊更新到哈希對象中sha1.update(data)# 檢查計算出的哈希值是否與預期的哈希值匹配if sha1.hexdigest() == sha1_hash:return fname  # 命中緩存print(f'正在從{url}下載{fname}...')# 發(fā)送get請求并設置stream=True支持流式傳輸r = requests.get(url, stream=True, verify=True)with open(fname, 'wb') as f: # 寫入模式f.write(r.content)return fname# folder=None是指解壓后數據應存放的文件名,如未指定則默認使用去除擴展名后的文件名作為文件夾名
def download_extract(name, folder=None):  # @save"""下載并解壓zip/tar文件"""# 下載文件,并返回下載的完整路徑fnamefname = download(name)# 獲取下載文件所在的基本目錄base_dir = os.path.dirname(fname)# 從文件名中分離出擴展名exe和數據目錄data_dir, ext = os.path.splitext(fname)# 根據文件類型打開文件if ext == '.zip':fp = zipfile.ZipFile(fname, 'r')elif ext in ('.tar', '.gz'):fp = tarfile.open(fname, 'r')else:assert False, '只有zip/tar文件可以被解壓縮'# 使用extractall方法將文件解壓到基本目錄,如果指定了folder參數,則返回base_dir和folder組合的路徑# 否則返回去除擴展名后的文件名作為路徑fp.extractall(base_dir)return os.path.join(base_dir, folder) if folder else data_dirdef download_all():  # @save"""下載DATA_HUB中的所有文件"""for name in DATA_HUB:download(name)# @save
DATA_HUB = dict() # 這是一個字典,用來存儲數據集的信息。
DATA_URL = 'http://d2l-data.s3-accelerate.amazonaws.com/' # 指向一個存儲了多個數據集文件的服務器
# 第二個參數:表示數據集文件的哈希值,用哈希值驗證文件的完整性
DATA_HUB['kaggle_house_train'] = (DATA_URL + 'kaggle_house_pred_train.csv','585e9cc9370b9160e7921475fbcd7d31219ce')
DATA_HUB['kaggle_house_test'] = (DATA_URL + 'kaggle_house_pred_test.csv', 'fal9780a7b011d9b009e8bff8e99922a8ee2eb90')
# 讀取路徑指向的csv文件
train_data = pd.read_csv(download('kaggle_house_train'))
test_data = pd.read_csv(download('kaggle_house_test'))print(train_data.shape) # 1460個樣本,80個特征,1個標號label
print(test_data.shape) # 測試樣本沒有標號label
print(train_data.iloc[0:4,[0,1,2,3,-3,-2,-1]]) # 前面四行的某些列特征

輸出:
在這里插入圖片描述




數據預處理

如上所述,我們有各種各樣的數據類型。 在開始建模之前,我們需要對數據進行預處理。 首先,我們將所有缺失的值替換為相應特征的平均值。然后,為了將所有特征放在一個共同的尺度上, 我們通過將特征重新縮放到零均值和單位方差來標準化數據在這里插入圖片描述其中 𝜇 和 𝜎 分別表示均值和標準差。 現(xiàn)在,這些特征具有零均值和單位方差,即 在這里插入圖片描述在這里插入圖片描述
直觀地說,我們標準化數據有兩個原因: 首先,它方便優(yōu)化。 其次,因為我們不知道哪些特征是相關的, 所以我們不想讓懲罰分配給一個特征的系數比分配給其他任何特征的系數更大。

# 若無法獲得測試數據,則可根據訓練數據計算均值和標準差
# all_features.dtypes 獲取每個特征的數據類型
# all_features.dtypes != 'object' 返回一個布爾值的 Series,其中為 True 的位置表示對應的特征不是對象類型(即數值類型)
# .index 提取數值類型特征的索引,并在numeric_features中存儲
print(all_features.dtypes) # 可以知道每一列分別為什么類型特征
numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index
print(numeric_features)
# 對all_features中所有數值類型特征進行標準化處理
all_features[numeric_features] = all_features[numeric_features].apply(lambda x: (x - x.mean()) / (x.std()))
# 在標準化數據之后,所有均值消失,因此我們可以將缺失值設置為0
all_features[numeric_features] = all_features[numeric_features].fillna(0)

輸出:
在這里插入圖片描述




接下來,我們處理離散值。 這包括諸如“MSZoning”之類的特征。我們用獨熱編碼替換它們), 例如,“MSZoning”包含值“RL”和“Rm”。 我們將創(chuàng)建兩個新的指示器特征“MSZoning_RL”和“MSZoning_RM”,其值為01。 根據獨熱編碼,如果“MSZoning”的原始值為“RL”, 則:“MSZoning_RL”為1,“MSZoning_RM”為0。 pandas軟件包會自動為我們實現(xiàn)這一點。

# “Dummy_na=True”將“na”(缺失值)視為有效的特征值,并為其創(chuàng)建指示符特征
# 未指定column時,pd.get_dummies函數默認轉換所有的分類列,包括MSZoning、SaleType、SaleCondition
# pd.get_dummies每個分類變量都會被轉換成多列,每個唯一值對應一列
# 理解意思:某列有五類值,就將此列等價于變成五列,然后對應的列置1,不存在的列置0
all_features = pd.get_dummies(all_features, dummy_na=True)

未改變時的數據特征:

# 這里僅驗證看一下特征的形狀
print(all_features.shape)

輸出:
在這里插入圖片描述


改變后:

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

輸出:
在這里插入圖片描述
可以看到此轉換會將特征的總數量從79個(去掉ID)增加到331個。



最后,通過values屬性,我們可以從pandas格式中提取NumPy格式,并將其轉換為張量表示用于訓練。

# 獲取訓練集的行數,即訓練樣本數量,并將其存儲在n_train中
n_train = train_data.shape[0]
# [:n_train].values是選擇前n_train作為訓練集的特征將數據轉換為Numpy數組
train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float32)
test_features = torch.tensor(all_features[n_train:].values, dtype=torch.float32)
# 將SalePrice列單獨提取為標簽
train_labels = torch.tensor(train_data.SalePrice.values.reshape(-1, 1), dtype=torch.float32)



訓練

首先,我們訓練一個帶有損失平方的線性模型。 顯然線性模型很難讓我們在競賽中獲勝,但線性模型提供了一種健全性檢查,以查看數據中是否存在有意義的信息。 如果我們在這里不能做得比隨機猜測更好,那么我們很可能存在數據處理錯誤。 如果一切順利,線性模型將作為基線(baseline)模型, 讓我們直觀地知道最好的模型有超出簡單的模型多少。

loss = nn.MSELoss()
in_features = train_features.shape[1]def get_net():net = nn.Sequential(nn.Linear(in_features,1))return net

房價就像股票價格一樣,我們關心的是相對數量,而不是絕對數量。因此,我們更關心相對誤差,而不是絕對誤差 。 例如,如果我們在俄亥俄州農村地區(qū)估計一棟房子的價格時,假設我們的預測偏差了10萬美元,然而那里一棟典型的房子的價值是12.5萬美元,那么模型可能做得很糟糕。另一方面,如果我們在加州豪宅區(qū)的預測出現(xiàn)同樣的10萬美元的偏差,(在那里,房價中位數超過400萬美元) 這可能是一個不錯的預測。

(解決這個問題的一種方法是用價格預測的對數來衡量差異)。 事實上,這也是比賽中官方用來評價提交質量的誤差指標。 即將在這里插入圖片描述轉換為在這里插入圖片描述。 這使得預測價格的對數真實標簽價格的對數之間出現(xiàn)以下均方根誤差
在這里插入圖片描述

# rmse=Root Mean Squared Error,對數均方根誤差
def log_rmse(net, features, labels):# 通過神經網絡net對輸入特征features進行前向傳播得到預測值# 然后為了在取對數時進一步穩(wěn)定該值,用torch.clamp()函數將小于1的值設置為1# 第三個參數:不設置上限,即預測可以無限大clipped_preds = torch.clamp(net(features), 1, float('inf'))rmse = torch.sqrt(loss(torch.log(clipped_preds),torch.log(labels)))# .item() 方法將rmse轉換為Python標量返回return rmse.item()

我們的訓練函數將借助Adam優(yōu)化器,Adam優(yōu)化器的主要吸引力在于它對初始學習率不那么敏感

# weight_decay權重衰退
def train(net, train_features, train_labels, test_features, test_labels,num_epochs, learning_rate, weight_decay, batch_size):# 用于存儲每一輪訓練和測試集上的log rmse值train_ls, test_ls = [], []train_iter = d2l.load_array((train_features, train_labels), batch_size)# 這里使用的是Adam優(yōu)化算法,Adam用于訓練過程中更新模型的權重,以最小化損失函數optimizer = torch.optim.Adam(net.parameters(),lr = learning_rate,weight_decay = weight_decay)for epoch in range(num_epochs):for X, y in train_iter:# 清空過往梯度optimizer.zero_grad()# 通過前向傳播計算損失值,然后計算預測值與真實值差異l = loss(net(X), y)l.backward() # 反向傳播計算當前梯度optimizer.step() # 更新模型參數# 將log_rmse函數返回的誤差值追加到train_ls列表中就記錄了每一輪迭代train_ls.append(log_rmse(net, train_features, train_labels))# 確保在提供了測試集的情況下計算測試集性能if test_labels is not None:test_ls.append(log_rmse(net, test_features, test_labels))return train_ls, test_ls



K折交叉驗證

K折交叉驗證有助于模型選擇和超參數調整。定義一個函數,在 𝐾 折交叉驗證過程中返回第 𝑖 折的數據。具體地說,它選擇第 𝑖 個切片作為驗證數據其余部分作為訓練數據。注意,這并不是處理數據的最有效方法,如果我們的數據集大得多,會有其他解決辦法。

# 四個參數:表示將數據集分為多少個子集、當前折的索引、特征數據集、標簽數據集
def get_k_fold_data(k, i, X, y):# 斷言確保折數大于1,因為至少兩個子集才能進行交叉驗證assert k > 1# 每個子集(折)的大小=數據集的總行數除以折數,余數在最后一個子集處理fold_size = X.shape[0] // k# 初始化訓練集X_train, y_train = None, Nonefor j in range(k):# idx將原始數據集的索引切片為 (j * fold_size) 到 ((j + 1) * fold_size),獲得當前折數據idx = slice(j * fold_size, (j + 1) * fold_size)X_part, y_part = X[idx, :], y[idx]# 當前折的索引 j 與指定用于驗證的索引 i 匹配,將該折的數據分配給驗證集(X_valid 和 y_valid)if j == i:# 將該折的數據分配給驗證集X_valid, y_valid = X_part, y_part# 如不匹配且訓練集為空(第一次看到),則將該折的數據分配給訓練集(X_train 和 y_train)elif X_train is None:X_train, y_train = X_part, y_part# 如不匹配且訓練集不為空,則將該折的數據追加到訓練集(X_train 和 y_train)中else:# 表示將X_train, X_part沿著第一個維度拼接起來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




在𝐾折交叉驗證中訓練𝐾次后,返回訓練和驗證誤差的平均值。

def k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay,batch_size):# 初始化該變量,用于累加每次折的訓練和驗證損失train_l_sum, valid_l_sum = 0, 0for i in range(k):# 做k次,每次拿到第i折,把數據data拿出來即拿到從訓練集和驗證集data = get_k_fold_data(k, i, X_train, y_train)# 每次循環(huán)都會創(chuàng)建一個新的模型實例,確保每折的評估是獨立的net = get_net()# 調用train函數訓練模型并返回訓練損失列表和驗證損失列表train_ls, valid_ls = train(net, *data, num_epochs, learning_rate,weight_decay, batch_size)# 索引[-1]獲取最后一個epoch的損失,即當前折的訓練損失累加到train_l_sum train_l_sum += train_ls[-1]valid_l_sum += valid_ls[-1]if i == 0: # 如果當前是第i折# 第一個參數:用作x軸數據# 第二個參數:一個列表儲存了每一輪訓練后的訓練損失和驗證損失d2l.plot(list(range(1, num_epochs + 1)), [train_ls, valid_ls],xlabel='epoch', ylabel='rmse', xlim=[1, num_epochs],legend=['train', 'valid'], yscale='log')print(f'折{i + 1},訓練log rmse{float(train_ls[-1]):f}, 'f'驗證log rmse{float(valid_ls[-1]):f}')# 返回平均訓練損失和平均驗證損失return train_l_sum / k, valid_l_sum / k



模型選擇

在本例中,我們選擇了一組未調優(yōu)的超參數,并將其留給讀者來改進模型。找到一組調優(yōu)的超參數可能需要時間,這取決于一個人優(yōu)化了多少變量。有了足夠大的數據集和合理設置的超參數,K折交叉驗證往往對多次測試具有相當的穩(wěn)定性。然而,如果我們嘗試了不合理的超參數,我們可能會發(fā)現(xiàn)驗證效果不再代表真正的誤差。

#數據集被分成了5份,然后執(zhí)行5次訓練和驗證過程,每次過程中,4份數據用于訓練模型,剩下的一份用于
k, num_epochs, lr, weight_decay, batch_size = 5, 100, 5, 0, 64
# 分別包含每次迭代的訓練集和驗證集的log rmse值
train_l, valid_l = k_fold(k, train_features, train_labels, num_epochs, lr,weight_decay, batch_size)
print(f'{k}-折驗證: 平均訓練log rmse: {float(train_l):f}, 'f'平均驗證log rmse: {float(valid_l):f}')

我們關心的是平均驗證log rmse




總代碼

import hashlib
import os
import tarfile
import zipfile
import requests
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2ldef download(name, cache_dir=os.path.join('..', 'data')):  # @save"""下載一個DATA_HUB中的文件,返回本地文件名"""assert name in DATA_HUB, f"{name} 不存在于 {DATA_HUB}"url, sha1_hash = DATA_HUB[name]os.makedirs(cache_dir, exist_ok=True)fname = os.path.join(cache_dir, 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:breaksha1.update(data)if sha1.hexdigest() == sha1_hash: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 fnamedef download_extract(name, folder=None):  # @save"""下載并解壓zip/tar文件"""fname = download(name)base_dir = os.path.dirname(fname)data_dir, ext = os.path.splitext(fname)if ext == '.zip':fp = zipfile.ZipFile(fname, 'r')elif ext in ('.tar', '.gz'):fp = tarfile.open(fname, 'r')else:assert False, '只有zip/tar文件可以被解壓縮'fp.extractall(base_dir)return os.path.join(base_dir, folder) if folder else data_dirdef download_all():  # @save"""下載DATA_HUB中的所有文件"""for name in DATA_HUB:download(name)def get_net():net = nn.Sequential(nn.Linear(in_features, 1))return net# rmse=Root Mean Squared Error,對數均方根誤差
def log_rmse(net, features, labels):# 通過神經網絡net對輸入特征features進行前向傳播得到預測值# 然后為了在取對數時進一步穩(wěn)定該值,用torch.clamp()函數將小于1的值設置為1# 第三個參數:不設置上限,即預測可以無限大clipped_preds = torch.clamp(net(features), 1, float('inf'))rmse = torch.sqrt(loss(torch.log(clipped_preds),torch.log(labels)))# .item() 方法將rmse轉換為Python標量返回return rmse.item()# weight_decay權重衰退
def train(net, train_features, train_labels, test_features, test_labels,num_epochs, learning_rate, weight_decay, batch_size):# 用于存儲每一輪訓練和測試集上的log rmse值train_ls, test_ls = [], []train_iter = d2l.load_array((train_features, train_labels), batch_size)# 這里使用的是Adam優(yōu)化算法,Adam用于訓練過程中更新模型的權重,以最小化損失函數optimizer = torch.optim.Adam(net.parameters(),lr=learning_rate,weight_decay=weight_decay)for epoch in range(num_epochs):for X, y in train_iter:# 清空過往梯度optimizer.zero_grad()# 通過前向傳播計算損失值,然后計算預測值與真實值差異l = loss(net(X), y)l.backward()  # 反向傳播計算當前梯度optimizer.step()  # 更新模型參數# 將log_rmse函數返回的誤差值追加到train_ls列表中就記錄了每一輪迭代train_ls.append(log_rmse(net, train_features, train_labels))# 確保在提供了測試集的情況下計算測試集性能if test_labels is not None:test_ls.append(log_rmse(net, test_features, test_labels))return train_ls, test_ls# 四個參數:表示將數據集分為多少個子集、當前折的索引、特征數據集、標簽數據集
def get_k_fold_data(k, i, X, y):# 斷言確保折數大于1,因為至少兩個子集才能進行交叉驗證assert k > 1# 每個子集(折)的大小=數據集的總行數除以折數,余數在最后一個子集處理fold_size = X.shape[0] // k# 初始化訓練集X_train, y_train = None, Nonefor j in range(k):# idx將原始數據集的索引切片為 (j * fold_size) 到 ((j + 1) * fold_size),獲得當前折數據idx = slice(j * fold_size, (j + 1) * fold_size)X_part, y_part = X[idx, :], y[idx]# 當前折的索引 j 與指定用于驗證的索引 i 匹配,將該折的數據分配給驗證集(X_valid 和 y_valid)if j == i:# 將該折的數據分配給驗證集X_valid, y_valid = X_part, y_part# 如不匹配且訓練集為空(第一次看到),則將該折的數據分配給訓練集(X_train 和 y_train)elif X_train is None:X_train, y_train = X_part, y_part# 如不匹配且訓練集不為空,則將該折的數據追加到訓練集(X_train 和 y_train)中else:# 表示將X_train, X_part沿著第一個維度拼接起來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_validdef k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay,batch_size):# 初始化該變量,用于累加每次折的訓練和驗證損失train_l_sum, valid_l_sum = 0, 0for i in range(k):# 做k次,每次拿到第i折,把數據data拿出來即拿到從訓練集和驗證集data = get_k_fold_data(k, i, X_train, y_train)# 每次循環(huán)都會創(chuàng)建一個新的模型實例,確保每折的評估是獨立的net = get_net()# 調用train函數訓練模型并返回訓練損失列表和驗證損失列表train_ls, valid_ls = train(net, *data, num_epochs, learning_rate,weight_decay, batch_size)# 索引[-1]獲取最后一個epoch的損失,即當前折的訓練損失累加到train_l_sumtrain_l_sum += train_ls[-1]valid_l_sum += valid_ls[-1]if i == 0:  # 如果當前是第i折# 第一個參數:用作x軸數據# 第二個參數:一個列表儲存了每一輪訓練后的訓練損失和驗證損失d2l.plot(list(range(1, num_epochs + 1)), [train_ls, valid_ls],xlabel='epoch', ylabel='rmse', xlim=[1, num_epochs],legend=['train', 'valid'], yscale='log')print(f'折{i + 1},訓練log rmse{float(train_ls[-1]):f}, 'f'驗證log rmse{float(valid_ls[-1]):f}')# 返回平均訓練損失和平均驗證損失return train_l_sum / k, valid_l_sum / k# @save
DATA_HUB = dict()
DATA_URL = 'http://d2l-data.s3-accelerate.amazonaws.com/'
DATA_HUB['kaggle_house_train'] = (DATA_URL + 'kaggle_house_pred_train.csv', '585e9cc9370b9160e7921475fbcd7d31219ce')
DATA_HUB['kaggle_house_test'] = (DATA_URL + 'kaggle_house_pred_test.csv', 'fal9780a7b011d9b009e8bff8e99922a8ee2eb90')
train_data = pd.read_csv(download('kaggle_house_train'))
test_data = pd.read_csv(download('kaggle_house_test'))# print(train_data.shape) # 1460個樣本,80個特征,1個標號label
# print(test_data.shape) # 測試樣本沒有標號label
# print(train_data.iloc[0:4,[0,1,2,3,-3,-2,-1]]) # 前面四行的某些列特征
all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))
# print(all_features.shape)# 若無法獲得測試數據,則可根據訓練數據計算均值和標準差
# all_features.dtypes 獲取每個特征的數據類型
# all_features.dtypes != 'object' 返回一個布爾值的 Series,其中為 True 的位置表示對應的特征不是對象類型(即數值類型)
# .index 提取數值類型特征的索引,并在numeric_features中存儲
# print(all_features.dtypes)  # 可以知道每一列分別為什么類型特征
numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index
# print(numeric_features)
# 對all_features中所有數值類型特征進行標準化處理
all_features[numeric_features] = all_features[numeric_features].apply(lambda x: (x - x.mean()) / (x.std()))
# 在標準化數據之后,所有均值消失,因此我們可以將缺失值設置為0
all_features[numeric_features] = all_features[numeric_features].fillna(0)# “Dummy_na=True”將“na”(缺失值)視為有效的特征值,并為其創(chuàng)建指示符特征
# 未指定column時,pd.get_dummies函數默認轉換所有的分類列,包括MSZoning、SaleType、SaleCondition
# pd.get_dummies每個分類變量都會被轉換成多列,每個唯一值對應一列
# 理解意思:某列有五類值,就將此列等價于變成五列,然后對應的列置1,不存在的列置0
all_features = pd.get_dummies(all_features, dummy_na=True)# 獲取訓練集的行數,即訓練樣本數量,并將其存儲在n_train中
n_train = train_data.shape[0]
# [:n_train].values是選擇前n_train作為訓練集的特征將數據轉換為Numpy數組
train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float32)
test_features = torch.tensor(all_features[n_train:].values, dtype=torch.float32)
# 將SalePrice列單獨提取為標簽
train_labels = torch.tensor(train_data.SalePrice.values.reshape(-1, 1), dtype=torch.float32)
loss = nn.MSELoss()
in_features = train_features.shape[1]# 數據集被分成了5份,然后執(zhí)行5次訓練和驗證過程,每次過程中,4份數據用于訓練模型,剩下的一份用于
k, num_epochs, lr, weight_decay, batch_size = 5, 100, 5, 0, 64
# 分別包含每次迭代的訓練集和驗證集的log rmse值
train_l, valid_l = k_fold(k, train_features, train_labels, num_epochs, lr,weight_decay, batch_size)
print(f'{k}-折驗證: 平均訓練log rmse: {float(train_l):f}, 'f'平均驗證log rmse: {float(valid_l):f}')

輸出:

在這里插入圖片描述
在這里插入圖片描述




提交你的Kaggle預測

既然我們知道應該選擇什么樣的超參數, 我們不妨使用所有數據對其進行訓練 (而不是僅使用交叉驗證中使用的 1? 1 K \frac 1K K1? 的數據)。 然后,我們通過這種方式獲得的模型可以應用于測試集。 將預測保存在CSV文件中可以簡化將結果上傳到Kaggle的過程。

def train_and_pred(train_features, test_features, train_labels, test_data,num_epochs, lr, weight_decay, batch_size):net = get_net()# 返回兩個值,一個包含每個epoch訓練,log mose的列表,一個未在代碼片段中使用的值train_ls, _ = train(net, train_features, train_labels, None, None,num_epochs, lr, weight_decay, batch_size)# 第一個參數和第二個參數:接收一個epoch數組和一個包含訓練log rmse的列表作為輸入d2l.plot(np.arange(1, num_epochs + 1), [train_ls], xlabel='epoch',ylabel='log rmse', xlim=[1, num_epochs], yscale='log')# 打印最后一個epoch訓練log rmse來評估模型的最終訓練性能print(f'訓練log rmse:{float(train_ls[-1]):f}')# 將訓練好的網絡模型應用于測試特征preds = net(test_features).detach().numpy()# 將其重新格式化以導出到Kaggle# pd.Series()封裝成一個Pandas的Series對象,以確保數據類型與DataFrame的列兼容。test_data['SalePrice'] = pd.Series(preds.reshape(1, -1)[0])submission = pd.concat([test_data['Id'], test_data['SalePrice']], axis=1)# 用于將DataFrame保存為csv文件submission.to_csv('submission.csv', index=False)

如果測試集上的預測𝐾 倍交叉驗證過程中的預測相似, 那就是時候把它們上傳到Kaggle了。 下面的代碼將生成一個名為submission.csv的文件。

train_and_pred(train_features, test_features, train_labels, test_data,num_epochs, lr, weight_decay, batch_size)

輸出:
在這里插入圖片描述

在這里插入圖片描述

import hashlib
import os
import tarfile
import zipfile
import requests
import numpy as np
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2ldef download(name, cache_dir=os.path.join('..', 'data')):  # @save"""下載一個DATA_HUB中的文件,返回本地文件名"""assert name in DATA_HUB, f"{name} 不存在于 {DATA_HUB}"url, sha1_hash = DATA_HUB[name]os.makedirs(cache_dir, exist_ok=True)fname = os.path.join(cache_dir, 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:breaksha1.update(data)if sha1.hexdigest() == sha1_hash: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 fnamedef download_extract(name, folder=None):  # @save"""下載并解壓zip/tar文件"""fname = download(name)base_dir = os.path.dirname(fname)data_dir, ext = os.path.splitext(fname)if ext == '.zip':fp = zipfile.ZipFile(fname, 'r')elif ext in ('.tar', '.gz'):fp = tarfile.open(fname, 'r')else:assert False, '只有zip/tar文件可以被解壓縮'fp.extractall(base_dir)return os.path.join(base_dir, folder) if folder else data_dirdef download_all():  # @save"""下載DATA_HUB中的所有文件"""for name in DATA_HUB:download(name)def get_net():net = nn.Sequential(nn.Linear(in_features, 1))return net# rmse=Root Mean Squared Error,對數均方根誤差
def log_rmse(net, features, labels):# 通過神經網絡net對輸入特征features進行前向傳播得到預測值# 然后為了在取對數時進一步穩(wěn)定該值,用torch.clamp()函數將小于1的值設置為1# 第三個參數:不設置上限,即預測可以無限大clipped_preds = torch.clamp(net(features), 1, float('inf'))rmse = torch.sqrt(loss(torch.log(clipped_preds),torch.log(labels)))# .item() 方法將rmse轉換為Python標量返回return rmse.item()# weight_decay權重衰退
def train(net, train_features, train_labels, test_features, test_labels,num_epochs, learning_rate, weight_decay, batch_size):# 用于存儲每一輪訓練和測試集上的log rmse值train_ls, test_ls = [], []train_iter = d2l.load_array((train_features, train_labels), batch_size)# 這里使用的是Adam優(yōu)化算法,Adam用于訓練過程中更新模型的權重,以最小化損失函數optimizer = torch.optim.Adam(net.parameters(),lr=learning_rate,weight_decay=weight_decay)for epoch in range(num_epochs):for X, y in train_iter:# 清空過往梯度optimizer.zero_grad()# 通過前向傳播計算損失值,然后計算預測值與真實值差異l = loss(net(X), y)l.backward()  # 反向傳播計算當前梯度optimizer.step()  # 更新模型參數# 將log_rmse函數返回的誤差值追加到train_ls列表中就記錄了每一輪迭代train_ls.append(log_rmse(net, train_features, train_labels))# 確保在提供了測試集的情況下計算測試集性能if test_labels is not None:test_ls.append(log_rmse(net, test_features, test_labels))return train_ls, test_lsdef train_and_pred(train_features, test_features, train_labels, test_data,num_epochs, lr, weight_decay, batch_size):net = get_net()# 返回兩個值,一個包含每個epoch訓練,log mose的列表,一個未在代碼片段中使用的值train_ls, _ = train(net, train_features, train_labels, None, None,num_epochs, lr, weight_decay, batch_size)# 第一個參數和第二個參數:接收一個epoch數組和一個包含訓練log rmse的列表作為輸入d2l.plot(np.arange(1, num_epochs + 1), [train_ls], xlabel='epoch',ylabel='log rmse', xlim=[1, num_epochs], yscale='log')# 打印最后一個epoch訓練log rmse來評估模型的最終訓練性能print(f'訓練log rmse:{float(train_ls[-1]):f}')# 將訓練好的網絡模型應用于測試特征preds = net(test_features).detach().numpy()# 將其重新格式化以導出到Kaggle# pd.Series()封裝成一個Pandas的Series對象,以確保數據類型與DataFrame的列兼容。test_data['SalePrice'] = pd.Series(preds.reshape(1, -1)[0])submission = pd.concat([test_data['Id'], test_data['SalePrice']], axis=1)# 用于將DataFrame保存為csv文件submission.to_csv('submission.csv', index=False)# @save
DATA_HUB = dict()
DATA_URL = 'http://d2l-data.s3-accelerate.amazonaws.com/'
DATA_HUB['kaggle_house_train'] = (DATA_URL + 'kaggle_house_pred_train.csv', '585e9cc9370b9160e7921475fbcd7d31219ce')
DATA_HUB['kaggle_house_test'] = (DATA_URL + 'kaggle_house_pred_test.csv', 'fal9780a7b011d9b009e8bff8e99922a8ee2eb90')
train_data = pd.read_csv(download('kaggle_house_train'))
test_data = pd.read_csv(download('kaggle_house_test'))# print(train_data.shape) # 1460個樣本,80個特征,1個標號label
# print(test_data.shape) # 測試樣本沒有標號label
# print(train_data.iloc[0:4,[0,1,2,3,-3,-2,-1]]) # 前面四行的某些列特征
all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))
# print(all_features.shape)# 若無法獲得測試數據,則可根據訓練數據計算均值和標準差
# all_features.dtypes 獲取每個特征的數據類型
# all_features.dtypes != 'object' 返回一個布爾值的 Series,其中為 True 的位置表示對應的特征不是對象類型(即數值類型)
# .index 提取數值類型特征的索引,并在numeric_features中存儲
# print(all_features.dtypes)  # 可以知道每一列分別為什么類型特征
numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index
# print(numeric_features)
# 對all_features中所有數值類型特征進行標準化處理
all_features[numeric_features] = all_features[numeric_features].apply(lambda x: (x - x.mean()) / (x.std()))
# 在標準化數據之后,所有均值消失,因此我們可以將缺失值設置為0
all_features[numeric_features] = all_features[numeric_features].fillna(0)# “Dummy_na=True”將“na”(缺失值)視為有效的特征值,并為其創(chuàng)建指示符特征
# 未指定column時,pd.get_dummies函數默認轉換所有的分類列,包括MSZoning、SaleType、SaleCondition
# pd.get_dummies每個分類變量都會被轉換成多列,每個唯一值對應一列
# 理解意思:某列有五類值,就將此列等價于變成五列,然后對應的列置1,不存在的列置0
all_features = pd.get_dummies(all_features, dummy_na=True)# 獲取訓練集的行數,即訓練樣本數量,并將其存儲在n_train中
n_train = train_data.shape[0]
# [:n_train].values是選擇前n_train作為訓練集的特征將數據轉換為Numpy數組
train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float32)
test_features = torch.tensor(all_features[n_train:].values, dtype=torch.float32)
# 將SalePrice列單獨提取為標簽
train_labels = torch.tensor(train_data.SalePrice.values.reshape(-1, 1), dtype=torch.float32)
loss = nn.MSELoss()
in_features = train_features.shape[1]num_epochs, lr, weight_decay, batch_size = 100, 5, 0, 64
train_and_pred(train_features, test_features, train_labels, test_data,num_epochs, lr, weight_decay, batch_size)
d2l.plt.show()



提交Kaggle

我們可以提交預測到Kaggle上,并查看在測試集上的預測實際房價(標簽)的比較情況。

?①登錄Kaggle網站,訪問房價預測競賽頁面。
?②點擊“Submit Predictions”按鈕。
?③點擊頁面底部虛線框中的“Upload Submission File”按鈕,選擇要上傳的預測文件。
?④點擊頁面底部的“Submission”按鈕,即可查看結果。

Kaggle注冊鏈接

Kaggle登錄鏈接

房價預測比賽頁面(如下圖 所示)的"Data"選項卡下可以找到數據集。我們可以通過下面的網址提交預測,并查看排名:

House Prices - Advanced Regression Techniques

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

這里是第一次提交(未優(yōu)化)

在這里插入圖片描述




1、用平均值替換缺失值總是好主意嗎?提示:能構造一個不隨機丟失值的情況嗎?
????用平均值替換缺失值并不總是一個好主意,因為這可能會導致數據失真或者模型表現(xiàn)下降。替代缺失值的方法應該根據數據的特點和缺失值產生的原因來選擇。
????比如,一個數據集中的某個屬性代表的是某種物質的濃度,這種物質在某個特定溫度下會分解,因此在這個溫度下所有樣本的該屬性值都是缺失的。在這種情況下,如果直接用平均值替換缺失值,則可能會導致數據嚴重失真。


2、通過 𝐾 折交叉驗證調整超參數,從而提高Kaggle的得分。

import hashlib
import os
import tarfile
import zipfile
import requests
import numpy as np
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2ldef download(name, cache_dir=os.path.join('..', 'data')):  # @save"""下載一個DATA_HUB中的文件,返回本地文件名"""assert name in DATA_HUB, f"{name} 不存在于 {DATA_HUB}"url, sha1_hash = DATA_HUB[name]os.makedirs(cache_dir, exist_ok=True)fname = os.path.join(cache_dir, 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:breaksha1.update(data)if sha1.hexdigest() == sha1_hash: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 fnamedef download_extract(name, folder=None):  # @save"""下載并解壓zip/tar文件"""fname = download(name)base_dir = os.path.dirname(fname)data_dir, ext = os.path.splitext(fname)if ext == '.zip':fp = zipfile.ZipFile(fname, 'r')elif ext in ('.tar', '.gz'):fp = tarfile.open(fname, 'r')else:assert False, '只有zip/tar文件可以被解壓縮'fp.extractall(base_dir)return os.path.join(base_dir, folder) if folder else data_dirdef download_all():  # @save"""下載DATA_HUB中的所有文件"""for name in DATA_HUB:download(name)def get_net():net = nn.Sequential(nn.Linear(in_features, 1))return net# rmse=Root Mean Squared Error,對數均方根誤差
def log_rmse(net, features, labels):# 通過神經網絡net對輸入特征features進行前向傳播得到預測值# 然后為了在取對數時進一步穩(wěn)定該值,用torch.clamp()函數將小于1的值設置為1# 第三個參數:不設置上限,即預測可以無限大clipped_preds = torch.clamp(net(features), 1, float('inf'))rmse = torch.sqrt(loss(torch.log(clipped_preds),torch.log(labels)))# .item() 方法將rmse轉換為Python標量返回return rmse.item()# weight_decay權重衰退
def train(net, train_features, train_labels, test_features, test_labels,num_epochs, learning_rate, weight_decay, batch_size):# 用于存儲每一輪訓練和測試集上的log rmse值train_ls, test_ls = [], []train_iter = d2l.load_array((train_features, train_labels), batch_size)# 這里使用的是Adam優(yōu)化算法,Adam用于訓練過程中更新模型的權重,以最小化損失函數optimizer = torch.optim.Adam(net.parameters(),lr=learning_rate,weight_decay=weight_decay)for epoch in range(num_epochs):for X, y in train_iter:# 清空過往梯度optimizer.zero_grad()# 通過前向傳播計算損失值,然后計算預測值與真實值差異l = loss(net(X), y)l.backward()  # 反向傳播計算當前梯度optimizer.step()  # 更新模型參數# 將log_rmse函數返回的誤差值追加到train_ls列表中就記錄了每一輪迭代train_ls.append(log_rmse(net, train_features, train_labels))# 確保在提供了測試集的情況下計算測試集性能if test_labels is not None:test_ls.append(log_rmse(net, test_features, test_labels))return train_ls, test_lsdef train_and_pred(train_features, test_features, train_labels, test_data,num_epochs, lr, weight_decay, batch_size):net = get_net()# 返回兩個值,一個包含每個epoch訓練,log mose的列表,一個未在代碼片段中使用的值train_ls, _ = train(net, train_features, train_labels, None, None,num_epochs, lr, weight_decay, batch_size)# 第一個參數和第二個參數:接收一個epoch數組和一個包含訓練log rmse的列表作為輸入d2l.plot(np.arange(1, num_epochs + 1), [train_ls], xlabel='epoch',ylabel='log rmse', xlim=[1, num_epochs], yscale='log')# 打印最后一個epoch訓練log rmse來評估模型的最終訓練性能print(f'訓練log rmse:{float(train_ls[-1]):f}')# 將訓練好的網絡模型應用于測試特征preds = net(test_features).detach().numpy()# 將其重新格式化以導出到Kaggle# pd.Series()封裝成一個Pandas的Series對象,以確保數據類型與DataFrame的列兼容。test_data['SalePrice'] = pd.Series(preds.reshape(1, -1)[0])submission = pd.concat([test_data['Id'], test_data['SalePrice']], axis=1)# 用于將DataFrame保存為csv文件submission.to_csv('submission.csv', index=False)# 四個參數:表示將數據集分為多少個子集、當前折的索引、特征數據集、標簽數據集
def get_k_fold_data(k, i, X, y):# 斷言確保折數大于1,因為至少兩個子集才能進行交叉驗證assert k > 1# 每個子集(折)的大小=數據集的總行數除以折數,余數在最后一個子集處理fold_size = X.shape[0] // k# 初始化訓練集X_train, y_train = None, Nonefor j in range(k):# idx將原始數據集的索引切片為 (j * fold_size) 到 ((j + 1) * fold_size),獲得當前折數據idx = slice(j * fold_size, (j + 1) * fold_size)X_part, y_part = X[idx, :], y[idx]# 當前折的索引 j 與指定用于驗證的索引 i 匹配,將該折的數據分配給驗證集(X_valid 和 y_valid)if j == i:# 將該折的數據分配給驗證集X_valid, y_valid = X_part, y_part# 如不匹配且訓練集為空(第一次看到),則將該折的數據分配給訓練集(X_train 和 y_train)elif X_train is None:X_train, y_train = X_part, y_part# 如不匹配且訓練集不為空,則將該折的數據追加到訓練集(X_train 和 y_train)中else:# 表示將X_train, X_part沿著第一個維度拼接起來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_validdef k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay,batch_size):# 初始化該變量,用于累加每次折的訓練和驗證損失train_l_sum, valid_l_sum = 0, 0for i in range(k):# 做k次,每次拿到第i折,把數據data拿出來即拿到從訓練集和驗證集data = get_k_fold_data(k, i, X_train, y_train)# 每次循環(huán)都會創(chuàng)建一個新的模型實例,確保每折的評估是獨立的net = get_net()# 調用train函數訓練模型并返回訓練損失列表和驗證損失列表train_ls, valid_ls = train(net, *data, num_epochs, learning_rate,weight_decay, batch_size)# 索引[-1]獲取最后一個epoch的損失,即當前折的訓練損失累加到train_l_sumtrain_l_sum += train_ls[-1]valid_l_sum += valid_ls[-1]if i == 0:  # 如果當前是第i折# 第一個參數:用作x軸數據# 第二個參數:一個列表儲存了每一輪訓練后的訓練損失和驗證損失d2l.plot(list(range(1, num_epochs + 1)), [train_ls, valid_ls],xlabel='epoch', ylabel='rmse', xlim=[1, num_epochs],legend=['train', 'valid'], yscale='log')print(f'折{i + 1},訓練log rmse{float(train_ls[-1]):f}, 'f'驗證log rmse{float(valid_ls[-1]):f}')# 返回平均訓練損失和平均驗證損失return train_l_sum / k, valid_l_sum / k# @save
DATA_HUB = dict()
DATA_URL = 'http://d2l-data.s3-accelerate.amazonaws.com/'
DATA_HUB['kaggle_house_train'] = (DATA_URL + 'kaggle_house_pred_train.csv', '585e9cc9370b9160e7921475fbcd7d31219ce')
DATA_HUB['kaggle_house_test'] = (DATA_URL + 'kaggle_house_pred_test.csv', 'fal9780a7b011d9b009e8bff8e99922a8ee2eb90')
train_data = pd.read_csv(download('kaggle_house_train'))
test_data = pd.read_csv(download('kaggle_house_test'))# print(train_data.shape) # 1460個樣本,80個特征,1個標號label
# print(test_data.shape) # 測試樣本沒有標號label
# print(train_data.iloc[0:4,[0,1,2,3,-3,-2,-1]]) # 前面四行的某些列特征
all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))
# print(all_features.shape)# 若無法獲得測試數據,則可根據訓練數據計算均值和標準差
# all_features.dtypes 獲取每個特征的數據類型
# all_features.dtypes != 'object' 返回一個布爾值的 Series,其中為 True 的位置表示對應的特征不是對象類型(即數值類型)
# .index 提取數值類型特征的索引,并在numeric_features中存儲
# print(all_features.dtypes)  # 可以知道每一列分別為什么類型特征
numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index
# print(numeric_features)
# 對all_features中所有數值類型特征進行標準化處理
all_features[numeric_features] = all_features[numeric_features].apply(lambda x: (x - x.mean()) / (x.std()))
# 在標準化數據之后,所有均值消失,因此我們可以將缺失值設置為0
all_features[numeric_features] = all_features[numeric_features].fillna(0)# “Dummy_na=True”將“na”(缺失值)視為有效的特征值,并為其創(chuàng)建指示符特征
# 未指定column時,pd.get_dummies函數默認轉換所有的分類列,包括MSZoning、SaleType、SaleCondition
# pd.get_dummies每個分類變量都會被轉換成多列,每個唯一值對應一列
# 理解意思:某列有五類值,就將此列等價于變成五列,然后對應的列置1,不存在的列置0
all_features = pd.get_dummies(all_features, dummy_na=True)# 獲取訓練集的行數,即訓練樣本數量,并將其存儲在n_train中
n_train = train_data.shape[0]
# [:n_train].values是選擇前n_train作為訓練集的特征將數據轉換為Numpy數組
train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float32)
test_features = torch.tensor(all_features[n_train:].values, dtype=torch.float32)
# 將SalePrice列單獨提取為標簽
train_labels = torch.tensor(train_data.SalePrice.values.reshape(-1, 1), dtype=torch.float32)
loss = nn.MSELoss()
in_features = train_features.shape[1]# 數據集被分成了5份,然后執(zhí)行5次訓練和驗證過程,每次過程中,4份數據用于訓練模型,剩下的一份用于
k, num_epochs, lr, weight_decay, batch_size = 5, 100, 10, 0, 32
# 分別包含每次迭代的訓練集和驗證集的log rmse值
train_l, valid_l = k_fold(k, train_features, train_labels, num_epochs, lr,weight_decay, batch_size)
print(f'{k}-折驗證: 平均訓練log rmse: {float(train_l):f}, 'f'平均驗證log rmse: {float(valid_l):f}')
train_and_pred(train_features, test_features, train_labels, test_data,num_epochs, lr, weight_decay, batch_size)
d2l.plt.show()

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述




3、通過改進模型(例如,層、權重衰減和dropout)來提高分數。

import hashlib
import os
import tarfile
import zipfile
import requests
import numpy as np
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2ldef download(name, cache_dir=os.path.join('..', 'data')):  # @save"""下載一個DATA_HUB中的文件,返回本地文件名"""assert name in DATA_HUB, f"{name} 不存在于 {DATA_HUB}"url, sha1_hash = DATA_HUB[name]os.makedirs(cache_dir, exist_ok=True)fname = os.path.join(cache_dir, 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:breaksha1.update(data)if sha1.hexdigest() == sha1_hash: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 fnamedef download_extract(name, folder=None):  # @save"""下載并解壓zip/tar文件"""fname = download(name)base_dir = os.path.dirname(fname)data_dir, ext = os.path.splitext(fname)if ext == '.zip':fp = zipfile.ZipFile(fname, 'r')elif ext in ('.tar', '.gz'):fp = tarfile.open(fname, 'r')else:assert False, '只有zip/tar文件可以被解壓縮'fp.extractall(base_dir)return os.path.join(base_dir, folder) if folder else data_dirdef download_all():  # @save"""下載DATA_HUB中的所有文件"""for name in DATA_HUB:download(name)def init_weights(m):if type(m) == nn.Linear:nn.init.normal_(m.weight, std=0.01)def get_net():net = nn.Sequential(nn.Flatten(),nn.Linear(in_features, 512),nn.ReLU(),nn.Linear(512, 1))net.apply(init_weights)return net# rmse=Root Mean Squared Error,對數均方根誤差
def log_rmse(net, features, labels):# 通過神經網絡net對輸入特征features進行前向傳播得到預測值# 然后為了在取對數時進一步穩(wěn)定該值,用torch.clamp()函數將小于1的值設置為1# 第三個參數:不設置上限,即預測可以無限大clipped_preds = torch.clamp(net(features), 1, float('inf'))rmse = torch.sqrt(loss(torch.log(clipped_preds),torch.log(labels)))# .item() 方法將rmse轉換為Python標量返回return rmse.item()# weight_decay權重衰退
def train(net, train_features, train_labels, test_features, test_labels,num_epochs, learning_rate, weight_decay, batch_size):# 用于存儲每一輪訓練和測試集上的log rmse值train_ls, test_ls = [], []train_iter = d2l.load_array((train_features, train_labels), batch_size)# 這里使用的是Adam優(yōu)化算法,Adam用于訓練過程中更新模型的權重,以最小化損失函數optimizer = torch.optim.Adam(net.parameters(),lr=learning_rate,weight_decay=weight_decay)for epoch in range(num_epochs):for X, y in train_iter:# 清空過往梯度optimizer.zero_grad()# 通過前向傳播計算損失值,然后計算預測值與真實值差異l = loss(net(X), y)l.backward()  # 反向傳播計算當前梯度optimizer.step()  # 更新模型參數# 將log_rmse函數返回的誤差值追加到train_ls列表中就記錄了每一輪迭代train_ls.append(log_rmse(net, train_features, train_labels))# 確保在提供了測試集的情況下計算測試集性能if test_labels is not None:test_ls.append(log_rmse(net, test_features, test_labels))return train_ls, test_lsdef train_and_pred(train_features, test_features, train_labels, test_data,num_epochs, lr, weight_decay, batch_size):net = get_net()# 返回兩個值,一個包含每個epoch訓練,log mose的列表,一個未在代碼片段中使用的值train_ls, _ = train(net, train_features, train_labels, None, None,num_epochs, lr, weight_decay, batch_size)# 第一個參數和第二個參數:接收一個epoch數組和一個包含訓練log rmse的列表作為輸入d2l.plot(np.arange(1, num_epochs + 1), [train_ls], xlabel='epoch',ylabel='log rmse', xlim=[1, num_epochs], yscale='log')# 打印最后一個epoch訓練log rmse來評估模型的最終訓練性能print(f'訓練log rmse:{float(train_ls[-1]):f}')# 將訓練好的網絡模型應用于測試特征preds = net(test_features).detach().numpy()# 將其重新格式化以導出到Kaggle# pd.Series()封裝成一個Pandas的Series對象,以確保數據類型與DataFrame的列兼容。test_data['SalePrice'] = pd.Series(preds.reshape(1, -1)[0])submission = pd.concat([test_data['Id'], test_data['SalePrice']], axis=1)# 用于將DataFrame保存為csv文件submission.to_csv('submission.csv', index=False)# 四個參數:表示將數據集分為多少個子集、當前折的索引、特征數據集、標簽數據集
def get_k_fold_data(k, i, X, y):# 斷言確保折數大于1,因為至少兩個子集才能進行交叉驗證assert k > 1# 每個子集(折)的大小=數據集的總行數除以折數,余數在最后一個子集處理fold_size = X.shape[0] // k# 初始化訓練集X_train, y_train = None, Nonefor j in range(k):# idx將原始數據集的索引切片為 (j * fold_size) 到 ((j + 1) * fold_size),獲得當前折數據idx = slice(j * fold_size, (j + 1) * fold_size)X_part, y_part = X[idx, :], y[idx]# 當前折的索引 j 與指定用于驗證的索引 i 匹配,將該折的數據分配給驗證集(X_valid 和 y_valid)if j == i:# 將該折的數據分配給驗證集X_valid, y_valid = X_part, y_part# 如不匹配且訓練集為空(第一次看到),則將該折的數據分配給訓練集(X_train 和 y_train)elif X_train is None:X_train, y_train = X_part, y_part# 如不匹配且訓練集不為空,則將該折的數據追加到訓練集(X_train 和 y_train)中else:# 表示將X_train, X_part沿著第一個維度拼接起來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_validdef k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay,batch_size):# 初始化該變量,用于累加每次折的訓練和驗證損失train_l_sum, valid_l_sum = 0, 0for i in range(k):# 做k次,每次拿到第i折,把數據data拿出來即拿到從訓練集和驗證集data = get_k_fold_data(k, i, X_train, y_train)# 每次循環(huán)都會創(chuàng)建一個新的模型實例,確保每折的評估是獨立的net = get_net()# 調用train函數訓練模型并返回訓練損失列表和驗證損失列表train_ls, valid_ls = train(net, *data, num_epochs, learning_rate,weight_decay, batch_size)# 索引[-1]獲取最后一個epoch的損失,即當前折的訓練損失累加到train_l_sumtrain_l_sum += train_ls[-1]valid_l_sum += valid_ls[-1]if i == 0:  # 如果當前是第i折# 第一個參數:用作x軸數據# 第二個參數:一個列表儲存了每一輪訓練后的訓練損失和驗證損失d2l.plot(list(range(1, num_epochs + 1)), [train_ls, valid_ls],xlabel='epoch', ylabel='rmse', xlim=[1, num_epochs],legend=['train', 'valid'], yscale='log')print(f'折{i + 1},訓練log rmse{float(train_ls[-1]):f}, 'f'驗證log rmse{float(valid_ls[-1]):f}')# 返回平均訓練損失和平均驗證損失return train_l_sum / k, valid_l_sum / k# @save
DATA_HUB = dict()
DATA_URL = 'http://d2l-data.s3-accelerate.amazonaws.com/'
DATA_HUB['kaggle_house_train'] = (DATA_URL + 'kaggle_house_pred_train.csv', '585e9cc9370b9160e7921475fbcd7d31219ce')
DATA_HUB['kaggle_house_test'] = (DATA_URL + 'kaggle_house_pred_test.csv', 'fal9780a7b011d9b009e8bff8e99922a8ee2eb90')
train_data = pd.read_csv(download('kaggle_house_train'))
test_data = pd.read_csv(download('kaggle_house_test'))# print(train_data.shape) # 1460個樣本,80個特征,1個標號label
# print(test_data.shape) # 測試樣本沒有標號label
# print(train_data.iloc[0:4,[0,1,2,3,-3,-2,-1]]) # 前面四行的某些列特征
all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))
# print(all_features.shape)# 若無法獲得測試數據,則可根據訓練數據計算均值和標準差
# all_features.dtypes 獲取每個特征的數據類型
# all_features.dtypes != 'object' 返回一個布爾值的 Series,其中為 True 的位置表示對應的特征不是對象類型(即數值類型)
# .index 提取數值類型特征的索引,并在numeric_features中存儲
# print(all_features.dtypes)  # 可以知道每一列分別為什么類型特征
numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index
# print(numeric_features)
# 對all_features中所有數值類型特征進行標準化處理
all_features[numeric_features] = all_features[numeric_features].apply(lambda x: (x - x.mean()) / (x.std()))
# 在標準化數據之后,所有均值消失,因此我們可以將缺失值設置為0
all_features[numeric_features] = all_features[numeric_features].fillna(0)# “Dummy_na=True”將“na”(缺失值)視為有效的特征值,并為其創(chuàng)建指示符特征
# 未指定column時,pd.get_dummies函數默認轉換所有的分類列,包括MSZoning、SaleType、SaleCondition
# pd.get_dummies每個分類變量都會被轉換成多列,每個唯一值對應一列
# 理解意思:某列有五類值,就將此列等價于變成五列,然后對應的列置1,不存在的列置0
all_features = pd.get_dummies(all_features, dummy_na=True)# 獲取訓練集的行數,即訓練樣本數量,并將其存儲在n_train中
n_train = train_data.shape[0]
# [:n_train].values是選擇前n_train作為訓練集的特征將數據轉換為Numpy數組
train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float32)
test_features = torch.tensor(all_features[n_train:].values, dtype=torch.float32)
# 將SalePrice列單獨提取為標簽
train_labels = torch.tensor(train_data.SalePrice.values.reshape(-1, 1), dtype=torch.float32)
loss = nn.MSELoss()
in_features = train_features.shape[1]# 數據集被分成了5份,然后執(zhí)行5次訓練和驗證過程,每次過程中,4份數據用于訓練模型,剩下的一份用于
k, num_epochs, lr, weight_decay, batch_size = 5, 100, 0.01, 300, 32
# 分別包含每次迭代的訓練集和驗證集的log rmse值
train_l, valid_l = k_fold(k, train_features, train_labels, num_epochs, lr,weight_decay, batch_size)train_and_pred(train_features, test_features, train_labels, test_data,num_epochs, lr, weight_decay, batch_size)print(f'{k}-折驗證: 平均訓練log rmse: {float(train_l):f}, 'f'平均驗證log rmse: {float(valid_l):f}')
d2l.plt.show()

在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述




十行代碼:

# 預測
import pandas as pd
from autogluon.tabular import TabularDataset, TabularPredictor# 訓練
train_data = TabularDataset('./data/California house price/house-prices-advanced-regression-techniques/train.csv')id, label = 'Id', 'SalePrice'
predictor = TabularPredictor(label=label).fit(train_data.drop(columns=[id]))test_data = TabularDataset('./data/California house price/house-prices-advanced-regression-techniques/test.csv')
preds = predictor.predict(test_data.drop(columns=[id]))
submission = pd.DataFrame({id: test_data[id], label: preds})
submission.to_csv('./kaggle_submission/submission_4.csv', index=False)

后面兩個代碼均為測試,發(fā)現(xiàn)并沒有那么好。

import hashlib
import os
import tarfile
import zipfile
import requests
import numpy as np
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2ldef download(name, cache_dir=os.path.join('..', 'data')):  # @save"""下載一個DATA_HUB中的文件,返回本地文件名"""assert name in DATA_HUB, f"{name} 不存在于 {DATA_HUB}"url, sha1_hash = DATA_HUB[name]os.makedirs(cache_dir, exist_ok=True)fname = os.path.join(cache_dir, 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:breaksha1.update(data)if sha1.hexdigest() == sha1_hash: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 fnamedef download_extract(name, folder=None):  # @save"""下載并解壓zip/tar文件"""fname = download(name)base_dir = os.path.dirname(fname)data_dir, ext = os.path.splitext(fname)if ext == '.zip':fp = zipfile.ZipFile(fname, 'r')elif ext in ('.tar', '.gz'):fp = tarfile.open(fname, 'r')else:assert False, '只有zip/tar文件可以被解壓縮'fp.extractall(base_dir)return os.path.join(base_dir, folder) if folder else data_dirdef download_all():  # @save"""下載DATA_HUB中的所有文件"""for name in DATA_HUB:download(name)def init_weights(m):if isinstance(m, nn.Linear):nn.init.normal_(m.weight, std=0.01)def get_net():net = nn.Sequential(nn.Flatten(),nn.Linear(in_features, 512),nn.ReLU(),nn.Dropout(p=0.5),  # 添加 Dropout 層nn.Linear(512, 256),nn.ReLU(),nn.Dropout(p=0.5),  # 添加 Dropout 層nn.Linear(256, 128),nn.ReLU(),nn.Dropout(p=0.5),  # 添加 Dropout 層nn.Linear(128, 1))net.apply(init_weights)return netdef log_rmse(net, features, labels):clipped_preds = torch.clamp(net(features), 1, float('inf'))rmse = torch.sqrt(loss(torch.log(clipped_preds),torch.log(labels)))return rmse.item()def train(net, train_features, train_labels, test_features, test_labels,num_epochs, learning_rate, weight_decay, batch_size):train_ls, test_ls = [], []train_iter = d2l.load_array((train_features, train_labels), batch_size)optimizer = torch.optim.Adam(net.parameters(),lr=learning_rate,weight_decay=weight_decay)scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.7)for epoch in range(num_epochs):net.train()  # 確保模型處于訓練模式for X, y in train_iter:optimizer.zero_grad()l = loss(net(X), y)l.backward()optimizer.step()scheduler.step()  # 更新學習率net.eval()  # 切換到評估模式with torch.no_grad():train_ls.append(log_rmse(net, train_features, train_labels))if test_labels is not None:test_ls.append(log_rmse(net, test_features, test_labels))return train_ls, test_lsdef train_and_pred(train_features, test_features, train_labels, test_data,num_epochs, lr, weight_decay, batch_size):net = get_net()train_ls, _ = train(net, train_features, train_labels, None, None,num_epochs, lr, weight_decay, batch_size)d2l.plot(np.arange(1, num_epochs + 1), [train_ls], xlabel='epoch',ylabel='log rmse', xlim=[1, num_epochs], yscale='log')print(f'訓練 log rmse:{float(train_ls[-1]):f}')net.eval()  # 切換到評估模式with torch.no_grad():preds = net(test_features).detach().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)def get_k_fold_data(k, i, X, y):assert k > 1fold_size = X.shape[0] // kX_train, y_train = None, Nonefor 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_partelif X_train is None:X_train, y_train = X_part, y_partelse: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_validdef k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay,batch_size):train_l_sum, valid_l_sum = 0, 0for i in range(k):data = get_k_fold_data(k, i, X_train, y_train)net = get_net()train_ls, valid_ls = train(net, *data, num_epochs, learning_rate,weight_decay, batch_size)train_l_sum += train_ls[-1]valid_l_sum += valid_ls[-1]if i == 0:d2l.plot(list(range(1, num_epochs + 1)), [train_ls, valid_ls],xlabel='epoch', ylabel='rmse', xlim=[1, num_epochs],legend=['train', 'valid'], yscale='log')print(f'折{i + 1},訓練log rmse{float(train_ls[-1]):f}, 'f'驗證log rmse{float(valid_ls[-1]):f}')return train_l_sum / k, valid_l_sum / k# @save
DATA_HUB = dict()
DATA_URL = 'http://d2l-data.s3-accelerate.amazonaws.com/'
DATA_HUB['kaggle_house_train'] = (DATA_URL + 'kaggle_house_pred_train.csv', '585e9cc9370b9160e7921475fbcd7d31219ce')
DATA_HUB['kaggle_house_test'] = (DATA_URL + 'kaggle_house_pred_test.csv', 'fal9780a7b011d9b009e8bff8e99922a8ee2eb90')
train_data = pd.read_csv(download('kaggle_house_train'))
test_data = pd.read_csv(download('kaggle_house_test'))all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index
all_features[numeric_features] = all_features[numeric_features].apply(lambda x: (x - x.mean()) / (x.std()))
all_features[numeric_features] = all_features[numeric_features].fillna(0)all_features = pd.get_dummies(all_features, dummy_na=True)n_train = train_data.shape[0]
train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float32)
test_features = torch.tensor(all_features[n_train:].values, dtype=torch.float32)
train_labels = torch.tensor(train_data.SalePrice.values.reshape(-1, 1), dtype=torch.float32)
loss = nn.MSELoss()
in_features = train_features.shape[1]k, num_epochs, lr, weight_decay, batch_size = 5, 100, 0.01, 300, 32
train_l, valid_l = k_fold(k, train_features, train_labels, num_epochs, lr,weight_decay, batch_size)print(f'{k}-折驗證: 平均訓練log rmse: {float(train_l):f}, 'f'平均驗證log rmse: {float(valid_l):f}')
train_and_pred(train_features, test_features, train_labels, test_data,num_epochs, lr, weight_decay, batch_size)
d2l.plt.show()

輸出:

在這里插入圖片描述

在這里插入圖片描述




import hashlib
import os
import tarfile
import zipfile
import requests
import numpy as np
import pandas as pd
import torch
from torch import nn
from d2l import torch as d2l# 數據下載和提取功能
def download(name, cache_dir=os.path.join('..', 'data')):"""下載一個DATA_HUB中的文件,返回本地文件名"""if name not in DATA_HUB:raise ValueError(f"{name} 不存在于 DATA_HUB")url, sha1_hash = DATA_HUB[name]os.makedirs(cache_dir, exist_ok=True)fname = os.path.join(cache_dir, url.split('/')[-1])if os.path.exists(fname):sha1 = hashlib.sha1()with open(fname, 'rb') as f:for chunk in iter(lambda: f.read(1048576), b''):sha1.update(chunk)if sha1.hexdigest() == sha1_hash:return fnameprint(f'正在從 {url} 下載 {fname}...')response = requests.get(url, stream=True)response.raise_for_status()with open(fname, 'wb') as f:f.write(response.content)return fnamedef download_extract(name, folder=None):"""下載并解壓zip/tar文件"""fname = download(name)base_dir = os.path.dirname(fname)ext = os.path.splitext(fname)[1]if ext == '.zip':with zipfile.ZipFile(fname, 'r') as zip_ref:zip_ref.extractall(base_dir)elif ext in ('.tar', '.gz'):with tarfile.open(fname, 'r') as tar_ref:tar_ref.extractall(base_dir)else:raise ValueError('僅支持zip和tar文件的解壓縮')return os.path.join(base_dir, folder) if folder else base_dir# 初始化權重
def init_weights(m):if isinstance(m, nn.Linear):nn.init.normal_(m.weight, std=0.01)# 創(chuàng)建網絡
def get_net():net = nn.Sequential(nn.Flatten(),nn.Linear(in_features, 1024),  # 增加神經元數量nn.ReLU(),nn.Dropout(0.3),  # 調整 Dropout 率nn.Linear(1024, 512),  # 增加神經元數量nn.ReLU(),nn.Dropout(0.3),  # 調整 Dropout 率nn.Linear(512, 256),nn.ReLU(),nn.Dropout(0.3),  # 調整 Dropout 率nn.Linear(256, 1))net.apply(init_weights)return net# 計算對數均方根誤差
def log_rmse(net, features, labels):clipped_preds = torch.clamp(net(features), 1, float('inf'))rmse = torch.sqrt(loss(torch.log(clipped_preds), torch.log(labels)))return rmse.item()# 訓練模型
def train(net, train_features, train_labels, test_features, test_labels, num_epochs, learning_rate, weight_decay,batch_size):train_ls, test_ls = [], []train_iter = d2l.load_array((train_features, train_labels), batch_size)optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate, weight_decay=weight_decay)scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=num_epochs)for epoch in range(num_epochs):net.train()for X, y in train_iter:optimizer.zero_grad()l = loss(net(X), y)l.backward()optimizer.step()scheduler.step()net.eval()with torch.no_grad():train_ls.append(log_rmse(net, train_features, train_labels))if test_labels is not None:test_ls.append(log_rmse(net, test_features, test_labels))return train_ls, test_ls# 訓練并預測
def train_and_pred(train_features, test_features, train_labels, test_data, num_epochs, lr, weight_decay, batch_size):net = get_net()train_ls, _ = train(net, train_features, train_labels, None, None, num_epochs, lr, weight_decay, batch_size)d2l.plot(np.arange(1, num_epochs + 1), [train_ls], xlabel='epoch', ylabel='log rmse', xlim=[1, num_epochs],yscale='log')print(f'訓練 log rmse:{train_ls[-1]:f}')net.eval()with torch.no_grad():preds = net(test_features).detach().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)# K折交叉驗證數據獲取
def get_k_fold_data(k, i, X, y):assert k > 1, 'k必須大于1'fold_size = X.shape[0] // kX_train, y_train = None, Nonefor 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_partelif X_train is None:X_train, y_train = X_part, y_partelse:X_train = torch.cat([X_train, X_part], dim=0)y_train = torch.cat([y_train, y_part], dim=0)return X_train, y_train, X_valid, y_valid# K折交叉驗證
def k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay, batch_size):train_l_sum, valid_l_sum = 0, 0for i in range(k):data = get_k_fold_data(k, i, X_train, y_train)net = get_net()train_ls, valid_ls = train(net, *data, num_epochs, learning_rate, weight_decay, batch_size)train_l_sum += train_ls[-1]valid_l_sum += valid_ls[-1]if i == 0:d2l.plot(list(range(1, num_epochs + 1)), [train_ls, valid_ls], xlabel='epoch', ylabel='rmse',xlim=[1, num_epochs], legend=['train', 'valid'], yscale='log')print(f'折{i + 1},訓練log rmse: {train_ls[-1]:.6f}, 驗證log rmse: {valid_ls[-1]:.6f}')return train_l_sum / k, valid_l_sum / k# 數據準備
DATA_HUB = {'kaggle_house_train': ('http://d2l-data.s3-accelerate.amazonaws.com/kaggle_house_pred_train.csv', '585e9cc9370b9160e7921475fbcd7d31219ce'),'kaggle_house_test': ('http://d2l-data.s3-accelerate.amazonaws.com/kaggle_house_pred_test.csv','fal9780a7b011d9b009e8bff8e99922a8ee2eb90')
}
train_data = pd.read_csv(download('kaggle_house_train'))
test_data = pd.read_csv(download('kaggle_house_test'))all_features = pd.concat([train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]])
numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index
all_features[numeric_features] = all_features[numeric_features].apply(lambda x: (x - x.mean()) / x.std()).fillna(0)
all_features = pd.get_dummies(all_features, dummy_na=True)n_train = train_data.shape[0]
train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float32)
test_features = torch.tensor(all_features[n_train:].values, dtype=torch.float32)
train_labels = torch.tensor(train_data.SalePrice.values.reshape(-1, 1), dtype=torch.float32)
loss = nn.MSELoss()
in_features = train_features.shape[1]# 設置訓練參數
k, num_epochs, lr, weight_decay, batch_size = 5, 100, 0.01, 0, 32# 執(zhí)行K折交叉驗證
train_l, valid_l = k_fold(k, train_features, train_labels, num_epochs, lr, weight_decay, batch_size)
print(f'{k}-折驗證: 平均訓練log rmse: {train_l:.6f}, 平均驗證log rmse: {valid_l:.6f}')# 訓練模型并生成預測
train_and_pred(train_features, test_features, train_labels, test_data, num_epochs, lr, weight_decay, batch_size)
d2l.plt.tight_layout()  # 調整子圖參數,使之填充整個圖像區(qū)域
d2l.plt.show()

輸出:
在這里插入圖片描述

在這里插入圖片描述




4、如果我們沒有像本節(jié)所做的那樣標準化連續(xù)的數值特征,會發(fā)生什么?

????可能導致模型訓練不穩(wěn)定、性能下降、泛化能力差:未標準化的特征可能具有不同的尺度,這可能導致某些特征在模型訓練過程中權重過大或過小,使得模型的收斂速度變慢,甚至無法收斂,標準化可以使得以確保所有特征對模型的影響是均衡的,從而提高算法的性能、收斂速度以及泛化能力。
????可能導致數值問題:如果數據的特征值范圍非常廣泛,可能會導致數值溢出或者精度問題。標準化可以減少這些問題的發(fā)生,確保計算的穩(wěn)定性和準確性。
????可能導致特征重要性誤判:未標準化的特征可能會導致對特征重要性的誤判。模型可能會錯誤地認為某些特征對目標變量的影響更大,而實際上這只是因為該特征的值范圍較大而已。

http://www.risenshineclean.com/news/44412.html

相關文章:

  • 手機網站用什么域名盤多多搜索引擎入口
  • 網站開發(fā)文件綜述網絡營銷企業(yè)網站
  • 軟件開發(fā)需要多久網站優(yōu)化有哪些技巧
  • 大良網站制作福建seo外包
  • 聊城網站建設泉州seo優(yōu)化
  • 如何免費建一個wordpressseo文章生成器
  • 在線做熱圖的網站站長工具seo綜合查詢5g
  • 深一集團的網站誰做的360開戶推廣
  • 武漢哪家網站建設公司好怎么用手機創(chuàng)建網站
  • 萍鄉(xiāng)做網站的百度云網盤資源搜索引擎入口
  • 卡姐的wap是什么意思百度seo站長工具
  • 網站怎么做搜索引擎才能收錄百度指數有什么參考意義
  • 做照片書的模板下載網站好惠州網站推廣排名
  • 沈陽網站建設專家seo營銷方案
  • 建站免費加盟網絡營銷推廣的優(yōu)勢
  • 有哪些做普洱茶網站的女生讀網絡營銷與電商直播
  • 廣州開發(fā)區(qū)醫(yī)院南崗院區(qū)莆田seo推廣公司
  • app開發(fā)公司收費seo優(yōu)化包括哪些
  • 哪個公司網站做的好網站推廣的目的是什么
  • 沈陽犀牛云做網站怎么樣長沙正規(guī)seo優(yōu)化價格
  • 杭州 手機網站免費搭建網站的軟件
  • 使用tag的網站最近一周的新聞大事10條
  • 織夢學校網站seo關鍵詞推廣方式
  • 百度搜索推廣技巧免費外鏈網站seo發(fā)布
  • 沈陽做網站哪家便宜深圳最新消息今天
  • 做的好的國外網站東莞做好網絡推廣
  • 貿易公司寮步網站建設極致發(fā)燒百度在線入口
  • 赤峰做企業(yè)網站公司企業(yè)網站建設方案策劃
  • 網站彈出信息怎么做怎么快速優(yōu)化關鍵詞排名
  • 專門做娛樂場所的設計網站近三天發(fā)生的大事