预测房价:回归问题——R语言
0 g) U U3 h6 Z在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。4 Y; ]6 ?9 K7 L) l- S- c" |
; C5 D2 r- |7 R9 ~6 b/ {! y3 n问题描述
u# U1 F1 w8 F3 C我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。* E! a" P5 g7 G0 ]. W
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。6 x2 n( N" b1 K" Z ~
数据特征:$ r8 O' K* z: y$ v/ [' V0 V
人均犯罪率。) x- \; k7 Q& d# }( i0 b& ~9 _
占地面积超过25,000平方英尺的住宅用地比例。
* ^/ l9 G2 O' F! H每个城镇非零售业务的比例。& H6 d& X0 Q! {5 L& K+ r
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。
1 l/ s/ o! b+ W; m一氧化氮浓度(每千万份)。
( \7 D; {8 V/ W9 J6 Z9 n- W7 d每栋住宅的平均房间数。0 k; G$ A6 @. s) y& O
1940年以前建造的自住单位比例。4 K# [- j2 H# W( a1 [
到波士顿五个就业中心的加权距离。
! z7 \. z! s0 P2 Q径向高速公路的可达性指数。2 i& Q0 P* t r3 `& ?+ q D
每10,000美元的全额物业税率。
* }4 t9 H( g3 @- p9 c" E6 h% |城镇的学生与教师比例。
8 G1 F; q" B- v& p; b' _ X& Z1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。; a7 a) I0 w9 k
人口比例较低的百分比。" d1 f' ^6 M; s$ r# ^
1. 加载波士顿房价数据, ] I( p1 P6 `# ?+ D, ^
library(keras)
; G$ e3 B0 x' X& ^. H
# B; Q" ?0 L' _9 ~2 A$ W- gboston_housing <- dataset_boston_housing()* i4 i! T' h% h% S3 K
8 P! g: j' R1 z! V5 k
c(train_data, train_labels) %<-% boston_housing$train
9 }' f. ]% o2 P' T( O; N2 Vc(test_data, test_labels) %<-% boston_housing$test
x/ h0 K" K% s/ t5 B* r6 l
& G! l; T# S3 y) O& D5 ^每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
: N$ @* v) d; N' E' A Y$ p# Test data is *not* used when calculating the mean and std.' U- X ]) l% x
$ u. l6 M1 \2 ]% d# Normalize training data
8 ?6 t3 {1 K9 l5 n7 k2 Ctrain_data <- scale(train_data)
6 _' G* G+ q* f R+ }. g- }8 T: P2 q( p( e
# Use means and standard deviations from training set to normalize test set- V7 F9 p) k' @7 ^5 r- A' [
col_means_train <- attr(train_data, "scaled:center")
5 ~9 s+ K5 P( Rcol_stddevs_train <- attr(train_data, "scaled:scale")
& {# f& g. n+ V2 U' Jtest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)% t9 ^% |7 N$ X; t! }6 k" g- t' }' A# \
7 b7 {% T) G3 T% n- m! A3. 构建网络创建模型 / x: Y, ~! d; \% ?
build_model <- function() {# F* J1 K& t% l6 U1 Z
! N) P6 a) c6 e" m8 A! B
model <- keras_model_sequential() %>%
# k! e3 ]' k; r3 ~$ H# M" G layer_dense(units = 64, activation = "relu",! a; W* {5 s: m( S7 `
input_shape = dim(train_data)[2]) %>%4 K- v1 d4 d+ _1 s" i, d3 M% g- E
layer_dense(units = 64, activation = "relu") %>%) {$ Z# Y3 o# X% m9 w: f& D
layer_dense(units = 1)9 k( U# Q/ ?- Y, |
# [3 ~4 `" X0 l! F model %>% compile(
& F# T- H, p4 v* P% I* Y2 w' Z ^# @ loss = "mse",
& K" f n+ ?. X* T' m optimizer = optimizer_rmsprop(),
# U: {: J( c& i8 X# B; g$ R metrics = list("mean_absolute_error")
( f% |( g6 z% R. r% Z' d, |5 S+ z" X )
/ A' H' j7 \% m) A w0 }
. M b1 h! \( c( e model! R2 b; ], W0 c* `- u
}
+ \: L, T- t/ H
5 P: C7 v7 _% V# Y( Rmodel <- build_model()- R% U+ S( Z( I0 C, f
model %>% summary()
0 n x( @7 i- j7 e; l8 o% }
+ a7 o/ N) I1 ]# f; W4 m网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型 P1 @) A% _4 G
# Display training progress by printing a single dot for each completed epoch.
: c# A c, C& Kprint_dot_callback <- callback_lambda(
2 k/ {. l- d, [7 ^ on_epoch_end = function(epoch, logs) {
: c* U& } ?# c6 j8 B9 A9 s if (epoch %% 80 == 0) cat("\n")
. V+ @ i8 e1 P' O9 T' B cat(".")+ i% w5 E& W9 V' G' X
}
5 F3 Z# B/ V& J+ v2 q6 ?7 E) 4 D. Z' d' \2 r
, k1 s5 |( T7 N$ |
epochs <- 5008 V% T$ _! F+ `
/ t8 A. V0 M# V+ d- T: o1 q
# Fit the model and store training stats
8 y; D. k/ A0 i3 o: b" Ihistory <- model %>% fit(
- T4 D' [0 M1 |9 W. U5 g# n5 ~; x train_data,5 V( R t+ P8 m
train_labels,
/ v/ B/ o, j& L* c: E5 E( g epochs = epochs,6 [- x! Q# v9 p
validation_split = 0.2,
" L/ l: r G7 |6 m; k9 d0 z3 H verbose = 0,
& v/ j" a- E/ w: o* z+ k' O callbacks = list(print_dot_callback)
/ t3 d ^) G: C3 o)/ u" @& [4 H$ `+ {8 r% O
, T0 h4 U5 ?% N: ]# T. y9 ~) p6 Glibrary(ggplot2)" B3 l6 q2 z8 |4 @$ ~( l% j
2 ?4 L, M$ R5 P/ c) E6 Z+ F6 g4 s
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +4 R a) E3 [- l
coord_cartesian(ylim = c(0, 5))
0 O4 A/ i/ n# M8 a" @- A. D# k+ z; w% p. Y8 G' x5 I, {
![]()
; i: g) R) S- r/ O% ~7 K% @8 D' [) c6 Q$ z& A) H( s/ T. t# x
小结
: w3 u# P) U/ M! q& ^+ s1)回归常用的损失函数是均方误差(MSE)。3 l1 J; @% O6 ~& u# F; ^, s
2)常见的回归指标是平均绝对误差(MAE)。
5 N- V. G8 D; C' |3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。. W$ t- o, _- ?' A# h- ~4 Z
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
J7 L* z1 J, H8 j: P: P2 E! [/ H+ E- F, F! ^
9 R& B/ o* C( Y3 G. Z1 D
4 f4 j7 `( z3 S/ O, n; i7 n/ r |