亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用Pytorch搭建一個房價預測模型

發布時間:2023-03-27 15:19:53 來源:億速云 閱讀:152 作者:iii 欄目:開發技術

本篇內容主要講解“怎么用Pytorch搭建一個房價預測模型”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么用Pytorch搭建一個房價預測模型”吧!

一、項目介紹

        在此項目中,目的是預測愛荷華州Ames的房價,給定81個特征,描述了房子、面積、土地、基礎設施、公共設施等。埃姆斯數據集具有分類和連續特征的良好組合,大小適中,也許最重要的是,它不像其他類似的數據集(如波士頓住房)那樣存在潛在的紅線或數據輸入問題。在這里我將主要討論PyTorch建模的相關方面,作為一點額外的內容,我還將演示PyTorch中開發的模型的神經元重要性。

二、準備工作

為了準備這個項目,我們首先需要下載數據,并通過以下步驟進行一些預處理。

from sklearn.datasets import fetch_openml
data = fetch_openml(data_id=42165, as_frame=True)

查看數據特征

import pandas as pd
data_ames = pd.DataFrame(data.data, columns=data.feature_names)
data_ames['SalePrice'] = data.target
data_ames.info()

下面是DataFrame的信息

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1460 entries, 0 to 1459
Data columns (total 81 columns):
Id               1460 non-null float64
MSSubClass       1460 non-null float64
MSZoning         1460 non-null object
LotFrontage      1201 non-null float64
LotArea          1460 non-null float64
Street           1460 non-null object
Alley            91 non-null object
LotShape         1460 non-null object
LandContour      1460 non-null object
Utilities        1460 non-null object
LotConfig        1460 non-null object
LandSlope        1460 non-null object
Neighborhood     1460 non-null object
Condition1       1460 non-null object
Condition2       1460 non-null object
BldgType         1460 non-null object
HouseStyle       1460 non-null object
OverallQual      1460 non-null float64
OverallCond      1460 non-null float64
YearBuilt        1460 non-null float64
YearRemodAdd     1460 non-null float64
RoofStyle        1460 non-null object
RoofMatl         1460 non-null object
Exterior1st      1460 non-null object
Exterior2nd      1460 non-null object
MasVnrType       1452 non-null object
MasVnrArea       1452 non-null float64
ExterQual        1460 non-null object
ExterCond        1460 non-null object
Foundation       1460 non-null object
BsmtQual         1423 non-null object
BsmtCond         1423 non-null object
BsmtExposure     1422 non-null object
BsmtFinType1     1423 non-null object
BsmtFinSF1       1460 non-null float64
BsmtFinType2     1422 non-null object
BsmtFinSF2       1460 non-null float64
BsmtUnfSF        1460 non-null float64
TotalBsmtSF      1460 non-null float64
Heating          1460 non-null object
HeatingQC        1460 non-null object
CentralAir       1460 non-null object
Electrical       1459 non-null object
1stFlrSF         1460 non-null float64
2ndFlrSF         1460 non-null float64
LowQualFinSF     1460 non-null float64
GrLivArea        1460 non-null float64
BsmtFullBath     1460 non-null float64
BsmtHalfBath     1460 non-null float64
FullBath         1460 non-null float64
HalfBath         1460 non-null float64
BedroomAbvGr     1460 non-null float64
KitchenAbvGr     1460 non-null float64
KitchenQual      1460 non-null object
TotRmsAbvGrd     1460 non-null float64
Functional       1460 non-null object
Fireplaces       1460 non-null float64
FireplaceQu      770 non-null object
GarageType       1379 non-null object
GarageYrBlt      1379 non-null float64
GarageFinish     1379 non-null object
GarageCars       1460 non-null float64
GarageArea       1460 non-null float64
GarageQual       1379 non-null object
GarageCond       1379 non-null object
PavedDrive       1460 non-null object
WoodDeckSF       1460 non-null float64
OpenPorchSF      1460 non-null float64
EnclosedPorch    1460 non-null float64
3SsnPorch        1460 non-null float64
ScreenPorch      1460 non-null float64
PoolArea         1460 non-null float64
PoolQC           7 non-null object
Fence            281 non-null object
MiscFeature      54 non-null object
MiscVal          1460 non-null float64
MoSold           1460 non-null float64
YrSold           1460 non-null float64
SaleType         1460 non-null object
SaleCondition    1460 non-null object
SalePrice        1460 non-null float64
dtypes: float64(38), object(43)
memory usage: 924.0+ KB

接下來,我們還將使用一個庫,即 captum,它可以檢查 PyTorch 模型的特征和神經元重要性。

pip install captum

 在做完這些準備工作后,我們來看看如何預測房價。

三、實驗過程

3.1數據預處理

        在這里,首先要進行數據縮放處理,因為所有的變量都有不同的尺度。分類變量需要轉換為數值類型,以便將它們輸入到我們的模型中。我們可以選擇一熱編碼,即我們為每個分類因子創建啞變量,或者是序數編碼,即我們對所有因子進行編號,并用這些數字替換字符串。我們可以像其他浮動變量一樣將虛擬變量送入,而序數編碼則需要使用嵌入,即線性神經網絡投影,在多維空間中對類別進行重新排序。我們在這里采取嵌入的方式。

import numpy as np
from category_encoders.ordinal import OrdinalEncoder
from sklearn.preprocessing import StandardScaler
 
num_cols = list(data_ames.select_dtypes(include='float'))
cat_cols = list(data_ames.select_dtypes(include='object'))
 
ordinal_encoder = OrdinalEncoder().fit(
    data_ames[cat_cols]
)
standard_scaler = StandardScaler().fit(
    data_ames[num_cols]
)
 
X = pd.DataFrame(
    data=np.column_stack([
        ordinal_encoder.transform(data_ames[cat_cols]),
        standard_scaler.transform(data_ames[num_cols])
    ]),
    columns=cat_cols + num_cols
)

3.2拆分數據集

       在構建模型之前,我們需要將數據拆分為訓練集和測試集。在這里,我們添加了一個數值變量的分層。這可以確保不同的部分(其中五個)在訓練集和測試集中都以同等的數量包含。

np.random.seed(12)  
from sklearn.model_selection import train_test_split
 
bins = 5
sale_price_bins = pd.qcut(
    X['SalePrice'], q=bins, labels=list(range(bins))
)
X_train, X_test, y_train, y_test = train_test_split(
    X.drop(columns='SalePrice'),
    X['SalePrice'],
    random_state=12,
    stratify=sale_price_bins
)

3.3構建PyTorch模型

        接下來開始建立我們的PyTorch模型。我們將使用PyTorch實現一個具有批量輸入的神經網絡回歸,具體將涉及以下步驟。

  • 1. 將數據轉換為Torch tensors

  • 2. 定義模型結構

  • 3. 定義損失標準和優化器。

  • 4. 創建一個批次的數據加載器

  • 5. 跑步訓練

3.3.1.數據轉換

首先將數據轉換為torch tensors

from torch.autograd import Variable 
 
num_features = list(
    set(num_cols) - set(['SalePrice', 'Id'])
)
X_train_num_pt = Variable(
    torch.cuda.FloatTensor(
        X_train[num_features].values
    )
)
X_train_cat_pt = Variable(
    torch.cuda.LongTensor(
        X_train[cat_cols].values
    )
)
y_train_pt = Variable(
    torch.cuda.FloatTensor(y_train.values)
).view(-1, 1)
X_test_num_pt = Variable(
    torch.cuda.FloatTensor(
        X_test[num_features].values
    )
)
X_test_cat_pt = Variable(
   torch.cuda.LongTensor(
        X_test[cat_cols].values
    ).long()
)
y_test_pt = Variable(
    torch.cuda.FloatTensor(y_test.values)
).view(-1, 1)

        這可以確保我們將數字和分類數據加載到單獨的變量中,類似于NumPy。如果你把數據類型混合在一個變量(數組/矩陣)中,它們就會變成對象。我們希望把數值變量弄成浮點數,把分類變量弄成長(或int),索引我們的類別。我們還將訓練集和測試集分開。顯然,一個ID變量在模型中不應該是重要的。在最壞的情況下,如果ID與目標有任何相關性,它可能會引入目標泄漏。我們已經把它從這一步的處理中刪除了。

3.3.2定義模型架構
class RegressionModel(torch.nn.Module): 
  
    def __init__(self, X, num_cols, cat_cols, device=torch.device('cuda'), embed_dim=2, hidden_layer_dim=2, p=0.5): 
        super(RegressionModel, self).__init__() 
        self.num_cols = num_cols
        self.cat_cols = cat_cols
        self.embed_dim = embed_dim
        self.hidden_layer_dim = hidden_layer_dim
        
        self.embeddings = [
            torch.nn.Embedding(
                num_embeddings=len(X[col].unique()),
                embedding_dim=embed_dim
            ).to(device)
            for col in cat_cols
        ]
        hidden_dim = len(num_cols) + len(cat_cols) * embed_dim,
        
        # hidden layer
        self.hidden = torch.nn.Linear(torch.IntTensor(hidden_dim), hidden_layer_dim).to(device)
        self.dropout_layer = torch.nn.Dropout(p=p).to(device)
        self.hidden_act = torch.nn.ReLU().to(device)
        
        # output layer
        self.output = torch.nn.Linear(hidden_layer_dim, 1).to(device)
    
    def forward(self, num_inputs, cat_inputs):
        '''Forward method with two input variables -
        numeric and categorical.
        '''
        cat_x = [
            torch.squeeze(embed(cat_inputs[:, i] - 1))
            for i, embed in enumerate(self.embeddings)
        ]
        x = torch.cat(cat_x + [num_inputs], dim=1)
        x = self.hidden(x)
        x = self.dropout_layer(x)
        x = self.hidden_act(x)
        y_pred = self.output(x)
        return y_pred
 
house_model = RegressionModel(
    data_ames, num_features, cat_cols
)

        我們在兩個線性層(上的激活函數是整流線性單元激活(ReLU)函數。這里需要注意的是,我們不可能將相同的架構(很容易)封裝成一個順序模型,因為分類和數值類型上發生的操作不同。

3.3.3定義損失準則和優化器

        接下來,定義損失準則和優化器。我們將均方誤差(MSE)作為損失,隨機梯度下降作為我們的優化算法。

criterion = torch.nn.MSELoss().to(device)
optimizer = torch.optim.SGD(house_model.parameters(), lr=0.001)
3.3.4創建數據加載器

現在,創建一個數據加載器,每次輸入一批數據。

data_batch = torch.utils.data.TensorDataset(
    X_train_num_pt, X_train_cat_pt, y_train_pt
)
dataloader = torch.utils.data.DataLoader(
    data_batch, batch_size=10, shuffle=True
)

我們設置了10個批次的大小,接下來我們可以進行訓練了。

3.3.5.訓練模型

       基本上,我們要在epoch上循環,在每個epoch內推理出性能,計算出誤差,優化器根據誤差進行調整。這是在沒有訓練的內循環的情況下,在epochs上的循環。

from tqdm.notebook import trange
 
train_losses, test_losses = [], []
n_epochs = 30
for epoch in trange(n_epochs):
    train_loss, test_loss = 0, 0
  
    # print the errors in training and test:
    if epoch % 10 == 0 :
        print(
            'Epoch: {}/{}\t'.format(epoch, 1000),
            'Training Loss: {:.3f}\t'.format(
                train_loss / len(dataloader)
            ),
            'Test Loss: {:.3f}'.format(
                test_loss / len(dataloader)
            )
        )

 訓練是在這個循環里面對所有批次的訓練數據進行的。

for (x_train_num_batch,x_train_cat_batch,y_train_batch) in dataloader:
        (x_train_num_batch,x_train_cat_batch, y_train_batch) = (
                x_train_num_batch.to(device),
                x_train_cat_batch.to(device),
                y_train_batch.to(device))
        pred_ytrain = house_model.forward(x_train_num_batch, x_train_cat_batch)
        loss = torch.sqrt(criterion(pred_ytrain, y_train_batch)) 
 
        optimizer.zero_grad() 
        loss.backward() 
        optimizer.step()
        train_loss += loss.item()
        with torch.no_grad():
            house_model.eval()
            pred_ytest = house_model.forward(X_test_num_pt, X_test_cat_pt)
            test_loss += torch.sqrt(criterion(pred_ytest, y_test_pt))
 
        train_losses.append(train_loss / len(dataloader))
        test_losses.append(test_loss / len(dataloader))

訓練結果如下:

怎么用Pytorch搭建一個房價預測模型

我們取 nn.MSELoss 的平方根,因為 PyTorch 中 nn.MSELoss 的定義如下:

((input-target)**2).mean()

繪制一下我們的模型在訓練期間對訓練和驗證數據集的表現。

plt.plot(
    np.array(train_losses).reshape((n_epochs, -1)).mean(axis=1),
    label='Training loss'
)
plt.plot(
    np.array(test_losses).reshape((n_epochs, -1)).mean(axis=1),
    label='Validation loss'
)
plt.legend(frameon=False)
plt.xlabel('epochs')
plt.ylabel('MSE')

怎么用Pytorch搭建一個房價預測模型

        在我們的驗證損失停止下降之前,我們及時停止了訓練。我們還可以對目標變量進行排序和bin,并將預測結果與之對比繪制,以便了解模型在整個房價范圍內的表現。這是為了避免回歸中的情況,尤其是用MSE作為損失,即你只對一個中值范圍的預測很好,接近平均值,但對其他任何東西都做得不好。

怎么用Pytorch搭建一個房價預測模型

        我們可以看到,事實上,這個模型在整個房價范圍內的預測非常接近。事實上,我們得到的Spearman秩相關度約為93%,具有非常高的顯著性,這證實了這個模型的表現具有很高的準確性。

四、原理講解

        深度學習神經網絡框架使用不同的優化算法。其中流行的有隨機梯度下降(SGD)、均方根推進(RMSProp)和自適應矩估計(ADAM)。我們定義了隨機梯度下降作為我們的優化算法。另外,我們還可以定義其他優化器。

opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.6)
opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.1)
opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.8, 0.98))

        SGD的工作原理與梯度下降相同,只是它每次只在一個例子上工作。有趣的是,收斂性與梯度下降相似,并且更容易占用計算機內存。

        RMSProp的工作原理是根據梯度符號來調整算法的學習率。最簡單的變體是檢查最后兩個梯度符號,然后調整學習率,如果它們相同,則增加一個分數,如果它們不同,則減少一個分數。

        ADAM是最流行的優化器之一。它是一種自適應學習算法,根據梯度的第一和第二時刻改變學習率。

        Captum是一個工具,可以幫助我們了解在數據集上學習的神經網絡模型的來龍去脈。它可以幫助我們學習以下內容。

  • 特征重要性

  • 層級重要性

  • 神經元的重要性

        這在學習可解釋的神經網絡中是非常重要的。在這里,綜合梯度已經被應用于理解特征重要性。之后,還用層傳導法來證明神經元的重要性。

五、補充

        既然我們已經定義并訓練了我們的神經網絡,那么讓我們使用 captum 庫找到重要的特征和神經元。

from captum.attr import (
    IntegratedGradients,
    LayerConductance,
    NeuronConductance
)
house_model.cpu()
for embedding in house_model.embeddings:
    embedding.cpu()
 
house_model.cpu()
ing_house = IntegratedGradients(forward_func=house_model.forward, )
#X_test_cat_pt.requires_grad_()
X_test_num_pt.requires_grad_()
attr, delta = ing_house.attribute(
 X_test_num_pt.cpu(),
 target=None,
 return_convergence_delta=True,
 additional_forward_args=X_test_cat_pt.cpu()
)
attr = attr.detach().numpy()

 現在,我們有了一個NumPy的特征重要性數組。層和神經元的重要性也可以用這個工具獲得。讓我們來看看我們第一層的神經元importances。我們可以傳遞house_model.act1,這是第一層線性層上面的ReLU激活函數。

cond_layer1 = LayerConductance(house_model, house_model.act1)
cond_vals = cond_layer1.attribute(X_test, target=None)
cond_vals = cond_vals.detach().numpy()
df_neuron = pd.DataFrame(data = np.mean(cond_vals, axis=0), columns=['Neuron Importance'])
df_neuron['Neuron'] = range(10)

怎么用Pytorch搭建一個房價預測模型

這張圖顯示了神經元的重要性。顯然,一個神經元就是不重要的。我們還可以通過對之前得到的NumPy數組進行排序,看到最重要的變量。

df_feat = pd.DataFrame(np.mean(attr, axis=0), columns=['feature importance'] )
df_feat['features'] = num_features
df_feat.sort_values(
    by='feature importance', ascending=False
).head(10)

 這里列出了10個最重要的變量

怎么用Pytorch搭建一個房價預測模型

        通常情況下,特征導入可以幫助我們既理解模型,又修剪我們的模型,使其變得不那么復雜(希望減少過度擬合)。

到此,相信大家對“怎么用Pytorch搭建一個房價預測模型”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

湾仔区| 榆树市| 都兰县| 周宁县| 黑山县| 德兴市| 德保县| 嘉善县| 正镶白旗| 香格里拉县| 岐山县| 中方县| 广州市| 太原市| 洛南县| 河南省| 鄂州市| 旅游| 河东区| 醴陵市| 武宣县| 乌鲁木齐市| 威宁| 康保县| 英超| 盈江县| 彭州市| 宁乡县| 张家口市| 玉林市| 大石桥市| 汉中市| 江川县| 张家界市| 海安县| 同仁县| 嘉鱼县| 本溪| 七台河市| 太保市| 宿松县|