Regression with Keras
在本教程中,您將學習如何使用 Keras 和深度學習執行回歸, 您將學習如何訓練 Keras 神經網路進行回歸和連續值預測,特別是在房價預測的背景下,

今天的帖子開始了關于深度學習、回歸和連續值預測的 3 部分系列,
我們將在房價預測的背景下研究 Keras 回歸預測:
第 1 部分:今天我們將訓練 Keras 神經網路,以根據分類和數字屬性(例如臥室/浴室的數量、平方英尺、郵政編碼等)來預測房價,
第 2 部分:下周我們將訓練 Keras 卷積神經網路,以根據房屋本身的輸入影像(即房屋、臥室、浴室和廚房的正面視圖)預測房價,
第 3 部分:在兩周內,我們將定義和訓練一個神經網路,該網路將我們的分類/數字屬性與我們的影像相結合,從而比單獨使用屬性或影像進行更好、更準確的房價預測,
與分類(預測標簽)不同,回歸使我們能夠預測連續值,
例如,分類可能能夠預測以下值之一:{便宜、負擔得起、昂貴},
另一方面,回歸將能夠預測確切的美元金額,例如“這所房子的估計價格為 489,121 美元”,
在許多實際情況中,例如房價預測或股票市場預測,應用回歸而不是分類對于獲得良好的預測至關重要,
要學習如何使用 Keras 執行回歸,請繼續閱讀!
在本教程的第一部分,我們將簡要討論分類和回歸之間的區別,
然后,我們將探索用于本系列 Keras 回歸教程的房價資料集, 從那里,我們將配置我們的開發環境并審查我們的專案結構,
在此程序中,我們將學習如何使用 Pandas 加載我們的房價資料集并定義一個用于 Keras 回歸預測的神經網路,
最后,我們將訓練我們的 Keras 網路,然后評估回歸結果,
分類與回歸
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-JJD3jMod-1635832983723)(https://pyimagesearch.com/wp-content/uploads/2019/01/keras_regression_classification_vs_reg.png?_ga=2.27468348.1485253468.1635742256-1229975524.1635374294)]](https://img.uj5u.com/2021/11/03/280412030729415.png)
圖 1:分類網路預測標簽(頂部), 相比之下,回歸網路可以預測數值(底部), 在這篇博文中,我們將使用 Keras 對房屋資料集進行回歸,
通常,我們會在分類的背景下討論 Keras 和深度學習——預測標簽以表征影像或輸入資料集的內容, 另一方面,回歸使我們能夠預測連續值, 讓我們再次考慮房價預測的任務, 眾所周知,分類用于預測類標簽, 對于房價預測,我們可以將分類標簽定義為:
labels = {very cheap, cheap, affordable, expensive, very expensive}
如果我們進行分類,我們的模型就可以學習根據一組輸入特征預測這五個值中的一個,
然而,這些標簽僅代表房屋的潛在價格范圍,但不代表房屋的實際成本,
為了預測房屋的實際成本,我們需要進行回歸,
使用回歸,我們可以訓練模型來預測連續值, 例如,雖然分類可能只能預測一個標簽,但回歸可以說: “根據我輸入的資料,我估計這所房子的成本為 781,993 美元,” 上面的圖 1 提供了執行分類和回歸的可視化, 在本教程的其余部分,您將學習如何使用 Keras 訓練神經網路進行回歸,
房價資料集

我們今天將使用的資料集來自 2016 年的論文,Ahmed 和 Moustafa 撰寫的基于視覺和文本特征的房價估計, 該資料集包括數值/分類屬性以及 535 個資料點的影像,使其成為研究回歸和混合資料預測的絕佳資料集, 房屋資料集包括四個數值和分類屬性:
- 臥室數量
- 浴室數量
- 面積(即平方英尺)
- 郵政編碼
這些屬性以 CSV 格式存盤在磁盤上, 在本教程的后面,我們將使用 pandas(一種用于資料分析的流行 Python 包)從磁盤加載這些屬性, 每個房子還提供了總共四張圖片:
- 臥室
- 浴室
- 廚房
- 房子的正面圖
房屋資料集的最終目標是預測房屋本身的價格,
環境配置

對于這個由 3 部分組成的系列博客文章,您需要安裝以下軟體包:
- NumPy
- sklearn-learn
- pandas
- Keras
- OpenCV(用于本系列的下兩篇博文)
下載資料集
$ git clone https://github.com/emanhamed/Houses-dataset
如果有git,則用git下載,沒有直接打開網頁鏈接下載,
專案結構
$ tree --dirsfirst --filelimit 10
.
├── Houses-dataset
│ ├── Houses Dataset [2141 entries]
│ └── README.md
├── model
│ ├── __init__.py
│ ├── datasets.py
│ └── models.py
└── mlp_regression.py
datasets.py :我們用于從資料集中加載數值/分類資料的腳本
models.py:神經網路模型 今天將審查這兩個腳本, 此外,我們將在接下來的兩個教程中重用 datasets.py 和 models.py(經過修改),以保持我們的代碼有條理和可重用,
回歸 + Keras 腳本包含在 mlp_regression.py 中,我們也將對其進行講解,
加載房價資料集
在我們訓練 Keras 回歸模型之前,我們首先需要加載房屋資料集的數值和分類資料, 打開 datasets.py 檔案并插入以下代碼:
# import the necessary packages
from sklearn.preprocessing import LabelBinarizer
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
import numpy as np
import glob
import cv2
import os
def load_house_attributes(inputPath):
# initialize the list of column names in the CSV file and then
# load it using Pandas
cols = ["bedrooms", "bathrooms", "area", "zipcode", "price"]
df = pd.read_csv(inputPath, sep=" ", header=None, names=cols)
我們首先從 scikit-learn、pandas、NumPy 和 OpenCV 匯入庫和模塊, 接下來將使用 OpenCV,因為我們將向該腳本添加加載影像的功能, 定義了 load_house_attributes 函式,它接受輸入資料集的路徑, 在函式內部,我們首先定義 CSV 檔案中列的名稱, 從那里,我們使用 pandas 的函式 read_csv 將 CSV 檔案作為第 14 行的日期框架 (df) 加載到記憶體中, 下面你可以看到我們輸入資料的一個例子,包括臥室數量、浴室數量、面積(即平方英尺)、郵政編碼、代碼,最后是我們的模型應該訓練來預測的目標價格:
bedrooms bathrooms area zipcode price
0 4 4.0 4053 85255 869500.0
1 4 3.0 3343 36372 865200.0
2 3 4.0 3923 85266 889000.0
3 5 5.0 4022 85262 910000.0
4 3 4.0 4116 85266 971226.0
讓我們完成 load_house_attributes 函式的其余部分:
# determine (1) the unique zip codes and (2) the number of data
# points with each zip code
zipcodes = df["zipcode"].value_counts().keys().tolist()
counts = df["zipcode"].value_counts().tolist()
# loop over each of the unique zip codes and their corresponding
# count
for (zipcode, count) in zip(zipcodes, counts):
# the zip code counts for our housing dataset is *extremely*
# unbalanced (some only having 1 or 2 houses per zip code)
# so let's sanitize our data by removing any houses with less
# than 25 houses per zip code
if count < 25:
idxs = df[df["zipcode"] == zipcode].index
df.drop(idxs, inplace=True)
# return the data frame
return df
在剩下的幾行中,我們:
- 確定唯一的郵政編碼集,然后計算每個唯一郵政編碼的資料點數,
- 過濾掉計數低的郵政編碼, 對于某些郵政編碼,我們只有一兩個資料點,這使得獲得準確的房價估算即使并非不可能,也極具挑戰性,
- 將資料回傳給呼叫函式,
現在讓我們創建用于預處理資料的 process_house_attributes 函式:
def process_house_attributes(df, train, test):
# initialize the column names of the continuous data
continuous = ["bedrooms", "bathrooms", "area"]
# performin min-max scaling each continuous feature column to
# the range [0, 1]
cs = MinMaxScaler()
trainContinuous = cs.fit_transform(train[continuous])
testContinuous = cs.transform(test[continuous])
我們定義函式, process_house_attributes 函式接受三個引數:
- df :pandas 生成的我們的資料框(前面的函式幫助我們從資料框中洗掉一些記錄)
- train :我們針對房價資料集的訓練資料
- test :我們的測驗資料,
然后,我們定義了連續資料的列,包括臥室、浴室和房屋大小,
我們將采用這些值并使用 sklearn-learn 的 MinMaxScaler 將連續特征縮放到范圍 [0, 1], 現在我們需要預處理我們的分類特征,即郵政編碼:
# one-hot encode the zip code categorical data (by definition of
# one-hot encoing, all output features are now in the range [0, 1])
zipBinarizer = LabelBinarizer().fit(df["zipcode"])
trainCategorical = zipBinarizer.transform(train["zipcode"])
testCategorical = zipBinarizer.transform(test["zipcode"])
# construct our training and testing data points by concatenating
# the categorical features with the continuous features
trainX = np.hstack([trainCategorical, trainContinuous])
testX = np.hstack([testCategorical, testContinuous])
# return the concatenated training and testing data
return (trainX, testX)
首先,我們將對郵政編碼進行one-hot編碼,
然后,我們將使用 NumPy 的 hstack 函式將分類特征與連續特征連接起來,將生成的訓練和測驗集作為元組回傳, 請記住,現在我們的分類特征和連續特征都在 [0, 1] 范圍內,
實作回歸神經網路

圖 5:我們的 Keras 回歸架構, 網路的輸入是一個資料點,包括家庭的#臥室、#浴室、面積/平方英尺和郵政編碼, 網路的輸出是具有線性激活函式的單個神經元, 線性激活允許神經元輸出房屋的預測價格,
在我們訓練 Keras 網路進行回歸之前,我們首先需要定義架構本身, 今天我們將使用一個簡單的多層感知器 (MLP),如圖 5 所示, 打開models.py檔案并插入以下代碼:
# import the necessary packages
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.layers import MaxPooling2D
from tensorflow.keras.layers import Activation
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Input
from tensorflow.keras.models import Model
def create_mlp(dim, regress=False):
# define our MLP network
model = Sequential()
model.add(Dense(8, input_dim=dim, activation="relu"))
model.add(Dense(4, activation="relu"))
# check to see if the regression node should be added
if regress:
model.add(Dense(1, activation="linear"))
# return our model
return model
首先,我們將從 Keras 匯入所有必要的模塊,通過撰寫一個名為 create_mlp 的函式來定義 MLP 架構, 該函式接受兩個引數: dim : 定義我們的輸入維度 regress : 一個布林值,定義是否應該添加我們的回歸神經元 我們將繼續使用dim-8-4架構開始構建我們的MLP, 如果我們正在執行回歸,我們會添加一個 Dense 層,其中包含一個具有線性激活函式的神經元, 通常我們使用基于 ReLU 的激活,但由于我們正在執行回歸,我們需要一個線性激活, 最后,回傳模型,
實作Keras 回歸腳本
現在是時候把所有的部分放在一起了!
打開 mlp_regression.py 檔案并插入以下代碼:
# import the necessary packages
from tensorflow.keras.optimizers import Adam
from sklearn.model_selection import train_test_split
from pyimagesearch import datasets
from pyimagesearch import models
import numpy as np
import argparse
import locale
import os
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", type=str, required=True,
help="path to input dataset of house images")
args = vars(ap.parse_args())
我們首先匯入必要的包、模塊和庫,
我們的腳本只需要一個命令列引數 --dataset, 當您在終端中運行訓練腳本時,您需要提供 --dataset 開關和資料集的實際路徑,
讓我們加載房屋資料集屬性并構建我們的訓練和測驗分割:
# construct the path to the input .txt file that contains information
# on each house in the dataset and then load the dataset
print("[INFO] loading house attributes...")
inputPath = os.path.sep.join([args["dataset"], "HousesInfo.txt"])
df = datasets.load_house_attributes(inputPath)
# construct a training and testing split with 75% of the data used
# for training and the remaining 25% for evaluation
print("[INFO] constructing training/testing split...")
(train, test) = train_test_split(df, test_size=0.25, random_state=42)
使用我們方便的 load_house_attributes 函式,并通過將 inputPath 傳遞給資料集本身,我們的資料被加載到記憶體中,
訓練集和測驗集按照4:1切分, 讓我們擴展我們的房價資料:
# find the largest house price in the training set and use it to
# scale our house prices to the range [0, 1] (this will lead to
# better training and convergence)
maxPrice = train["price"].max()
trainY = train["price"] / maxPrice
testY = test["price"] / maxPrice
如評論中所述,將我們的房價縮放到 [0, 1] 范圍將使我們的模型更容易訓練和收斂, 將輸出目標縮放到 [0, 1] 將減少我們的輸出預測范圍(相對于 [0, maxPrice ]),不僅使我們的網路訓練更容易、更快,而且使我們的模型能夠獲得更好的結果, 因此,我們獲取訓練集中的最高價格,并相應地擴展我們的訓練和測驗資料, 現在讓我們處理房屋屬性:
# process the house attributes data by performing min-max scaling
# on continuous features, one-hot encoding on categorical features,
# and then finally concatenating them together
print("[INFO] processing data...")
(trainX, testX) = datasets.process_house_attributes(df, train, test)
從 datasets.py 腳本中回憶 process_house_attributes 函式:
- 預處理我們的分類和連續特征,
- 通過最小-最大縮放將我們的連續特征縮放到范圍 [0, 1],
- One-hot 編碼我們的分類特征,
- 連接分類特征和連續特征以形成最終特征向量,
現在讓我們繼續訓練MLP模型:
# create our MLP and then compile the model using mean absolute
# percentage error as our loss, implying that we seek to minimize
# the absolute percentage difference between our price *predictions*
# and the *actual prices*
model = models.create_mlp(trainX.shape[1], regress=True)
opt = Adam(lr=1e-3, decay=1e-3 / 200)
model.compile(loss="mean_absolute_percentage_error", optimizer=opt)
# train the model
print("[INFO] training model...")
model.fit(x=trainX, y=trainY,
validation_data=(testX, testY),
epochs=200, batch_size=8)
我們的模型用 Adam 優化器初始化,然后compile, 請注意,我們使用平均絕對百分比誤差作為我們的損失函式,這表明我們尋求最小化預測價格和實際價格之間的平均百分比差異,
訓練,
訓練完成后,我們可以評估我們的模型并總結我們的結果:
# make predictions on the testing data
print("[INFO] predicting house prices...")
preds = model.predict(testX)
# compute the difference between the *predicted* house prices and the
# *actual* house prices, then compute the percentage difference and
# the absolute percentage difference
diff = preds.flatten() - testY
percentDiff = (diff / testY) * 100
absPercentDiff = np.abs(percentDiff)
# compute the mean and standard deviation of the absolute percentage
# difference
mean = np.mean(absPercentDiff)
std = np.std(absPercentDiff)
# finally, show some statistics on our model
locale.setlocale(locale.LC_ALL, "en_US.UTF-8")
print("[INFO] avg. house price: {}, std house price: {}".format(
locale.currency(df["price"].mean(), grouping=True),
locale.currency(df["price"].std(), grouping=True)))
print("[INFO] mean: {:.2f}%, std: {:.2f}%".format(mean, std))
第 57 行指示 Keras 對我們的測驗集進行預測,
使用預測,我們計算:
- 預測房價與實際房價之間的差異,
- 百分比差異,
- 絕對百分比差異,
- 計算絕對百分比差異的均值和標準差,
- 結果列印,
使用 Keras 進行回歸并沒有那么難,對吧? 讓我們訓練模型并分析結果!
Keras 回歸結果

圖 6: Keras 回歸模型采用四個數值輸入,產生一個數值輸出:房屋的預測值,
打開一個終端并提供以下命令(確保 --dataset 命令列引數指向您下載房價資料集的位置):
$ python mlp_regression.py --dataset Houses-dataset/Houses\ Dataset/
[INFO] loading house attributes...
[INFO] constructing training/testing split...
[INFO] processing data...
[INFO] training model...
Epoch 1/200
34/34 [==============================] - 0s 4ms/step - loss: 73.0898 - val_loss: 63.0478
Epoch 2/200
34/34 [==============================] - 0s 2ms/step - loss: 58.0629 - val_loss: 56.4558
Epoch 3/200
34/34 [==============================] - 0s 1ms/step - loss: 51.0134 - val_loss: 50.1950
Epoch 4/200
34/34 [==============================] - 0s 1ms/step - loss: 47.3431 - val_loss: 47.6673
Epoch 5/200
34/34 [==============================] - 0s 1ms/step - loss: 45.5581 - val_loss: 44.9802
Epoch 6/200
34/34 [==============================] - 0s 1ms/step - loss: 42.4403 - val_loss: 41.0660
Epoch 7/200
34/34 [==============================] - 0s 1ms/step - loss: 39.5451 - val_loss: 34.4310
Epoch 8/200
34/34 [==============================] - 0s 2ms/step - loss: 34.5027 - val_loss: 27.2138
Epoch 9/200
34/34 [==============================] - 0s 2ms/step - loss: 28.4326 - val_loss: 25.1955
Epoch 10/200
34/34 [==============================] - 0s 2ms/step - loss: 28.3634 - val_loss: 25.7194
...
Epoch 195/200
34/34 [==============================] - 0s 2ms/step - loss: 20.3496 - val_loss: 22.2558
Epoch 196/200
34/34 [==============================] - 0s 2ms/step - loss: 20.4404 - val_loss: 22.3071
Epoch 197/200
34/34 [==============================] - 0s 2ms/step - loss: 20.0506 - val_loss: 21.8648
Epoch 198/200
34/34 [==============================] - 0s 2ms/step - loss: 20.6169 - val_loss: 21.5130
Epoch 199/200
34/34 [==============================] - 0s 2ms/step - loss: 19.9067 - val_loss: 21.5018
Epoch 200/200
34/34 [==============================] - 0s 2ms/step - loss: 19.9570 - val_loss: 22.7063
[INFO] predicting house prices...
[INFO] avg. house price: $533,388.27, std house price: $493,403.08
[INFO] mean: 22.71%, std: 18.26%
從我們的輸出中可以看出,我們最初的平均絕對百分比誤差高達 73%,然后迅速下降到 30% 以下,
當我們完成訓練時,我們可以看到我們的網路開始有點過擬合了, 我們的訓練損失低至~20%; 然而,我們的驗證損失約為 23%,
計算我們最終的平均絕對百分比誤差,我們得到的最終值為 22.71%, 這個值是什么意思?
我們最終的平均絕對百分比誤差意味著,平均而言,我們的網路在其房價預測中將降低約 23%,標準差為約 18%,
房價資料集的局限性
在房價預測中獲得 22% 的折扣是一個好的開始,但肯定不是我們正在尋找的準確性型別, 也就是說,這種預測準確性也可以看作是房價資料集本身的局限性, 請記住,資料集僅包含四個屬性:
- 臥室數量
- 浴室數量
- 面積(即平方英尺)
- 郵政編碼
大多數其他房價資料集包含更多屬性,
例如,波士頓房價資料集包括總共 14 個可用于房價預測的屬性(盡管該資料集確實存在一些種族歧視), Ames House 資料集包含超過 79 個不同的屬性,可用于訓練回歸模型, 在本系列的下兩篇文章中,我將向您展示如何: 將我們的數值/分類資料與房屋影像相結合,生成的模型優于我們之前所有的 Keras 回歸實驗,
總結
在本教程中,您學習了如何使用 Keras 深度學習庫進行回歸, 具體來說,我們使用 Keras 和回歸根據四個數值和分類屬性來預測房屋價格:
- 臥室數量
- 浴室數量
- 面積(即平方英尺)
- 郵政編碼
總的來說,我們的神經網路獲得了 22.71% 的平均絕對百分比誤差,這意味著,平均而言,我們的房價預測將下降 22.71%,
代碼和模型下載:
https://download.csdn.net/download/hhhhhhhhhhwwwwwwwwww/35595361
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/345620.html
標籤:AI
上一篇:VMware 與戴爾正式“分手”
下一篇:基于深度學習的云反演-文獻分析
