预测房价:回归问题——R语言
7 h$ Z1 e1 N3 }) G2 ]在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
3 v% l% N3 @: z/ G3 D
2 B6 F' g+ R/ \" J- T1 T+ U. F6 K问题描述
2 T/ m9 {' _3 t我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。 f+ {( I, H3 g; [6 P: }! l$ ~
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。) i t9 X4 \; H5 V
数据特征:
T7 |5 N4 T( @0 r6 O1 K人均犯罪率。
) i; e3 V, ?6 X占地面积超过25,000平方英尺的住宅用地比例。
5 S( E: ^3 I0 q1 e I每个城镇非零售业务的比例。. f# G# ^: _; ]# R
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。4 O: ]0 V0 N, n- @
一氧化氮浓度(每千万份)。
# S5 {: J' r* f2 l8 H k每栋住宅的平均房间数。( f' i- W3 a$ I! I ]
1940年以前建造的自住单位比例。
v' D1 o* h+ `到波士顿五个就业中心的加权距离。
Y! I3 z, Y* t径向高速公路的可达性指数。, `, d; Z( A6 ]: B$ b. K
每10,000美元的全额物业税率。& H1 ^) W# M; R7 O
城镇的学生与教师比例。0 _9 \/ I. x) @. R0 a/ e
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。# J- i( T [7 a/ N% N
人口比例较低的百分比。
) d4 T6 {9 M. T3 `1 \( {3 U1. 加载波士顿房价数据
?8 @2 E1 E" f1 x9 J# K# Dlibrary(keras)5 F! q+ r, P( p, n( {, M# c
. M! a, X5 b. Eboston_housing <- dataset_boston_housing()
! V# k4 ^% a$ F; Q+ k# Z G0 K0 v8 z( C4 x( h5 r
c(train_data, train_labels) %<-% boston_housing$train
( ` b! c+ r! y T6 g7 tc(test_data, test_labels) %<-% boston_housing$test4 C! _% M: z+ C# l6 V
* S$ @6 j7 r4 q) |
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 2 ?$ j* i( O* Q
# Test data is *not* used when calculating the mean and std.
) T3 m- _$ r* l5 C6 Y
! M3 j9 c6 y# j& h# Normalize training data2 T1 R; n- Z0 L) y' I5 {
train_data <- scale(train_data)
) Q( z! k( q5 o- f. ~; C7 N: T7 [% O% u3 G, L6 b* U
# Use means and standard deviations from training set to normalize test set# n; O) a) J5 Y. w; P
col_means_train <- attr(train_data, "scaled:center") : p) b n, W1 q: W5 m; K! D
col_stddevs_train <- attr(train_data, "scaled:scale")+ J3 K4 d% s$ O+ _: ^+ M" ^
test_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
' e D7 A$ T2 c3 \5 J# Y6 I& u, q5 t* P6 o7 H: L6 k% n
3. 构建网络创建模型
$ m- h/ {3 g! ]build_model <- function() {
9 J7 g) q7 D; `2 n* a
i1 h- W! D' o% B7 M- Y( \9 L model <- keras_model_sequential() %>%4 x) W+ Q9 h; j8 d* j. ~& E
layer_dense(units = 64, activation = "relu",) K2 {! e- Q: ~: p
input_shape = dim(train_data)[2]) %>%
, W- C8 w4 E2 j" W layer_dense(units = 64, activation = "relu") %>%5 n3 r1 R8 f5 i- V# b- X- r$ G
layer_dense(units = 1)6 E2 h8 v1 H1 S! h7 \
6 G' I; @' J" J$ b& ]
model %>% compile(/ f" G( [, z5 Y& p; n! I0 q6 K
loss = "mse",
4 \$ I# G: Y6 u7 i optimizer = optimizer_rmsprop(),
" Q! i% j2 |- ] metrics = list("mean_absolute_error")
1 j0 @. K" F$ T( j% A t4 k )3 Q/ X8 F' }9 i( m1 j7 v0 e
5 T) s2 f( g' g! ]1 ? model1 ]7 T* R3 u( y0 T: {2 ^! D
}5 a5 g3 @6 L0 f, v) T: k
3 J( Y1 j+ D: Y+ b5 jmodel <- build_model()# x# x1 N. I( @. h% I5 L
model %>% summary()2 ]5 G$ S' _" m9 J f# G+ P
) u2 y1 S7 {- F4 Z网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型# }) }4 c2 R7 `: [( L
# Display training progress by printing a single dot for each completed epoch.. C: J: a$ _4 O2 v6 K$ |" N, E
print_dot_callback <- callback_lambda(
) s5 F' c3 i. f# T+ T on_epoch_end = function(epoch, logs) {4 p" ^2 d* S W2 \5 x
if (epoch %% 80 == 0) cat("\n")
' g# m. @+ ^, a8 [$ s3 b1 S- ^ cat(".")& R! Z D3 T: |7 Q' R! q: G
}
+ b! f2 i) A# T& m# | h/ [2 s, H)
* ]' J& i1 H6 V7 m5 ~2 a: s
& l+ J4 I8 T7 S4 r+ e0 k9 V: uepochs <- 500+ A( ?+ w+ Y. h" q" c! t
# a' Y! y9 | L* O7 `9 h; W$ v Y
# Fit the model and store training stats
+ I- i( V4 W6 u! T& r+ v( q1 thistory <- model %>% fit(
% o6 L' i5 D5 f$ v4 g. g train_data,, o1 h! W" Y; ^2 X; J7 E v
train_labels,, |4 F+ C% }. K1 l4 q- Y, E
epochs = epochs,' X: d. z& r3 o% L, s5 j- C- g
validation_split = 0.2,
) g7 D( B# R* {9 u verbose = 0,
/ O! [ F6 n7 J3 j callbacks = list(print_dot_callback)1 a& ]: }6 D9 w$ X% x( p
)
% l, v+ Y$ s6 v9 X) H
: `1 M$ m. [- p5 Rlibrary(ggplot2)
0 r+ u8 E/ Z) e& u7 v7 R
! }) B+ W8 _9 q( e- bplot(history, metrics = "mean_absolute_error", smooth = FALSE) +
3 K. U) F( m0 M5 G+ L. ~! j coord_cartesian(ylim = c(0, 5))6 e4 }2 ?9 X; ^
5 Y ?# {% c9 h# g
7 _& x4 x/ u! I# \8 P- @; j
3 `) J q* z B, T3 q' g小结5 G( H+ Y# C' ~7 `
1)回归常用的损失函数是均方误差(MSE)。
+ O7 L7 _6 ^" G+ h2)常见的回归指标是平均绝对误差(MAE)。/ c4 j' z+ I) G2 K2 F
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
# S- y0 ]( x1 g6 K. F& l+ @4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。8 G8 | t8 e$ x9 ^& z$ z1 [/ D
! M* w$ Z4 \' f: t# a
$ V( }+ }3 a5 K: E, k, T# E" G8 h+ F6 _+ ~& f- v
|