说明

由于是历史文档,其中有些内容没有列出参考,如果侵权,请联系作者删除。

 本次数据选自sklearn这一python机器学习库的波士顿房价数据集(http://lib.stat.cmu.edu/datasets/boston)。实现房价回归任务,数据包含各城镇人均犯罪率,划为25,000平方英尺以上地块的住宅用地比例,各城镇非零售商业面积比例,查尔斯河虚拟变量(如果小区内有河流=1;否=0),一氧化氮浓度(千万分率)等等变量。因为涉及种族问题(有一个和黑人人口占比相关的变量B),波士顿房价这个数据集在sklearn库的1.2版本中被移除。备选数据集包括加州住房数据集等。在使用load_boston()这个函数加载数据时,会产生相关的警告提示。具体的变量描述如表 1所示,其中没有缺少属性值的情况。

波士顿房价数据集

变量 描述 CRIM per capita crime rate by town ZN proportion of residential land zoned for lots over 25,000 sq.ft. INDUS proportion of non-retail business acres per town CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise) NOX nitric oxides concentration (parts per 10 million) RM average number of rooms per dwelling AGE proportion of owner-occupied units built prior to 1940 DIS weighted distances to five Boston employment centres RAD index of accessibility to radial highways TAX full-value property-tax rate per $10,000 PTRATIO pupil-teacher ratio by town B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town LSTAT % lower status of the population MEDV Median value of owner-occupied homes in $1000's

数据预处理

从本地或URL读取数据,并完成预处理操作,数据集概述中已说明没有缺少属性值的情况,不再做缺失值处理等工作。

数据处理包含五个部分:数据导入、数据形状变换、数据集划分、数据归一化处理和封装load_data和build_data函数。数据预处理后,才能被模型调用。

由于读入的原始数据是1维的,所有数据都连在一起。因此需要我们将数据的形状进行变换,形成一个2维的矩阵,每行为一个数据样本(14个值),每个数据样本包含13个X(影响房价的特征)和一个Y(该类型房屋的均价)。

采用留出法,将数据集以8∶2的比例划分成训练集和测试集。在训练集对模型参数进行优化,并通过测试集对所提模型进行性能验证。

为消除各数据之间数量级及量纲的不同,需进一步归一化处理数据,归一化操作能有效地加快模型收敛速度、减轻潜在梯度问题。Z-score归一化公式如下:

式中, 为原始数据, 为样本均值, 为样本标准差, 为归一化后的数据。

数据分析

波士顿房价数据集的可视化情况如图所示。

(a) 散点图 (b) 相关系数矩阵

波士顿房价数据集包含506个实例,13个用于学习的影响房价的变量,第14个变量MEDV房价中位数为回归的目标。通过数据的预处理与可视化展示,数据中13个变量会对房价产生影响,从相关系数矩阵中也可以看到还是有部分变量之间存在较高的相关系数。回到题目,接下来根据这13个变量的情况,可以训练一个回归模型,对房价进行预测。

模型构建

本次的回归任务为利用Keras库构建的模型为一个基准神经网络。

首先依据《Python深度学习》对深度学习模型最后一层激活和损失函数进行参考说明如表 2所示。依据经验与此说明,最后一层不选用激活函数,损失函数采用均方误差(MSE)。回归问题最常使用的是均方误差损失。当目标变量的分布为高斯分布时,它是最大似然推理下的首选损失函数。所以只有当你有一个更好的理由时,才应该改变为其他损失函数。

在Keras中编译模型时将“mse”或“mean_squared_error”指定为损失函数,则使用均方误差损失函数。

构建了如图 2所示的一个基准神经网络(绘图工具http://alexlenail.me/NN-SVG/index.html),输入层大小为13,即进行学习的13个变量,构建了两个大小为16的隐层,输出大小为1,即为预测的房价。

神经网络

激活函数

在讨论优化算法时,有一点要说明:目前已经基本上不用sigmoid函数了,tanh函数在所有场合都优于sigmoid函数。但有一个例外:在二分类的问题中,对于输出层,因为y的值是0或1,所以想让y的数值介于0和1之间,而不是在-1和+1之间。所以需要使用sigmoid激活函数,然后其它的所有单元都选择Relu函数。

这是很多激活函数的默认选择,如果在隐藏层上不确定使用哪个激活函数,那么通常会使用Relu激活函数。有时,也会使用tanh激活函数,但Relu的一个优点是:当y是负值的时候,导数等于0。也有另一个版本的Relu被称为LeakyRelu。当y是负值时,这个函数的值不是等于0,而是轻微的倾斜。这个函数通常比Relu激活函数效果要好,尽管在实际中LeakyReLu使用的并不多。

各激活函数如图 3所示,总的来讲:

(1)sigmoid激活函数:除了输出层是一个二分类问题基本不会用它。

(2)tanh激活函数:tanh是非常优秀的,几乎适合所有场合。

(3)ReLu激活函数:最常用的默认函数,如果不确定用哪个激活函数,就使用ReLu或者LeakyReLu。

综上,在采用不同的激活函数搭配,进行了一系列的对比后,本文在隐层采用的激活函数为ReLu,最后输出层没有引入激活函数。

激活函数

隐层层数

神经网络主要由输入层,隐藏层以及输出层构成,合理的选择神经网络的层数以及隐藏层神经元的个数,会在很大程度上影响模型的性能(不论是进行分类还是回归任务)。对于一些很简单的数据集,一层甚至两层隐藏元都已经够了,隐藏层的层数不一定设置的越好,过多的隐藏层可能会导致数据过拟合。对于自然语言处理以及CV领域,则建议增加网络层数。

输入层的节点数量以及输出层的节点数量是最容易获得的。输入层的神经元数量等于数据的特征数量(feature个数)。

若为回归,则输出层的神经元数量等于1;若为分类,则输出层的神经元数量为分类的类别个数(如区分猫狗,则为2;区分手写数字0-9,则为10)。

隐藏层的层数与神经网络的结果如表 3所示:

层数越深,理论上来说模型拟合函数的能力增强,效果会更好,但是实际上更深的层数可能会带来过拟合的问题,同时也会增加训练难度,使模型难以收敛。

经验来讲,在使用神经网络时,最好可以参照已有的性能良好的模型。如果自己手写的话,若数据集很简单,则最好从一两层开始尝试,尽量不要使用太多的层数。

综上,本文在模型经过一系列调整后,最终确定构建隐层的层数为2。

神经元个数

在隐藏层中使用太少的神经元将导致欠拟合(underfitting)。相反,使用过多的神经元同样会导致一些问题。首先,隐藏层中的神经元过多可能会导致过拟合(overfitting)。

当神经网络具有过多的节点时,训练集中包含的有限信息量不足以训练隐藏层中的所有神经元,因此就会导致过拟合。即使训练数据包含的信息量足够,隐藏层中过多的神经元会增加训练时间,从而难以达到预期的效果。显然,选择一个合适的隐藏层神经元数量是至关重要的。欠拟合、过拟合效果如图所示。

拟合效果

通常对于某些数据集,拥有较大的第一层并在其后跟随较小的层将导致更好的性能,因为第一层可以学习很多低阶的特征,这些较低层的特征可以馈入后续层中,提取出较高阶特征。

需要注意的是,与在每一层中添加更多的神经元相比,添加层层数将获得更大的性能提升。因此,不要在一个隐藏层中加入过多的神经元。

如果欠拟合然后慢慢添加更多的层和神经元,如果过拟合就减小层数和神经元。此外,在实际过程中还可以考虑引入Batch Normalization,Dropout,正则化等降低过拟合的方法。确定神经元的数量可以参考如下公式:

式中, 是输入层神经元个数,是输出层神经元个数,是训练集的样本数, 是任意值变量,通常取值范围为2-10。

综上,最终确定隐层大小为16(一般是2的n次方,但也有研究表示,此经验取值方法缺乏一定严谨性,也即不一定要选择其为2的n次方)。

损失函数

模型训练的目标是降低真实值和预测值的误差,预测模型采用损失函数对训练集中的模型参数进行调整优化,损失函数值越小时表明预测值和真实值分散度越低,且误差越小,预测结果较为可靠。本试验的损失函数确定为均方误差(mean-square error, MSE),公式如下:

式中,为预测值,为真实值,为样本数量。

模型评价

训练

将训练过程整合到了train()函数中,也方便对超参数进行调用,本文对模型进行了保存,就使用到了模型名称这个参数,其它的还有训练次数,学习率,批大小,是否打乱数据集等。

整体代码以Python语言编写,训练模型的计算机CPU为Intel Core i5。

模型超参数设置为:批大小(Batch Size)定为16、隐藏层大小(Hidden)定为32、训练使用了自适应矩估计(Adaptive moment estimation, Adam)优化器、学习率(learning rate, lr)为0.0002、训练次数(epoch)500、对训练集进行打乱。为了降低随机性,可对模型进行多次独立训练,并取多次试验结果得分均值作为最终评分。

batch的取值会影响模型训练效果。batch过大,会增大内存消耗和计算时间,且效果并不会明显提升;batch过小,每个batch的样本数据将没有统计意义。由于房价预测模型的训练数据集较小,batch为16。

训练完成后对模型进行保存,避免后续对模型进行验证时需要再次训练模型。

对训练集上的训练损失和验证损失进行了输出,从下图中可以看出,模型收敛速度相当快,训练和测试(验证)性能保持不变,没有出现过拟合(随着训练次数增加,训练损失继续下降,而测试损失有上升)或欠拟合的情况。根据模型的性能和收敛特性,均方误差(MSE)是回归问题的一个很好的选择。

损失曲线

验证

将验证过程整合到eval()函数中,由于在训练过程中已将模型进行保存,所以可以在不进行二次训练的情况下调用模型在测试集上验证模型效果。

在本实验中,模型的评价指标选取相关系数 , 表示数据相关程度,用来衡量预测结果代表实际数据的能力, 值域范围为(0,1]((0,0.3]为微弱相关,(0.3,0.5]为低度相关,(0.5,0.8]为显着相关,(0.8,1]为高度相关,1为完全相关), 值越大表示预测结果越好。

式中, 是样本大小, 为样本  的平均值, 和  分别为样本的实际值和预测值。

经过在测试集上进行验证,得到相关系数为0.9228,为高度相关,且对预测结果进行可视化如图 6所示,可以看到模型的预测效果较好。其中未进行反归一化处理。

预测结果

模型对比

为验证本文模型有效性,将本文神经网络模型与其它回归方法如正规方程模型(最小二乘法线性回归、岭回归、梯度下降)进行了对比如表所示(最优结果已标粗),

总得来说,本文模型较正规方程模型精度提升大约21.2%,表明文中方法具有较好的预测精度。

如有错误的地方,欢迎讨论指正。

精彩文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。