一、准备数据
1、本次将要预测 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()
l 我们有 404 个训练样本和 102 个测试样本,每个样本都有 13 个数值特征,比如
人均犯罪率、每个住宅的平均房间数、高速公路可达性等。
l 目标是房屋价格的中位数,单位是千美元。
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
二、构建模型
将训练数据和测试数据标准化
sc = StandardScaler()
x_train = sc.fit_transform(x_train)
x_test = sc.fit_transform(x_test)
print(x_train[0])
print(x_test[0])
设置模型参数
n_hidden_1 = 64
n_hidden_2 = 64
n_input = 13
n_classes = 1
training_epochs = 200
batch_size = 10
配置模型
input_dim=n_input,第一层必须写明输入数据维度,这里是13;
n_hidden_1指输出维度,这里是64(可以自己设置任意值),代表第一层的神经元个数;
n_hidden_2指第二层的输出,也代表第二层的神经元个数;¶
第三层为一个维度的输出n_classes
from keras import models
model = models.Sequential()
model.add(Dense(n_hidden_1,activation='relu',input_dim=n_input))
model.add(Dense(n_hidden_2,activation='relu'))
model.add(Dense(n_classes))
导入keras后端,定义评价指标
import keras.backend as K
def r2(y_true,y_pred):
a = K.square(y_pred - y_true)
b = K.sum(a)
c = K.mean(y_true)
d = K.square(y_true - c)
e = K.sum(d)
f = 1 - b/e
三、训练模型**
**K折交叉验证
当调整模型参数时,为了评估模型,我们通常将数据集分成训练集和验证集。但是当数据量过小时,验证集数目也变得很小,导致验证集上的评估结果相互之间差异性很大—与训练集和测试集的划分结果相关。评估结果可信度不高。
最好的评估方式是采用K折交叉验证–将数据集分成K份(K=4或5),实例化K个模型,每个模型在K-1份数据上进行训练,在1份数据上进行评估,最后用K次评估分数的平均值做最后的评估结果。
k = 4
num_val_samples = len(x_train) // k
num_epochs = 100
all_scores = []
for i in range(k):
print('processing fold #',i)
val_data = x_train[i*num_val_samples : (i+1)*num_val_samples] # 划分出验证集部分
val_targets = y_train[i*num_val_samples : (i+1)*num_val_samples]
partial_train_data = np.concatenate([x_train[:inum_val_samples],x_train[(i+1) num_val_samples:] ],axis=0) # 将训练集拼接到一起
partial_train_targets = np.concatenate([y_train[:inum_val_samples],y_train[(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)
processing fold # 0
processing fold # 1
processing fold # 2
processing fold # 3
model = build_model()
for step in range(30001):
cost = model.train_on_batch(x_train,y_train)
画图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(16,8), dpi=160)
plt.plot(range(len(y_test)), y_test, ls='-.',lw=2,c='r',label='真实值')
plt.plot(range(len(pred_y_test)), pred_y_test, ls='-',lw=2,c='b',label='预测值')
plt.grid(alpha=0.4, linestyle=':')
plt.legend()
plt.xlabel('number')
plt.ylabel('房价')
plt.show()