预测房价:回归问题——R语言3 S" U; R. I0 K7 B
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。' `0 S, D7 H9 K3 K
R; f8 H+ n+ j h0 ^问题描述% H* U7 z, a9 |4 i4 A
我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。
" i( z- @" q8 ~" e9 }本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。: y2 k2 T9 s4 W; y8 r. w
数据特征:
: k0 l: Z/ e; `# f人均犯罪率。8 F, W0 s$ C0 E2 q1 A: W ^
占地面积超过25,000平方英尺的住宅用地比例。0 Q8 J( D6 M# j5 V; t
每个城镇非零售业务的比例。
5 @( {4 \" G3 L0 {& ^5 h# {2 vCharles River虚拟变量(如果管道限制河流则= 1;否则为0)。
2 w* R' N g2 @8 [; J; \2 q一氧化氮浓度(每千万份)。
2 o7 a- R7 m, O2 u6 n每栋住宅的平均房间数。7 i0 T! z9 d8 `- U2 p0 P7 {# u
1940年以前建造的自住单位比例。" t$ N2 T' l9 y& y# F, R1 h
到波士顿五个就业中心的加权距离。1 _: Z# {% a! { \) G
径向高速公路的可达性指数。
5 K# c& P( }( N; q6 K9 ^每10,000美元的全额物业税率。
8 _' Z9 X. N% E6 w h城镇的学生与教师比例。" M) V1 {% ^& @) X, G7 y: b8 p A6 c0 m, q
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
9 r) c3 `' j$ Y! K+ m0 n4 f* Y人口比例较低的百分比。- L# f3 G" D/ L( M
1. 加载波士顿房价数据; \' A) y2 A+ W( Y( v6 l9 p
library(keras)
% |1 D7 O( [6 A, J
# ^: ~7 j5 x7 ]5 pboston_housing <- dataset_boston_housing()' o# m# q; N3 Q R
0 ~, R8 {3 K' Z: Y" W9 a$ W! ?c(train_data, train_labels) %<-% boston_housing$train
( K& F6 n% \* U9 ?c(test_data, test_labels) %<-% boston_housing$test( D$ P( m5 m# G5 w; p1 X' J- m5 T \( l
7 D7 R; D" P+ {8 i' [每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
* k* y1 D4 S) R( G; A3 j1 O, f: l# Test data is *not* used when calculating the mean and std.
- h0 ], P$ r4 f5 s/ p: J( P# {" G+ o6 J6 _; D+ R
# Normalize training data( t M, g0 f! y
train_data <- scale(train_data) 5 b: {: ^0 o( n* f$ e( i
8 I5 p* U; _0 w
# Use means and standard deviations from training set to normalize test set2 k- h5 t0 i0 _; x: x! G8 r. Z% S
col_means_train <- attr(train_data, "scaled:center") . [" n0 Q6 g1 D L3 B
col_stddevs_train <- attr(train_data, "scaled:scale")
; _5 {0 ]6 |- Q% F. Ntest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)& l4 q1 n" v7 t
# ^" I# y y0 C, K3. 构建网络创建模型 ! I1 l$ S: e& t. W7 ]! b- S2 c
build_model <- function() {
2 R v4 Y# ^0 h) @4 t
; o3 i4 X# w* w1 w3 T1 A x model <- keras_model_sequential() %>% t; B: g' r! F( T
layer_dense(units = 64, activation = "relu",
8 _ ]7 ]/ ` h8 n$ U input_shape = dim(train_data)[2]) %>%
j1 x5 S) y$ a layer_dense(units = 64, activation = "relu") %>%
0 S9 i1 w/ ~$ u layer_dense(units = 1)
4 b& ~2 D. b5 \& P, x9 W. C2 u1 K s5 _
model %>% compile(4 u" z5 J, k8 w, J
loss = "mse",
2 {6 R- c& i; t optimizer = optimizer_rmsprop(),) Q* ~6 b8 D5 {; s: P' _
metrics = list("mean_absolute_error")* v: K4 z) x7 R6 d8 O+ y5 Q
)
. J) j5 R6 G2 _: i3 A, ~4 U. U: K9 d+ Z
model
: K4 Q% K- p8 c}# k* f* c$ C) U: d+ S S8 O
! R- P: Z/ P( y6 o9 q- U- L) l
model <- build_model()# q; J! @* K; k9 S3 R7 J0 ^ E
model %>% summary()
. E+ ]" _9 h# L0 j
8 t" Y" ^, V$ X, _; B% p! T" I+ L& g网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
( Z6 ~, _% k# J. j3 ]# Display training progress by printing a single dot for each completed epoch.# |# ?: ^* k; s& a' T3 m7 o
print_dot_callback <- callback_lambda(
* H1 G9 {# d+ G* k3 X. ?! { on_epoch_end = function(epoch, logs) {
8 U6 r" F; S5 ?; [5 ? if (epoch %% 80 == 0) cat("\n")6 c, ]3 Z2 ]- p2 S5 e
cat(".")8 c! t. a- ]: ]1 I @
}$ L2 o2 J/ j! \: r1 ^- j
)
1 O- T& |0 e7 C! w* _. Y O( _' q/ @) V K) T3 p" x0 [8 c
epochs <- 500
) I) G1 ?$ m$ G3 C. Y$ ]
- ]7 E- B8 _" u# Fit the model and store training stats
$ F: D. q9 I4 u& ]* shistory <- model %>% fit(% ?2 _) J# F7 e
train_data,3 t) k* f0 h$ a% }' o! @2 m
train_labels,
1 H+ L8 K( G8 }: B* q epochs = epochs,2 K k, }: j/ W) T0 L3 E. G7 `3 }
validation_split = 0.2,! z% A0 `: v s
verbose = 0,* A9 s7 O$ w# ^0 ~
callbacks = list(print_dot_callback) T; T9 E# z( a/ T3 b! A: ]( O% R
)
1 M8 R3 W. H) m; G# _# O+ [6 w% `- F# d9 x7 j& k* w6 N) O) l1 C2 ]& d' t) d; G
library(ggplot2)0 m7 X9 ?8 q6 H9 G/ H
2 Y0 I/ s7 l& [" ]( s$ G" Q; p
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +6 ~' }. k7 y; t9 W* i) ^$ c8 e
coord_cartesian(ylim = c(0, 5))% ^( N6 ~7 m5 q B9 u
3 ]: h m$ s& G, c& ?9 b
5 c! C2 H& e* Y; B8 e
4 K" h( {; Z. [- k小结
: P# E) I( G( ?4 X& [; k9 v8 h, R1)回归常用的损失函数是均方误差(MSE)。; c% ?0 E ^' u' j( a% N1 K1 n. p
2)常见的回归指标是平均绝对误差(MAE)。: `+ E) P" ?0 ?
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
7 {! {2 L& n4 Q4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
" W0 _2 E$ {' P* d* e N. u& ^- H0 y/ n) }: |
& P! q; K9 B, D( w2 \
+ d' k/ [) m$ m3 N0 F/ N7 T' { |