预测房价:回归问题——R语言# {4 J2 f0 d& J
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
: w& j3 E% `3 G6 |. g1 b$ T. m, Q- E5 G2 A6 `
问题描述
& V6 L' z2 [* g m& `我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。9 z4 G" {& }$ h+ Q- s6 J# C
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。8 z1 v4 }0 b5 m( e7 i
数据特征:5 O$ \ \; K/ ]# b* w! @# L! T
人均犯罪率。
, ]3 ]! J) {' }& y8 [# f占地面积超过25,000平方英尺的住宅用地比例。
& w; }* n k+ K7 {* y) T3 [4 b8 |每个城镇非零售业务的比例。, P: r% V# {$ u N9 m+ U- Q' ^
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。, {7 A$ y6 v4 W4 \) g5 Q0 f
一氧化氮浓度(每千万份)。
: K+ K- c9 J0 t l X每栋住宅的平均房间数。
) v+ k# L0 ~% K2 d) a5 k1940年以前建造的自住单位比例。
( E# z+ W7 [0 c \1 m到波士顿五个就业中心的加权距离。
4 Q8 |4 o2 }8 Y径向高速公路的可达性指数。, K$ q1 u, s1 {
每10,000美元的全额物业税率。9 ]# ?; P& ^6 @. p4 B8 n: Q
城镇的学生与教师比例。+ l3 K) H: N$ M
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。/ D7 Y" W6 z A# v
人口比例较低的百分比。! G9 n4 z9 z/ w# H i5 i7 A2 s
1. 加载波士顿房价数据
K/ t3 F5 R" g, s wlibrary(keras)
+ V" Z) v( m# x# P7 S% m7 J- Y) Q+ Y2 Q2 Q- S! r) h
boston_housing <- dataset_boston_housing(); e0 F. ~7 ]% W5 z7 j1 z
. Q4 K; R4 v! ]% i& L. U
c(train_data, train_labels) %<-% boston_housing$train
8 X1 z4 B; K" F/ N: J$ Nc(test_data, test_labels) %<-% boston_housing$test0 s5 V$ \+ p y& F3 K9 m" ]4 x
# @) b: ~2 I, _$ y7 g Z' }4 |# S9 @每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 ; a& s/ \9 K; k) k, p9 @
# Test data is *not* used when calculating the mean and std.
) i) C& x, f$ }; }; O1 A) P, ?6 _7 `
# Normalize training data$ G: m; s- {+ T: A2 t9 c, v
train_data <- scale(train_data) $ f- p# M; p& L7 [) q
7 G- F8 f1 z- T; q
# Use means and standard deviations from training set to normalize test set/ P3 ?6 `) l9 C, J. Z+ s+ H8 v
col_means_train <- attr(train_data, "scaled:center") * z# b/ @- O7 x$ N/ n6 G$ ]) q) t
col_stddevs_train <- attr(train_data, "scaled:scale"), f) }2 B7 m. f- X7 B$ o. n. H
test_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
( g6 Q# ~' ^$ `: ^! `$ N0 K3 d
/ t- @* M/ Z% P' ]! t3. 构建网络创建模型 ! O! B- S, M) T1 }" F% W
build_model <- function() {& X' v+ L! Y0 ]# \2 r Q$ T
. K4 O, M8 |) O# x! | model <- keras_model_sequential() %>%" M+ a9 E- p5 z% r9 q
layer_dense(units = 64, activation = "relu",
/ j- }. i/ |. {# ?9 r& x& r input_shape = dim(train_data)[2]) %>%( r; F1 Q. M. D) K3 T
layer_dense(units = 64, activation = "relu") %>%
4 ~4 O8 j% D5 u& l v" ^: S# F& e* r layer_dense(units = 1)- o" Q5 Q% G5 ~
) \3 L# I6 U/ t* E5 O% i
model %>% compile(# q7 |( T# n! m- _9 t
loss = "mse",6 X. l/ M2 f. J% W9 X
optimizer = optimizer_rmsprop(),
! v) B [: q/ B8 ^ metrics = list("mean_absolute_error")
% O4 W8 B6 o$ A% i' R% L6 p ): n7 k! h; A. [& i% b G
7 V; w4 Y. r6 n3 X4 U6 `
model. z+ ^5 o3 \" _% d. x
}* z* w G$ w# r3 C1 Y8 m k, w
+ E/ S" |5 }% X
model <- build_model()' s8 G/ |) N' m
model %>% summary() G: d' J; w$ Y8 I
* r( r7 R$ E2 X3 i' c* L
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
5 h, B4 A* [# F# Display training progress by printing a single dot for each completed epoch.
+ f1 h, k3 i% j0 ~ @3 aprint_dot_callback <- callback_lambda(
% m, U0 T- ^" \! x% F on_epoch_end = function(epoch, logs) {
4 H4 _: I5 n8 W. K. n; {8 D if (epoch %% 80 == 0) cat("\n")) s1 i+ k7 f9 Y/ J5 M2 p+ g
cat(".") p3 j' h9 X* i+ _/ B' W
}4 k, {5 J' H- ?: U5 @5 h
)
+ Q8 F# Q3 D$ k# N; N/ g$ U+ H# F- |) m& F) y# g
epochs <- 5004 X* J8 t: z* S
9 p: ?7 c9 d: I) K
# Fit the model and store training stats2 Q: l# W7 @; \3 x$ t5 X9 p: k4 J* N
history <- model %>% fit(, C3 K, J0 n7 L- ~( ?
train_data,
. G8 F( s# k. F" j+ e+ Y' W. @3 N# E" Y train_labels,( Z) n w6 M/ x4 k e3 `( p. h
epochs = epochs,
0 x8 G8 L0 S! l+ {2 l+ O# s% X4 B validation_split = 0.2,
' @# e- B( I: a verbose = 0,
9 s e5 ^0 b7 x1 P' b8 G! L+ }' \ callbacks = list(print_dot_callback)9 _1 w! ]2 K9 w' V. Y; d9 C' V+ {0 B
)- G* T- N" I. {
7 H, }; l8 w( W3 z/ Rlibrary(ggplot2)
: {5 F$ [; ]% F+ R+ h& z6 s. C# o; m8 H
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +
9 r, z# M( P. g$ v$ S) G5 i* t coord_cartesian(ylim = c(0, 5))
! \: Z. o; F' l/ \8 m# c4 h; d: l/ A9 Z
1 w w: d: R, a# S& P0 Z
4 u# l0 C L4 c, n1 Z; D
小结
7 e& h" }6 t! Q g1)回归常用的损失函数是均方误差(MSE)。
- i0 ~/ Y+ x# C; E8 {2)常见的回归指标是平均绝对误差(MAE)。
; F ^; }( m2 Q. r2 L8 w3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。5 X* K: h$ d+ k0 E1 V, A* c
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
1 s* n8 v: t* |3 X" _ o1 f& Q# T8 V' Z
: G! J! B: g4 t
' s- \, `; q/ E b( q' { |