基本的回归
在回归问题中,我们的目标是预测一个连续值的输出,如价格或概率。与此形成对比的是分类问题,在分类问题中,我们的目标是预测一个离散的标签(例如,一张图片中包含一个苹果或一个橘子)。
这本笔记本建立了一个模型来预测20世纪70年代中期波士顿郊区房屋的中位数价格。为了做到这一点,我们将为模型提供一些关于郊区的数据点,比如犯罪率和当地的房产税率。
波士顿房价数据集
的波士顿房价数据集可直接从喀拉斯邦访问。
boston_housing < -dataset_boston_housing()c(train_data train_labels)% < - %boston_housing$火车c(test_data test_labels)% < - %boston_housing$测验
例子和特性
这个数据集比我们目前使用过的其他数据集要小得多:它总共有506个示例,分别为404个训练示例和102个测试示例:
##[1]“训练条目:5252,标签:404”
数据集包含13个不同的特性:
- 人均犯罪率。
- 住宅用地的比例超过25000平方英尺。
- 非零售企业占城镇面积比例。
- 查尔斯河虚拟变量(= 1如果土地边界河流;0否则)。
- 一氧化氮浓度(千万分之一)。
- 每套住宅的平均房间数。
- 1940年以前建造的自住单位的比例。
- 到五个波士顿就业中心的加权距离。
- 径向公路可达性指数。
- 每1万美元的全值财产税税率。
- 按城镇划分的学生教师比例。
- 1000 * (Bk - 0.63) ** 2,其中Bk是城镇黑人的比例。
- 人口地位较低的百分比。
每个输入数据特性都使用不同的规模存储。有些特征用0到1之间的比例表示,有些特征用1到12之间的比例表示,有些特征用0到100之间的比例表示,以此类推。
## [8] 3.97690 4.00000 307.00000 21.00000 396.90000 18.72000
让我们添加列名,以便更好地进行数据检查。
图书馆(dplyr)column_names < -c(“罪犯”,“锌”,“印度”,‘底盘’,“诺克斯”,“RM”,“年龄”,“说”,RAD的,“税收”,“PTRATIO”,“B”,“LSTAT”)train_df < -train_data% > %as_tibble(.name_repair =“最低”)% > %setNames(column_names)% > %变异(标签=train_labels)test_df < -test_data% > %as_tibble(.name_repair =“最低”)% > %setNames(column_names)% > %变异(标签=test_labels)
标签
标签是几千美元的房价。(你可能注意到了20世纪70年代中期的价格。)
## [1] 15.2 42.3 50.0 21.1 17.7 18.5 11.3 15.6 15.6 14.4
正常功能
建议将使用不同规模和范围的特性标准化。尽管没有特征归一化,模型可能会收敛,但这会增加训练的难度,并且会使得到的模型更加依赖于输入中使用的单位的选择。
我们要用feature_spec
接口实现。tfdatasets
包装标准化。的feature_columns
接口允许对表格数据进行其他常见的预处理操作。
规范< -feature_spec(train_df标签~)。% > %step_numeric_column(all_numeric(),normalizer_fn =scaler_standard())% > %适合()规范
# #──功能规范───────────────────────────────────────────────────────────────────────────# # feature_spec 13步骤。# #安装:真# #──步骤──────────────────────────────────────────────────────────────────────────────────# # feature_spec有密集的特性。# # StepNumericColumn:罪犯、锌、印度河、底盘,氮氧化物,RM,年龄,说,RAD,税,PTRATIO, B, LSTAT # #──密集特性─────────────────────────────────────────────────────────────────────────
的规范
创建tfdatasets
可以配合使用吗layer_dense_features
直接在TensorFlow图中执行预处理。
我们可以看看由这个创建的密集特征层的输出规范
:
# #特遣部队。张量(##[0.81205493 0.44752213 -0.2565147…[-1.9079947 - 0.43137115 -0.2565147…]1.8920003 -0.34800112 ## 2.9880793 ##[1.1091131 0.2203439 -0.2565147…]-0.48301655] ##…-1.6359899 0.07934052 -0.2565147…-0.3326088 -0.61246467 ## 0.9895695 ##[1.0554279 -0.98642045 -0.2565147…-0.7862657 -0.01742171 ##[-1.7970455 - 0.23288251 -0.2565147…]0.47467488 -0.84687555 ## 2.0414166]], shape=(404, 13), dtype=float32)
注意,这返回了一个带有缩放值的矩阵(因为它是一个二维张量)。
创建模型
让我们构建我们的模型。这里我们将使用Keras功能API -这是使用feature_spec
API。注意,我们只需要传递dense_features
从规范
我们刚刚创建的。
输入< -layer_input_from_dataset(train_df% > %选择(-标签)输出< -输入% > %layer_dense_features(dense_features(规范)% > %layer_dense(单位=64,激活=“relu”)% > %layer_dense(单位=64,激活=“relu”)% > %layer_dense(单位=1)模型< -keras_model(输入、输出)总结(模型)
# #模型:”模型 " ## ___________________________________________________________________________ ## 层(类型)形状参数#连接到输出 ## =========================================================================== ## 年龄(InputLayer) ((,)) 0 ## ___________________________________________________________________________ ## B (InputLayer) ((,)) 0 ## ___________________________________________________________________________ ## 底盘(InputLayer) ((,)) 0 # #___________________________________________________________________________ ## 罪犯(InputLayer) ((,)) 0 ## ___________________________________________________________________________ ## DIS (InputLayer) ((,)) 0 ## ___________________________________________________________________________ ## 印度河(InputLayer) ((,)) 0 ## ___________________________________________________________________________ ## LSTAT (InputLayer) ((,)) 0 # #___________________________________________________________________________ ## 氮氧化物(InputLayer) ((,)) 0 ## ___________________________________________________________________________ ## PTRATIO (InputLayer) ((,)) 0 ## ___________________________________________________________________________ ## RAD (InputLayer) ((,)) 0 ## ___________________________________________________________________________ ## RM (InputLayer) ((,)) 0 # #___________________________________________________________________________ ## 税(InputLayer) ((,)) 0 ## ___________________________________________________________________________ ## 锌(InputLayer) ((,)) 0 ## ___________________________________________________________________________ ## dense_features_1(密度(没有,13) 0岁[0][0]# # B[0][0] # #底盘[0][0]# #罪犯[0][0]# #说[0][0]# #印度河[0][0]# # LSTAT[0][0] # #氮氧化物[0][0]# # PTRATIO [0] [0] # # RAD [0] [0] # # RM[0][0] # #税[0][0]# #锌[0][0 ] ## ___________________________________________________________________________ ## 密度(密度)(896,64)dense_features_1 [0] [0 ] ## ___________________________________________________________________________ ## dense_1(致密)(没有,64) 4160 [0] [0 ] ## ___________________________________________________________________________ ## dense_2(致密)(没有,1)65 dense_1 [0] [0 ] ## =========================================================================== ## 总参数:5121 # #可训练的参数:5121 # # Non-trainable参数:0 ## ___________________________________________________________________________
然后我们用以下语句编译模型:
我们将把模型构建代码封装到一个函数中,以便能够在不同的实验中重用它。记住,Keras适合
就地修改模型。
build_model < -函数() {输入< -layer_input_from_dataset(train_df% > %选择(-标签)输出< -输入% > %layer_dense_features(dense_features(规范)% > %layer_dense(单位=64,激活=“relu”)% > %layer_dense(单位=64,激活=“relu”)% > %layer_dense(单位=1)模型< -keras_model(输入、输出)模型% > %编译(损失=“mse”,优化器=optimizer_rmsprop(),指标=列表(“mean_absolute_error”))模型}
火车模型
对模型进行500个epoch的训练,在一个时间内记录训练和验证的准确性keras_training_history
对象。我们还展示了如何使用自定义回调,将默认的训练输出替换为每个epoch的单个点。
通过打印单个点来显示训练进度。print_dot_callback < -callback_lambda(on_epoch_end =函数(时代、日志){如果(时代% %80= =0)猫("\ n")猫(“。”)})模型< -build_model()< -历史模型% > %适合(x =train_df% > %选择(-标签),y =train_df$标签,时代=500,validation_split =0.2,verbose =0,回调函数=列表(print_dot_callback))
## ## ................................................................................## ................................................................................## ................................................................................## ................................................................................## ................................................................................## ................................................................................## ....................
现在,我们使用存储在历史
变量。我们希望使用这些数据来确定在模型停止前进之前需要训练多长时间。
图书馆(ggplot2)
## ##附加包:'ggplot2'
##下面的对象被蒙版_by_ '。GlobalEnv': ## ##层
情节(历史)
这张图显示了大约200个时代之后模型的改进甚微。让我们更新适合
方法来在验证分数没有提高时自动停止训练。我们将使用一个回调这是对每个时代的训练条件的考验。如果时间过了一定的时间而没有显示出改善,它就会自动停止训练。
耐心参数是要检查改进的epoch的数量。early_stop < -callback_early_stopping(监控=“val_loss”,耐心=20.)模型< -build_model()< -历史模型% > %适合(x =train_df% > %选择(-标签),y =train_df$标签,时代=500,validation_split =0.2,verbose =0,回调函数=列表(early_stop))情节(历史)
图表显示,平均误差约为2500美元。这是好吗?2500美元可不是个小数目,因为有些厂牌只有15000美元。
让我们看看模型在测试集上的表现:
c(损失、美)% < - %(模型% > %评估(test_df% > %选择(-标签),test_df$标签,verbose =0))paste0(“测试集的平均绝对误差:$”,sprintf(“% .2f”,梅。*1000))
“测试集的平均绝对误差:$3002.32”
预测
最后,利用测试集中的数据对部分房价进行预测:
test_predictions < -模型% > %预测(test_df% > %选择(-标签)test_predictions (,1]
## [1] 7.759608 18.546511 21.525824 30.329552 26.206022 20.379061 28.972841 ## [8] 22.936476 19.548115 23.058081 18.773306 17.231783 16.081644 44.336926 ## [15] 19.217535 20.302008 28.332586 21.567612 20.574213 37.461048 11.579722 ## [22] 14.513885 21.496672 16.669203 22.553066 26.068880 30.536131 30.404364 ## [29] 10.445388 22.028477 19.943378 14.874774 33.198818 26.659334 17.360529 ## [36] 8.178129 15.533298 19.064489 19.243929 28.054504 31.655251 29.567472 ## [43] 14.953157 43.25531031.586626 25.668932 28.000528 16.941755 24.727943 ## [50] 23.172396 36.855518 19.777802 12.556808 15.813701 36.187881 29.673326 ## [57] 13.030141 50.681965 33.722412 24.914156 25.301760 17.899117 14.868908 ## [64] 18.992828 24.683514 23.111195 13.744761 23.787327 14.203387 7.391667 ## [71] 37.876629 30.980328 26.656527 14.644408 27.063200 18.266968 21.141125 ## [78] 24.851347 36.980850 10.906940 20.344542 40.68722 15.938128 14.283166 ## [85] 18.121195 18.713694 21.409807 21.765066 22.94352132.322598 19.994921 ## [92] 21.079947 26.719408 43.338303 36.935383 18.671057 37.789886 55.973999 ## [99] 27.252848 46.181122 32.272293 21.036985
结论
这本笔记本介绍了一些处理回归问题的技术。
- 均方误差(MSE)是一个常用的损失函数用于回归问题(不同于分类问题)。
- 同样,用于回归的评价指标与分类不同。一个常见的回归度量是平均绝对误差(MAE)。
- 当输入数据特征具有不同范围的值时,每个特征需要独立缩放。
- 如果训练数据不多,建议使用隐藏层较少的小网络,避免过拟合。
- 早期停止是防止过拟合的有用技术。