预测房价:回归问题——R语言3 s/ Y, P) D3 y- c5 E9 d
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
2 a0 O; a* U" ?! q. n, n1 [- `; c) K
问题描述9 v7 i' E( r* a+ F8 }, ?
我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。! d7 \0 s# \% g" o, s- R
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。
: v% C# H( a' H# r% [/ }" S数据特征:
7 d' A: f% K7 _5 z9 p$ I人均犯罪率。& |: n# }; ?9 k3 }8 U) G
占地面积超过25,000平方英尺的住宅用地比例。
, M# I A8 ^& k$ y每个城镇非零售业务的比例。3 C" s. u4 o# h& F0 I
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。5 ?/ S" `( V2 |6 h. c2 p- Y. o
一氧化氮浓度(每千万份)。% e# B. g' h0 f6 C" V
每栋住宅的平均房间数。# \& f' b6 x5 {2 b; e3 X
1940年以前建造的自住单位比例。: R# K- f, S2 V8 F
到波士顿五个就业中心的加权距离。3 C# }2 u6 @9 z& i3 f+ }; Q
径向高速公路的可达性指数。
S" k& h' ]: ~. F$ `每10,000美元的全额物业税率。
: Y* e+ @# d c0 i( r% i2 s1 W" C城镇的学生与教师比例。7 j" ]0 C' C r* \* g1 `# \
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
0 ~, y4 ~ t7 v" `+ B$ k7 Y. R6 A人口比例较低的百分比。
s+ [1 P2 ?8 g) y1. 加载波士顿房价数据
" [ _5 n3 U5 K- F: K4 blibrary(keras)4 h5 Q/ y, G- T+ h% p% I' e# a: H+ m/ I
7 E, Z' O/ R5 }# ^# S8 H! f# K iboston_housing <- dataset_boston_housing()
( [7 s/ F% X( k0 F: Y' F% a1 X
/ E# O$ g! p) {: `' h1 c8 v$ Vc(train_data, train_labels) %<-% boston_housing$train
' c x! Q5 ?5 J8 c: Cc(test_data, test_labels) %<-% boston_housing$test
! p1 x' q+ K. c5 {5 J4 W( j1 e( @3 |) J3 |
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
3 P. m: w @2 Z0 f Y# Test data is *not* used when calculating the mean and std.7 B1 K) \7 I& y- o) o) G: J
# s* Q5 B4 B, ]4 M, Q8 S* n
# Normalize training data
* q8 p1 \& u) G" C# h2 Utrain_data <- scale(train_data)
4 g& [3 x! R. P
" u4 `9 }: s+ }# Use means and standard deviations from training set to normalize test set5 q$ k# C+ x. B( R( _8 A0 e' {0 ?" ?: A
col_means_train <- attr(train_data, "scaled:center") 2 q7 J `" d! W& ^
col_stddevs_train <- attr(train_data, "scaled:scale")
7 h9 O+ ^+ I$ w7 p: f$ [6 vtest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
+ T1 @0 p* Z5 q u M( u5 K
: b$ v9 p- g7 f! w! K5 \ X! W3. 构建网络创建模型 , }/ z! {$ z3 J) f
build_model <- function() {
, Q) ?7 g! l7 j+ i# I: M% Z5 _6 E; o
: I2 a7 T$ Q* T7 N; r- N model <- keras_model_sequential() %>%
y& P) H( N& M* }: `6 j% q layer_dense(units = 64, activation = "relu",
: z2 n( R5 i" H7 w input_shape = dim(train_data)[2]) %>%" Z l# O& l7 J
layer_dense(units = 64, activation = "relu") %>%2 Z5 E6 }- {/ _( L3 c! b
layer_dense(units = 1)1 V% t& j6 G' j0 z7 L
3 ?- \) l3 l( }4 Q model %>% compile(
4 `5 V& l/ p$ j loss = "mse",
5 p) A/ H) g1 S4 V& n& m9 n" a optimizer = optimizer_rmsprop(),
5 o0 \$ p3 G( {) V metrics = list("mean_absolute_error")3 \3 J/ m. }& J$ w7 x0 b5 y
)
$ D; M' Y7 y) M4 v9 v3 d# F% d7 D0 P' [; |6 {
model5 {5 R) u# _8 ^: }
}
& V2 M; Q, p7 ~2 O" N
/ L7 `' t8 O7 A/ N- Z5 E) G2 [model <- build_model()7 q5 B9 Q3 G) v/ N. y
model %>% summary()
. a" v: p6 b ~6 C: k- r7 r: d, c
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
. Y5 g' ` f( M2 v# Display training progress by printing a single dot for each completed epoch.
, J6 D; l4 f! V, N; D3 `' p: aprint_dot_callback <- callback_lambda(
6 k ~; u9 k0 O5 B on_epoch_end = function(epoch, logs) {, s+ o8 f* Q! t S) W
if (epoch %% 80 == 0) cat("\n")0 D" g* S& K; e
cat("."), S2 y8 X% F: ~. ^5 d8 W
}
' @* w6 c; B% J) s3 p7 Q) / n0 W1 z4 V9 f: D( h
) ~$ d' e* ]% Oepochs <- 500
% V7 e+ I+ I# E/ D
* y& K5 O5 I! R! P$ m |# Fit the model and store training stats: d9 p7 N( A2 w3 S) N) s M
history <- model %>% fit(* |0 l7 e2 p3 a N' \# N
train_data,, B- U) B& B3 J3 \. G* b5 a8 u
train_labels,
, Y0 K" n/ {& H5 C2 z+ w3 ^ epochs = epochs,: \- @' ]9 d) I9 p
validation_split = 0.2,
' J' w; V( c2 s. l6 ~# I verbose = 0,+ @. ^- ~2 u6 d% J% R) s( z8 c
callbacks = list(print_dot_callback)
7 X/ t$ d! H2 B5 m7 z)
2 q* ^! i$ V- u9 O* w# s" O8 p4 C5 N$ d0 \
library(ggplot2)
* X" I; O+ A" Z8 f
, O' C( i, e4 vplot(history, metrics = "mean_absolute_error", smooth = FALSE) +
3 y* |. i( L& c coord_cartesian(ylim = c(0, 5))0 l" S8 k2 M; ?- Y- C4 b
& I- F! l- D* `& h% v* c
( a3 v$ k2 J, Y* ]! T& @
5 w2 L/ d( g& H- l
小结9 x! N6 J/ Y, Z% {
1)回归常用的损失函数是均方误差(MSE)。
: N; r3 m t# r; Z. n2)常见的回归指标是平均绝对误差(MAE)。2 x* T3 A8 L) k7 [1 n+ T
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。' B% S4 `: F/ q' b" e! r! O6 d
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
# x1 t& E8 R6 Y5 k0 B: y: d) |( E+ R3 x a$ R$ Y1 ]
' }- F! D3 U: \- v
& f& ^2 M1 S, h6 O8 d( N. t
|