《Python 深度学习》刷书笔记 Chapter 3 预测房价:回归问题

文章目录

  • 波士顿房价数据集
  • 3-24 加载波士顿房价数据
  • 3-25 数据标准化
  • 3-26 模型定义
  • 3-27 K折验证
  • 3-28 训练500轮,保存每折的验证结果
  • 3-29 计算所有轮次茨种的K折验证分数平均值
  • 3-30 绘制验证分数
  • 3-31 重新绘制验证分数
  • 3-32 绘制最终模型
  • 写在最后


波士顿房价数据集


在Chapter3的前面两个例子中我们都是使用深度学习算法来解决分类问题,而另一种在机器学习领域经常遇到的是回归问题

  • 回归问题: 预测一个连续值(用于预测功能居多)
  • 分类问题: 将输入的预测数据点贴上一个单一的离散标签(例如:是、不是,是A类物品,是D类物品)

在本例中将要根据数据预测20实际70年代中期的波士顿郊区房屋价格的中位数,可能影响的因素有犯罪率、房产税率等等

数据特征

  • 数据样本点较少,只有506个(404个训练样本、102个测试样本)
  • 每个样本点有不同的取值范围(0~1(百分比,如0.87、0.21等)、1~12(等级))

3-24 加载波士顿房价数据


# 加载数据

from keras.datasets import boston_housing

(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()

# 数据观察

print(train_data.shape) # 对应影响房子价格的因素有13种
print(train_data[0])
print(test_data.shape)
print(train_targets) # 房子价格,单位:千美元
(404, 13)
[  1.23247   0.        8.14      0.        0.538     6.142    91.7
   3.9769    4.      307.       21.      396.9      18.72   ]
(102, 13)
[15.2 42.3 50.  21.1 17.7 18.5 11.3 15.6 15.6 14.4 12.1 17.9 23.1 19.9
 15.7  8.8 50.  22.5 24.1 27.5 10.9 30.8 32.9 24.  18.5 13.3 22.9 34.7
 16.6 17.5 22.3 16.1 14.9 23.1 34.9 25.  13.9 13.1 20.4 20.  15.2 24.7
 22.2 16.7 12.7 15.6 18.4 21.  30.1 15.1 18.7  9.6 31.5 24.8 19.1 22.
 14.5 11.  32.  29.4 20.3 24.4 14.6 19.5 14.1 14.3 15.6 10.5  6.3 19.3
 19.3 13.4 36.4 17.8 13.5 16.5  8.3 14.3 16.  13.4 28.6 43.5 20.2 22.
 23.  20.7 12.5 48.5 14.6 13.4 23.7 50.  21.7 39.8 38.7 22.2 34.9 22.5
 31.1 28.7 46.  41.7 21.  26.6 15.  24.4 13.3 21.2 11.7 21.7 19.4 50.
 22.8 19.7 24.7 36.2 14.2 18.9 18.3 20.6 24.6 18.2  8.7 44.  10.4 13.2
 21.2 37.  30.7 22.9 20.  19.3 31.7 32.  23.1 18.8 10.9 50.  19.6  5.
 14.4 19.8 13.8 19.6 23.9 24.5 25.  19.9 17.2 24.6 13.5 26.6 21.4 11.9
 22.6 19.6  8.5 23.7 23.1 22.4 20.5 23.6 18.4 35.2 23.1 27.9 20.6 23.7
 28.  13.6 27.1 23.6 20.6 18.2 21.7 17.1  8.4 25.3 13.8 22.2 18.4 20.7
 31.6 30.5 20.3  8.8 19.2 19.4 23.1 23.  14.8 48.8 22.6 33.4 21.1 13.6
 32.2 13.1 23.4 18.9 23.9 11.8 23.3 22.8 19.6 16.7 13.4 22.2 20.4 21.8
 26.4 14.9 24.1 23.8 12.3 29.1 21.  19.5 23.3 23.8 17.8 11.5 21.7 19.9
 25.  33.4 28.5 21.4 24.3 27.5 33.1 16.2 23.3 48.3 22.9 22.8 13.1 12.7
 22.6 15.  15.3 10.5 24.  18.5 21.7 19.5 33.2 23.2  5.  19.1 12.7 22.3
 10.2 13.9 16.3 17.  20.1 29.9 17.2 37.3 45.4 17.8 23.2 29.  22.  18.
 17.4 34.6 20.1 25.  15.6 24.8 28.2 21.2 21.4 23.8 31.  26.2 17.4 37.9
 17.5 20.   8.3 23.9  8.4 13.8  7.2 11.7 17.1 21.6 50.  16.1 20.4 20.6
 21.4 20.6 36.5  8.5 24.8 10.8 21.9 17.3 18.9 36.2 14.9 18.2 33.3 21.8
 19.7 31.6 24.8 19.4 22.8  7.5 44.8 16.8 18.7 50.  50.  19.5 20.1 50.
 17.2 20.8 19.3 41.3 20.4 20.5 13.8 16.5 23.9 20.6 31.5 23.3 16.8 14.
 33.8 36.1 12.8 18.3 18.7 19.1 29.  30.1 50.  50.  22.  11.9 37.6 50.
 22.7 20.8 23.5 27.9 50.  19.3 23.9 22.6 15.2 21.7 19.2 43.8 20.3 33.2
 19.9 22.5 32.7 22.  17.1 19.  15.  16.1 25.1 23.7 28.7 37.2 22.6 16.4
 25.  29.8 22.1 17.4 18.1 30.3 17.5 24.7 12.6 26.5 28.7 13.3 10.4 24.4
 23.  20.  17.8  7.  11.8 24.4 13.8 19.4 25.2 19.4 19.4 29.1]

3-25 数据标准化


将不同取值范围的数据直接塞进网络中的做法是有问题的,为此我们应对所有的输入数据进行标准化:减去样本平均值,再除以标准差(所得的数据特征平均值 = 0, 标准差 = 1)

X ^ i j = X i j − X ˉ i ∑ j = 1 N ( X i j − X ˉ i ) 2 \hat{X}_{i j}=\frac{X_{i j}-\bar{X}_{i}}{\sqrt{\sum_{j=1}^{N}\left(X_{i j}-\bar{X}_{i}\right)^{2}}} X^ij=j=1N(XijXˉi)2 XijXˉi


# 数据标准化

# 样本数据标准化
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-26 模型定义


# 定义模型
from keras import models
from 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))
    # 网络的最后一层只有一个单元,没有激活层
    # 目的是为了直接输出一个预测的数值,而不是一个0~1之间的概率
    model.compile(optimizer = 'rmsprop', loss = 'mse', metrics = ['mae']) # mse:均方误差(mean squared error)...
    # mae:平均绝对误差(mean absloute error):如MAE = 0.5 表示你的房价与实际的价格相差500美元
     
    return model

3-27 K折验证


由于训练的样本过小,如果单单将数据分为验证集和测试集,则会使得最终得分有较大的分差,我们使用K验证方法对样本进行验证

# K折验证
import numpy as np

k = 4
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] # i从0开始
    
    # 将数据按行分段,进行K划分,详见书P69页图
    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模型
    
    # 训练模型 (静默模式 verbose = 0) 
    model.fit(partial_train_data, partial_train_targets,
              epochs = num_epochs, batch_size = 1, verbose = 0)
    
    val_mse, val_mae = model.evaluate(val_data, val_targets, verbose = 0)
    # 记录mae数据
    all_scores.append(val_mae)
    
# 显示训练结果
print(all_scores)
print("各折最终训练分数:%f" % np.mean(all_scores))
processing fold # 0
processing fold # 1
processing fold # 2
processing fold # 3
[2.043470859527588, 2.728513479232788, 2.582028865814209, 2.374497175216675]
各折最终训练分数:2.432128

3-28 训练500轮,保存每折的验证结果


我们将训练的时间再拉长,并且将每一轮的结果都记录在一个向量中

# K折验证
import numpy as np

k = 4
num_val_samples = len(train_data) // k
num_epochs = 100
all_scores = []

# 训练500轮
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] # i从0开始
    
    # 准备训练数据
    # 将数据按行分段,进行K划分,详见书P69页图
    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模型
    
    # 训练模型 (静默模式 verbose = 0) 
    # 记录训练历史
    history = model.fit(partial_train_data, partial_train_targets,
                        validation_data = (val_data, val_targets),
              epochs = num_epochs, batch_size = 1, verbose = 0)
    
    # mae
    # mae_history = history.history['val_mean_absolute_error']
    mae_history = history.history['val_mae'] # 作者本版本的键值已修改,仅供参考
    
    all_mae_histories.append(mae_history)
processing fold # 0
processing fold # 1
processing fold # 2
processing fold # 3

3-29 计算所有轮次茨种的K折验证分数平均值


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

3-30 绘制验证分数


# 绘图
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()

《Python 深度学习》刷书笔记 Chapter 3 预测房价:回归问题_第1张图片

3-31 重新绘制验证分数


由于前10个数据点的缘故,使得纵轴的数据范围较大,所以难以看清楚该图的规律,为此,我们重新绘制一张数据图

def smooth_cruve(points, factor = 0.9):
    smoothed_points = []
    for point in points:
        if smoothed_points:
            previous = smoothed_points[-1]
            smoothed_points.append(previous * factor + point * (1 - factor))
        else:
            smoothed_points.append(point)
    return smoothed_points

smooth_mae_history = smooth_cruve(average_mae_history[10:])

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

《Python 深度学习》刷书笔记 Chapter 3 预测房价:回归问题_第2张图片

3-32 绘制最终模型


model_f = build_model()
model_f.fit(train_data, train_targets, epochs = 80, batch_size = 16, verbose = 0)
test_mse_score, test_mae_score = model.evaluate(test_data, test_targets)

# 打印结果
print(test_mae_score)
102/102 [==============================] - 0s 29us/step
2.8328466415405273

写在最后

注:本文代码来自《Python 深度学习》,做成电子笔记的方式上传,仅供学习参考,作者均已运行成功,如有遗漏请练习本文作者

各位看官,都看到这里了,麻烦动动手指头给博主来个点赞8,您的支持作者最大的创作动力哟!
<(^-^)>
才疏学浅,若有纰漏,恳请斧正
本文章仅用于各位同志作为学习交流之用,不作任何商业用途,若涉及版权问题请速与作者联系,望悉知

你可能感兴趣的:(Python之路,#,《Python,深度学习》,刷书笔记,python,深度学习,机器学习,回归问题,预测问题)