波士顿房价预测

270 阅读3分钟

一、准备数据

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

    return f

三、训练模型**
**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()

image.png