《Python 深度学习》3.6 预测房价:回归问题(代码)

Predicting house prices: a regression example

波士顿房价数据集

本节将要预测 20 世纪 70 年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。本节用到的数据集与前面两个例子有一个有趣的区别。它包含的数据点相对较少,只有 506 个,分为 404 个训练样本和 102 个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特性是比例,取值范围为 0~1;有的取值范围为 1~12;还有的取值范围为 0~100,等等。

由于是在Jupyter Notebook上直接copy下来的,所以使用时请记得注意。

## 1. 加载波士顿房价数据集

from tensorflow.keras.datasets import boston_housing
(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()

train_data.shape

train_targets.shape

train_targets

test_data.shape

test_targets.shape

## 2. 数据标准化

#如果量纲不一致,最好对输入向量进行标准化,此处采用减去均值除以标准差。
#即对于输入数据的每个特征(输入数据矩阵中的列),减去特征平均值,再除以标准差,这样得到的特征平均值为0,标准差为1。
mean = train_data.mean(axis=0)
train_data -= mean
std = train_data.std(axis=0)
train_data /= std

test_data -= mean
test_data /= std

## 3. 模型定义

from tensorflow.keras import models
from tensorflow.keras import layers

def build_model(): #因为需要将同一个模型多次实例化,所以用一个函数来构建模型。
    model = models.Sequential()
    model.add(layers.Dense(64, activation='relu',input_shape=(train_data.shape[1],)))
    model.add(layers.Dense(64, activation='relu'))
    model.add(layers.Dense(1)) #标量回归
    model.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])
    return model

## 4. K折验证

import numpy as np
k = 4   #由于训练集数量少,为了得到较好的超参数,采用K折交叉法,此处K取4,也就是3折用作训练,1折用作验证。
num_val_samples = len(train_data) // k
num_epochs = 100
all_scores = []
for i in range(k):
    print('processing fold #', i)
    val_data = train_data[i * num_val_samples: (i + 1) * num_val_samples] #准备验证数据:第K个分区的数据
    val_targets = train_targets[i * num_val_samples: (i + 1) * num_val_samples]
    
    partial_train_data = np.concatenate(  #准备训练数据:其他所有分区的数据
    [train_data[:i * num_val_samples],
    train_data[(i + 1) * num_val_samples:]],
    axis=0)
    partial_train_targets = np.concatenate(
    [train_targets[:i * num_val_samples],
    train_targets[(i + 1) * num_val_samples:]],
    axis=0)
    
    model = build_model()  #构建Keras模型(已编译)
    model.fit(partial_train_data, partial_train_targets,
    epochs=num_epochs, batch_size=1, verbose=0) #训练模型(静默模式,verbose=0)
    val_mse, val_mae = model.evaluate(val_data, val_targets, verbose=0) #在验证数据上评估模型
    all_scores.append(val_mae)

all_scores

np.mean(all_scores)

## 5. 保存每折的验证结果

num_epochs = 500
all_mae_histories = []
for i in range(k):
    print('processing fold ##', i)
    val_data = train_data[i * num_val_samples: (i + 1) * num_val_samples] #准备验证数据:第K个分区的数据
    val_targets = train_targets[i * num_val_samples: (i + 1) * num_val_samples]
    
    partial_train_data = np.concatenate(  #准备训练数据:其他所有分区的数据
    [train_data[:i * num_val_samples],
    train_data[(i + 1) * num_val_samples:]],
    axis=0)
    partial_train_targets = np.concatenate(
    [train_targets[:i * num_val_samples],
    train_targets[(i + 1) * num_val_samples:]],
    axis=0)
    
    model = build_model()  #构建Keras模型(已编译)
    history=model.fit(partial_train_data, partial_train_targets,validation_data=(val_data,val_targets),
                      epochs=num_epochs, batch_size=1, verbose=0) #训练模型(静默模式,verbose=0)
    mae_history = history.history['val_mae'] #在验证数据上评估模型
    all_mae_histories.append(mae_history)

history_dict=history.history

history_dict.keys()

## 6. 计算所有轮次中所有折MAE的平均值

average_mae_history=[np.mean([x[i] for x in all_mae_histories]) for i in range(num_epochs)]

## 7. 绘制验证分数

import matplotlib.pyplot as plt

plt.plot(range(1,len(average_mae_history)+1),average_mae_history)
plt.xlabel('Epochs')
plt.ylabel('Validation MAE')
 
plt.show()

## 8. 绘制验证分数(删除前10个数据点)

def smooth_curve(points,alpha = 0.9):
    smothed_points = []
    for point in points:
        if smothed_points:
            pre_point = smothed_points[-1]
            smothed_points.append (pre_point*alpha + point*(1- alpha))
        else:
            smothed_points.append(point)
    return smothed_points
 
smooth_mae_history = smooth_curve(average_mae_history[10:])
 
plt.plot(range(1,len(smooth_mae_history)+1),smooth_mae_history)
plt.xlabel('Epochs')
plt.ylabel('Validation MAE after 10 epchs(smoothed)')
 
plt.show()

## 9. 计算所有轮次中所有折MAE的平均值

# Get a fresh, compiled model.
model = build_model()
# Train it on the entirety of the data.
model.fit(train_data, train_targets,
          epochs=80, batch_size=16, verbose=0)
test_mse_score, test_mae_score = model.evaluate(test_data, test_targets)

test_mae_score

test_mse_score

小结: 

  • 回归问题使用的损失函数与分类问题不同。回归常用的损失函数是均方误差(MSE)。
  • 同样,回归问题使用的评估指标也与分类问题不同。显而易见,精度的概念不适用于回归问题。常见的回归指标是平均绝对误差(MAE)。
  • 如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
  • 如果可用的数据很少,使用 K 折验证可以可靠地评估模型。
  • 如果可用的训练数据很少,最好使用隐藏层较少(通常只有一到两个)的小型网络,以避免严重的过拟合。

相关链接:

《Python 深度学习》3.4 电影评论分类:二分类问题(代码)

《Python 深度学习》3.5 新闻分类:多分类问题(代码)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值