预测房价:回归问题——R语言( Y7 i6 g4 d) S" a8 w
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
, p: a) _& Q& |3 f3 i( b' r
& a6 a3 q9 Q. `; w2 c2 T/ q5 G& c问题描述
3 T" q9 Y. d5 [* g$ p我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。
! Y, q: D$ \" y: g2 @本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。( { S. _$ r) n: D* A6 [
数据特征:" y3 o) f' ?8 |5 _
人均犯罪率。
- J( _# \* J1 ~8 v占地面积超过25,000平方英尺的住宅用地比例。
8 x1 x- K, P% r, _" `% e* W% O每个城镇非零售业务的比例。
* d! O E- m. }; I9 G& I0 s+ H) x. @Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。
R7 n" A5 S7 u; X一氧化氮浓度(每千万份)。
. r# k' u6 B: ?7 B" U+ J每栋住宅的平均房间数。; T, ] ]8 `; _' {; ]6 @; f6 L
1940年以前建造的自住单位比例。
$ W" V& p& o8 L' t) h0 _, D到波士顿五个就业中心的加权距离。" O3 M. X5 J2 {0 m. A* y6 D
径向高速公路的可达性指数。 |% A# ]5 z- ^
每10,000美元的全额物业税率。1 P" G( ^' y; Z6 |
城镇的学生与教师比例。4 }% w( Q: T* d2 P2 p
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
' A( l$ H* q( A& a5 A, s, @人口比例较低的百分比。$ k' x8 h9 q/ ]
1. 加载波士顿房价数据
" X6 g; [3 e* J& ~library(keras)7 h. Z: Y7 y5 B! \
2 C- Z0 g+ O& L7 F% ^6 i! bboston_housing <- dataset_boston_housing()& J, c. a0 @0 y+ y
# h& Z0 Y. H0 ~& Z7 z
c(train_data, train_labels) %<-% boston_housing$train
6 V: ]7 h& ^$ H; gc(test_data, test_labels) %<-% boston_housing$test: L _% a) d. D. m9 e1 j
9 j. p3 s3 {& @% B4 f; Z+ d( z! W8 B
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
2 m9 s* J7 y, Q5 y5 V' M: b% f0 R g# Test data is *not* used when calculating the mean and std.
( l3 O; M" j0 e* P, v1 H0 B/ @$ w: o: A* W1 a T) |3 h* ]. |5 p7 Y
# Normalize training data* l* p3 o- ?# e3 P' O
train_data <- scale(train_data)
i! w6 \% T2 ] O% ~
! s4 ], q* f2 O- }# Use means and standard deviations from training set to normalize test set$ Y: R) p0 h- Q$ W( t
col_means_train <- attr(train_data, "scaled:center")
" j' {, E h n' `' k. ^col_stddevs_train <- attr(train_data, "scaled:scale")6 _ ?& k; f0 p
test_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train), ^7 w2 Y. N7 l. X/ m* N+ N& o
; K- X! F3 }: E6 T' F+ C' W6 ]: h3. 构建网络创建模型
9 t1 C7 f P8 ^7 _" L9 ]build_model <- function() {1 L0 _5 C* U+ q7 n2 H) L
c& G6 B- V/ E' o model <- keras_model_sequential() %>%. a- n* S, s3 U2 H3 g
layer_dense(units = 64, activation = "relu",) f- R& I. g/ @
input_shape = dim(train_data)[2]) %>% h4 y3 ]+ n: i* k) e
layer_dense(units = 64, activation = "relu") %>%% t9 D+ h8 v; U$ {8 F$ m
layer_dense(units = 1); p0 n( R1 `- q9 T* x5 r8 i# D" R
. j3 ]8 ?4 K; D$ ?3 @; M model %>% compile(% w* L; w. n- ^! ]5 E
loss = "mse",4 r3 [, P" f. B; U( I: W9 c
optimizer = optimizer_rmsprop(),
* \: k: c& Y) K. D6 Y" T* s$ M- f" f metrics = list("mean_absolute_error") \$ o5 U# V, L" @0 F1 N" W
)
6 B- u9 V# B$ Y6 Q7 Z3 H- k6 D# p }4 p! j2 {7 D
model! ]- N& T; o! L% n. `0 @
}
& r- m( j2 C; i
$ V) K% y2 @- E; U" Q3 ]0 cmodel <- build_model()
9 c$ L, M$ A! V! z* o5 bmodel %>% summary()
+ A9 J0 d/ G1 G& d; A B
5 c- Y o% J/ L( G2 R网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
/ H# c* P$ h4 o# Display training progress by printing a single dot for each completed epoch.
h6 } y5 v+ w( bprint_dot_callback <- callback_lambda(
: w2 d5 o5 Z( e4 @" n on_epoch_end = function(epoch, logs) {6 Z( k w- e7 F6 K ?% ~
if (epoch %% 80 == 0) cat("\n")
2 K# c% s$ [# p$ B8 R: T cat(".")
+ ^1 F% }: m- a" N5 j5 v% S }: m( d# @! o ~1 y9 V9 w% F
)
8 G; g. Q+ L6 L t. c' ?8 u. q1 Q! q
+ I0 J. L/ e) ]3 Sepochs <- 500
" C2 t" }2 a% t8 y: g, H( s( e! ?3 }7 w2 {
# Fit the model and store training stats
: V" o0 s' l2 t3 c* P( H' p8 @, [history <- model %>% fit(+ Y! ^/ u5 U% I- f) U/ l& A" b
train_data,& [( d' F) J& F
train_labels," t! t, l( Y# E; y
epochs = epochs,
6 L9 W& V7 b# |6 o. r6 d6 t+ X validation_split = 0.2,* ~) B( l0 H4 I8 ]; c5 @
verbose = 0,
3 a/ x; @% @6 p+ T) |" a callbacks = list(print_dot_callback)
" ?% `7 O$ G0 Q+ `6 l)5 j4 c7 Q: G. v5 N# g3 ^* u$ X4 }
& D; c3 ^" C A% w' O" ]
library(ggplot2)
7 y% t. }! J6 E) Q3 L' E, b+ k3 D: n! P: g
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +7 U! i4 ?: p2 V% [/ C' y. w9 r
coord_cartesian(ylim = c(0, 5))
% p: E' {/ {, b* ~6 i3 m/ L; Q( l5 I
![]()
$ X3 r! K1 a& Y4 I# x* i u8 K7 T" }+ ?
2 N- W* y2 q2 u$ }* A9 X( h$ E小结- }3 {/ B# s w
1)回归常用的损失函数是均方误差(MSE)。
# q5 K" R: n% T8 H$ y2)常见的回归指标是平均绝对误差(MAE)。
3 ~% O3 ?. ^+ L) K4 z; h6 v3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
}7 c7 Z& p9 X* Y4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。% w$ M+ o8 ]/ o7 d* v/ L
+ f" ^( ]( a6 x* t) Z
& z, r# s; j: ^ E$ E. g: M' S% z" w
3 U/ ~1 q6 M: I8 z) F |