1. 程式人生 > >tf.keras入門(3) Predicting House Prices: Regression(boston_housing 資料集)

tf.keras入門(3) Predicting House Prices: Regression(boston_housing 資料集)

預測房價(迴歸)

預測 20 世紀 70 年代中期波士頓郊區房價的中間值。

該資料集包含 13 個不同的特徵:

  1. 人均犯罪率。
  2. 佔地面積超過 25000 平方英尺的住宅用地所佔的比例。
  3. 非零售商業用地所佔的比例(英畝/城鎮)。
  4. 查爾斯河虛擬變數(如果大片土地都臨近查爾斯河,則為 1;否則為 0)。
  5. 一氧化氮濃度(以千萬分之一為單位)。
  6. 每棟住宅的平均房間數。
  7. 1940 年以前建造的自住房所佔比例。
  8. 到 5 個波士頓就業中心的加權距離。
  9. 輻射式高速公路的可達性係數。
  10. 每 10000 美元的全額房產稅率。
  11. 生師比(按城鎮統計)。
  12. 1000 * (Bk - 0.63) ** 2,其中 Bk 是黑人所佔的比例(按城鎮統計)。
  13. 較低經濟階層人口所佔百分比。

資料預處理與網路結構

img

img

介面解釋

df = pd.DataFrame(train_data, columns=column_names) # DataFrame 型別類似於資料庫表結構的資料結構,其含有行索引和列索引,

print(df.head()) # 可以將DataFrame 想成是由相同索引的Series組成的Dict型別。

optimizer = tf.train.RMSPropOptimizer(0.001) 一種最優化方法 具體原理之後補上

防止過擬合或者做無用功 patience表示每多少Epoch檢測一次需不需要停止

early_stop = keras.callbacks.EarlyStopping(monitor='val_loss',patience=EPOCHS/20)

# Store training status
history = model.fit(train_data, train_labels, epochs=EPOCHS,
​                    validation_split=0.2, verbose=0, 
​                    callbacks=[early_stop, PrintDot()])   #verbose 表示是否顯示詳細資訊
test_predictions = model.predict(test_data)
test_predictions = test_predictions.flatten(order='C') #將二維矩陣轉為一維
# C means to flatten in row-major order   (C-style)  default
# F means to flatten in column-major order   (Fortran- style) 
# ‘A’ means to flatten in column-major order if a is Fortran contiguous
#  in memory, row-major order otherwise. ‘K’ means to flatten a in the 
# order the elements occur in memory. 

總結

  • 均方誤差 ( M S E MSE ) 是用於迴歸問題的常見損失函式(與分類問題不同)。
  • 同樣,用於迴歸問題的評估指標也與分類問題( a c c acc )不同。常見迴歸指標是平均絕對誤差 ( M A E MAE )。
  • 如果輸入資料特徵的值具有不同的範圍,則應分別縮放每個特徵。
  • 如果訓練資料不多,則選擇隱藏層較少的小型網路,以避免出現過擬合。
  • 早停法( k e r a s . c a l l b a c k s . E a r l y S t o p p i n g ( ) keras.callbacks.EarlyStopping() )是防止出現過擬合的實用技術。 (依據每個epoch)

Code

main.py

import tensorflow as tf 
from tensorflow import keras
import numpy as np
import pandas as pd
from plot import plot_history
from matplotlib import pyplot as plt

'''
資料預處理
'''
boston_housing = keras.datasets.boston_housing

(train_data, train_labels), (test_data, test_labels) = boston_housing.load_data()

# shuffle the training set
# 生成train_labels.shape個0~1間的隨機浮點數 
# 然後使用argsort 獲得排序後對應原List中的id 那麼由於之前是random的 
# 就相當於產生了一個隨機排列
order = np.argsort(np.random.random(train_labels.shape))
train_data = train_data[order]
train_labels = train_labels[order]

print("Training Set Size: {}".format(train_data.shape))
print("Testing Set Size: {}".format(test_data.shape))
print("第一個資料:\n",train_data[0])


# 使用 Pandas 庫在格式規範的表格中顯示資料集的前幾行:
column_names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
                'TAX', 'PTRATIO', 'B', 'LSTAT']


# DataFrame 型別類似於資料庫表結構的資料結構,其含有行索引和列索引,
# 可以將DataFrame 想成是由相同索引的Series組成的Dict型別。
df = pd.DataFrame(train_data, columns=column_names)  
print(df.head())
# 下面檢視標籤(以千美元為單位)
print(train_labels[0:10])


'''
標準化特徵 

雖然在未進行特徵標準化的情況下,模型可能會收斂,但這樣做會增
加訓練難度,而且使生成的模型更加依賴於在輸入中選擇使用的單位。
'''
# 按照列求平均 (很自然)和 標準差
mean = train_data.mean(axis = 0)
std = train_data.std(axis=0)
train_data = (train_data - mean) / std
test_data = (test_data - mean) / std
print(train_data[0]) # First training sample , normalized


'''
構建模型
'''
def build_model():
    model = keras.Sequential()
    model.add(keras.layers.Dense(64, activation=tf.nn.relu,
                     input_shape = (train_data.shape[1],)))
    model.add(keras.layers.Dense(64, activation=tf.nn.relu))
    model.add(keras.layers.Dense(1))
    optimizer = tf.train.RMSPropOptimizer(0.001)

    model.compile(loss='mse',
                  optimizer = optimizer,
                  metrics=['mae'])# mse:Mean squared error   mae:Mean Abs Error
    return model


model = build_model()
model.summary()
# 可見第一層有896: (13+1)*64 個引數   
# 第二層有4160: (64+1)*64個引數   
# 第三層有65: (64+1)*1個引數


'''
訓練模型
'''
EPOCHS = 500

# Display training progress by 
# printing a single dot for each completed epoch
class PrintDot(keras.callbacks.Callback):
    def on_epoch_end(self, epoch, logs):
        if epoch % 100 ==0 : print('')  # 每一百個換行一次
        print('.',end='')

# The patience parameter is the amount of epochs to check for improvement
# 防止過擬合或者做無用功
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss',patience=EPOCHS/20)


# Store training stats
history = model.fit(train_data, train_labels, epochs=EPOCHS,
                    validation_split=0.2, verbose=0, 
                    callbacks=[early_stop, PrintDot()])   #verbose 表示是否顯示詳細資訊


'''
作LOSS圖
'''
plot_history(history)


'''
在測試集上評估
'''
[loss, mae] = model.evaluate(test_data, test_labels, verbose=1)
print("\nTesting set Mean Abs Error: ${:7.2f}".format(mae * 1000))


'''
預測
'''
test_predictions = model.predict(test_data)
test_predictions = test_predictions.flatten(order='C') 
# C means to flatten in row-major order   (C-style)  default
# F means to flatten in column-major order   (Fortran- style) 
# ‘A’ means to flatten in column-major order if a is Fortran contiguous
#  in memory, row-major order otherwise. ‘K’ means to flatten a in the 
# order the elements occur in memory. 

plt.figure()
plt.scatter(test_labels, test_predictions)
plt.xlabel('True Values [1000$]')
plt.ylabel('Predictions [1000$]')
plt.axis('equal')
plt.xlim(plt.xlim())
plt.ylim(plt.ylim())
_ = plt.plot([-100, 100], [-100, 100]) #參考線
plt.savefig('預測結果與真實值對比.png')

plt.figure()
error = test_predictions - test_labels
n,bins,patches = plt.hist(error, bins = 50) # 分成50塊 檢視每個error區間內對應的數量
plt.xlabel("Prediction Error [1000$]")
_ = plt.ylabel("Count")
plt.savefig('預測誤差.png')

print(type(n),type(bins),type(patches))
print(n,bins)

plt.show()


plot.py

import matplotlib.pyplot as plt
import numpy as np

def plot_history(history):
    Dict = history.history
    plt.figure()
    plt.xlabel('Epoch')
    plt.ylabel('Mean Abs Error [1000$]')
    plt.plot(history.epoch, np.array(Dict['mean_absolute_error']),
                label='Train_Loss')
    plt.plot(history.epoch, np.array(Dict['val_mean_absolute_error']),
                label='Val_Loss')
    plt.legend()
    plt.ylim([0, 5])
    plt.savefig('訓練過程.png')

img

img

img