预测房价:回归问题——R语言( w2 X5 P& M" u4 Z4 ]6 V
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。/ N/ Q3 `( N% r- d* @2 A+ y
! R0 T: X1 f5 @! ?4 Z+ L. J4 E问题描述& O& D5 G3 l4 G! A" \/ ]
我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。
! b% R* a0 a' b! ? t+ ^本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。
; \) [" L% x/ l: X数据特征:0 @! {2 P4 B/ ]2 g: K
人均犯罪率。
7 v4 L, k7 i6 c占地面积超过25,000平方英尺的住宅用地比例。
( d- r: |/ v4 X1 N+ S" j4 E每个城镇非零售业务的比例。
6 M! S. @6 n: J3 C2 @+ GCharles River虚拟变量(如果管道限制河流则= 1;否则为0)。
! N1 ]* R9 y5 I" \; n一氧化氮浓度(每千万份)。* s& `/ ~/ [$ k% d5 N
每栋住宅的平均房间数。
0 I5 m4 \/ Q7 a7 d C; l& u1940年以前建造的自住单位比例。' J! G! h6 k8 W( G5 `
到波士顿五个就业中心的加权距离。/ Y$ w% o5 `/ P1 k' d
径向高速公路的可达性指数。2 ?: c3 B3 J$ A" `7 E3 q
每10,000美元的全额物业税率。4 I$ p" A; v6 P4 w
城镇的学生与教师比例。
- ` i# K+ }( E9 }; x3 p1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。- z L) A8 L) @" d8 E: Y8 Q
人口比例较低的百分比。
1 X0 h% _# n8 H" G6 d( D% P* k1. 加载波士顿房价数据7 J4 _ ]# P" D4 \+ J7 q: A0 I+ w( f
library(keras)
3 z5 P2 Q8 _ x6 k4 o8 k+ B+ V% V" s
boston_housing <- dataset_boston_housing()
! ?$ [! q, \0 e9 K6 ?+ W( |7 ~6 n3 }' ^$ P" s I. q8 q
c(train_data, train_labels) %<-% boston_housing$train
# P8 x. |: h/ v- M5 |5 Jc(test_data, test_labels) %<-% boston_housing$test& B# E2 q6 {0 @$ y
, K* Q9 {$ _5 x0 ~8 ?每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 6 b7 E( p5 Z# i l+ r$ c5 x
# Test data is *not* used when calculating the mean and std.
4 z- I+ K" f5 N" ]- J O1 ~. Q- u
# Normalize training data
! Q. j% L8 c! |' z ttrain_data <- scale(train_data) ! X) t( H y9 T4 X$ G
7 k2 S& E0 c3 w. Q# Use means and standard deviations from training set to normalize test set9 ]# r j1 ]2 |# b
col_means_train <- attr(train_data, "scaled:center")
. X1 O% L5 o5 t' l+ f9 Ucol_stddevs_train <- attr(train_data, "scaled:scale")6 I6 ?8 u2 ?: F z
test_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
. e4 l. N& K' K* ^ H) c# W0 f: e
2 y1 F7 e- T* l1 _8 C/ C3. 构建网络创建模型 ' L. O2 Y! i/ c# r" Y6 ]
build_model <- function() {% `2 T; S' Q3 `; p4 M( t$ ~ c }
. e5 a6 d* M0 W model <- keras_model_sequential() %>%
2 n! s8 i$ E% l$ Z0 @5 n layer_dense(units = 64, activation = "relu",
. k5 k: u' |2 Z# K n g6 v input_shape = dim(train_data)[2]) %>%
9 a3 l G8 }5 K3 e layer_dense(units = 64, activation = "relu") %>%7 u7 C3 B8 x' T1 `8 P0 [& _
layer_dense(units = 1)
T5 ]" O: w2 h5 \: T. p
4 R, W+ ` d5 \, f4 O7 }2 | model %>% compile(
- U/ U Q( ]$ G# }5 s7 ?8 ^ loss = "mse",+ _2 T' s* S* G6 ^+ r+ w) H
optimizer = optimizer_rmsprop(),1 J+ y1 M$ t' n' I' e. o
metrics = list("mean_absolute_error")
) y+ ~! [* Y3 L; c) @ )4 z+ P/ Q- ?8 f$ ^
1 ` E" w* f0 D# H model: `2 ]! z X4 y2 R0 h& j3 T
}3 |2 s9 p1 I7 N
1 `) k- ~- }# X+ u* Xmodel <- build_model()9 P. R8 L$ ?1 v; y8 s& @! j' g
model %>% summary()$ H8 {7 t" Y* \" V& {
7 q, Z9 f6 J7 K1 j: [5 b8 _& U
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型5 X1 X* t/ {6 r+ f4 ]' N: [
# Display training progress by printing a single dot for each completed epoch.8 X- R" N9 x8 n! B, Z2 N9 n
print_dot_callback <- callback_lambda(3 H3 ]- _) I/ o2 E) K6 Y
on_epoch_end = function(epoch, logs) {
& [4 G3 |1 N% z; ~, | if (epoch %% 80 == 0) cat("\n")
7 G; }- U* C, W9 E cat(".")
4 ?3 H% C1 v) Q4 R! y6 f }. ^- w \; \1 g( E& T2 j- d
) & m$ q8 N! C) G9 Z
( R* \/ Z5 B5 k x9 l3 Repochs <- 500+ B: V1 b$ J3 z8 M4 t- H
z- \4 Q7 p- M) ]$ J* a- Y# Fit the model and store training stats
* W1 j/ B1 M1 E1 ]. f5 c5 `history <- model %>% fit(
8 P- X* M3 t3 ^3 [4 G ?. V train_data,
: Z1 b+ |) a+ Z( { train_labels,
5 |8 l8 P4 Z9 z! e epochs = epochs,
. s3 `( z+ _0 a validation_split = 0.2,
/ t! Y/ w/ ~9 I- ` verbose = 0,
, ?* r& A' g R% R callbacks = list(print_dot_callback)# M* T- g0 d) t; L9 {! t5 u
); o& T& U# _& E @2 Q7 }/ O# M
, b2 V8 @/ D! B5 g: @" u
library(ggplot2)
8 l: [( V) N5 q8 K& Y/ |! [( L* u5 i8 ]" {3 h- [. m6 e. H4 E
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +
( [! E1 `, ?$ ~. H5 B; ` coord_cartesian(ylim = c(0, 5))8 \4 o" ]- r' g, a& Q) _( J
* ~4 v/ O; l0 E' ?6 ?& f5 u! E
# z* P- ~) a1 I& ~+ T x, f
' o% w" T3 B% W6 W6 U
小结( z h$ X4 B; j% W3 z7 ^( d
1)回归常用的损失函数是均方误差(MSE)。" Q+ a3 W- o E) i& t
2)常见的回归指标是平均绝对误差(MAE)。) @0 P( ~0 E0 y( X7 U) Z
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。# T) M ?! x2 w _1 W1 g" r
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
! o0 s5 j8 T0 a' Q0 Z9 e
$ J+ h% x) P7 o+ F- Q/ C( h% Z( |! a% O! \1 y$ A- @) j2 O
- n) N, Z/ Z$ D. C# E3 _ |