关键词

[Deep-Learning-with-Python]基于Keras的房价预测

回归问题预测结果为连续值,而不是离散的类别。

波士顿房价数据集

通过20世纪70年代波士顿郊区房价数据集,预测平均房价;数据集的特征包括犯罪率、税率等信息。数据集只有506条记录,划分成404的训练集和102的测试集。每个记录的特征取值范围各不相同。比如,有01,112以及0~100的等等。

加载数据集

from keras.datasets import boston_housing

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

训练集形状:

>>> train_data.shape
(404, 13)

测试集形状:

>>> test_data.shape
(102, 13)

训练集404条,测试集102条;每条记录13个数值特征。
房价单位为1000美元。

>>> train_targets
[ 15.2, 42.3, 50. ...19.4,19.4,29.1]

房价范围在$10,000到$50,000。

准备数据

因为数据各个特征取值范围各不相同,不能直接送到神经网络模型中进行处理。尽管网络模型能适应数据的多样性,但是相应的学习过程变得非常困难。一种常见的数据处理方法是特征归一化normalization---减均值除以标准差;数据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

模型构建

由于数据集数据量过小,模型也不能太复杂,否则容易发生过拟合。

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

模型的最后一层只有一个神经元,没有激活函数--相当于一个线性层。这种处理方法常用在单标量回归问题中。使用激活函数将会限制输出结果的范围,比如使用sigmoid激活函数,输出结果在0~1之间。这里,因为最后一层只是一个线性层,模型的输出结果可能是任意值。
模型的损失函数为mse均方误差。监测的指标为mean absolute error(MAE)平均绝对误差---两个结果之间差的绝对值。

K折交叉验证

当调整模型参数时,为了评估模型,我们通常将数据集分成训练集和验证集。但是当数据量过小时,验证集数目也变得很小,导致验证集上的评估结果相互之间差异性很大---与训练集和测试集的划分结果相关。评估结果可信度不高。
最好的评估方式是采用K折交叉验证--将数据集分成K份(K=4或5),实例化K个模型,每个模型在K-1份数据上进行训练,在1份数据上进行评估,最后用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()
	model.fit(partial_train_data,partial_train_targets,epochs=num_epochs,batch_size=16,verbose=0)#模型训练silent模型
	val_mse, val_mae = model.evaluate(val_data, val_targets, verbose=0) # 验证集上评估
	all_scores.append(val_mae)
	

模型训练

model = build_model()
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)# score 2.5532484335057877

小结

  • 回归问题:损失函数通常为MSE均方误差;
  • 模型评估监测指标通常为MAE(mean absolute error);
  • 当数据取值范围不一致时,需要对特征进行预处理;
  • 数据量小时,可以采用K折验证来衡量模型;
  • 数据量小时,模型复杂度也应该相应的简单,可以避免模型过拟合。

本文链接:http://task.lmcjl.com/news/12237.html

展开阅读全文