房价的预测和前两期的问题是不同的,最大的区别就是这个问题不是离散的分类,他是一个连续值,那么在搭建网络时候的技巧就有所区别。
from keras.datasets import boston_housing
(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()
导入数据
train_data.shape
test_data.shape
看一下数据的尺寸,发现训练集的尺寸是404,13;测试集的尺寸是102,13;说明这些数据不多,这十三个数据特征是各种数值,包括犯罪率,住宅平均房间数,道路的通畅程度等。很明显,这些数据都看起来没什么关系,相互之间无法联系,还有一个最要命的就是我们无法确定那个数据更加的重要。另外,这些数据的范围也不同,想要使用,必须要做一些处理。
train_targets
看一下targets,就可以看到当时房子的房价了,这就是训练集中对应的结果集,类似于上两个例子中的标签集。
mean = train_data.mean(axis=0)
train_data -= mean
std = train_data.std(axis=0)
train_data /= std
test_data -= mean
test_data /= std
这里就是应对数据范围不同的办法,方法叫标准化,含义就是加工每个特征,使他们的数据满足平均值为0,标准差为1.具体的方法就是每列取平均值,减去平均值,再除以减掉之后的标准差。这里要注意标准化所用的数据必须是在训练集上得到,实际操作中不能让任何数据从验证集上得到,不然会导致模型过拟合的问题。
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))
model.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])
return model
这里就是搭建学习模型的步骤,因为这个模型要重复使用,所以我们把它写成函数的形式。前两层输出维数都是64,并且用激活函数relu去激活,但最后一层是纯的线性层,只输出一个值,而且不激活,可见输出的值是任意范围内的。
下面编译用的是优化器rmsprop,损失函数是mse,即为均方误差,就是预测值与目标值之差的平方,反应了差距的大小,回归问题用的比较多。最后一个指标是mae,平均绝对误差,它求的是差值的绝对值,没有平方。
回到数据集本身,就会发现问题在于训练集和验证集都太小了,特别是验证集小,这会让每次验证的结果差距都比较大,就没办法得出结论,于是就要引入一种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]
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()
# Train the model (in silent mode, 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)
all_scores.append(val_mae)
这段代码看似很长,其实只反映了一个思想,就是k折验证,第一部分把训练集分成四份,每一份都是待定的验证集;第二部分把第一步选定的数据除外的数据拿出来然后使用concatenate拼接起来当了训练集;第三部分去训练然后验证。得到的分数就是mae。其中的参数verbose为0就是不输出进度条,默认的是1,就是显示进度条,日志,这个不影响过程,只影响能不能看到进度。
后面的事情下一期讲。