预测房价:回归问题——R语言1 h( Z) L5 q/ ]5 F
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。+ g5 d' o9 }% s3 V( j; ^6 `
- K2 Y8 ~7 O+ b/ V+ z& D
问题描述4 i! v/ f! g! Q% w; w- f- \6 m
我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。0 P, i1 M" |8 _+ r& F5 Q
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。( p- e$ N9 y% q- s9 Z# ^# k9 i
数据特征:1 v7 ~* d: q5 q2 d7 f; z
人均犯罪率。 V9 S+ W5 P: J. m8 Y4 }: ?6 [
占地面积超过25,000平方英尺的住宅用地比例。& h9 K, B/ i- G, O, n3 G+ ^
每个城镇非零售业务的比例。
& v6 _; }5 F" v$ p3 E8 [Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。
v" n1 ~7 ]3 B' o, U一氧化氮浓度(每千万份)。9 \! n, M" ~# M- e; E. j
每栋住宅的平均房间数。
9 E, ?) Z" i: w" H z+ c1940年以前建造的自住单位比例。
/ h/ W( r9 u4 H& I8 L' y* w7 }到波士顿五个就业中心的加权距离。" p+ R, g7 A1 m# k; Q; C: X$ ?0 m
径向高速公路的可达性指数。
6 ], U; E$ C0 T每10,000美元的全额物业税率。
, x6 j5 } [( f3 j城镇的学生与教师比例。
+ y+ y" b/ I2 V- n" y1 E/ F1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。' s$ I% P, }+ @2 R. \) A. m- q
人口比例较低的百分比。' z/ l3 B- g0 Y' n! X% q7 Z
1. 加载波士顿房价数据6 _( t5 U9 h) T! N4 Q
library(keras)! H4 s* g" \! B+ M
, l5 l+ Z5 m" l2 v1 \. P+ J4 iboston_housing <- dataset_boston_housing()
/ D; R) s2 A% Q& z f n$ c; D( J0 }) e: G& }& ^" Z9 s
c(train_data, train_labels) %<-% boston_housing$train
! z0 \# O3 j S+ ^$ r+ a$ P9 cc(test_data, test_labels) %<-% boston_housing$test
1 F) k+ Q9 \9 o5 w" K
" T7 e6 @2 W/ F. ~2 R8 H* E每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
. M/ V* n1 P+ L% W3 J& g# e# Test data is *not* used when calculating the mean and std.
; w2 l3 m2 K0 k" t! c9 D% e% P- v5 k" E- N7 Y' ^8 z
# Normalize training data
; R/ y5 }. x( W7 p3 @train_data <- scale(train_data) " h4 H9 |" ]; {# W. S
1 Z. {2 Y& V8 D! J7 {8 ~& l# Use means and standard deviations from training set to normalize test set
?' [9 s, W' x' C8 ccol_means_train <- attr(train_data, "scaled:center")
6 }. V! u$ S" ?) tcol_stddevs_train <- attr(train_data, "scaled:scale")
9 u* A$ u2 P- l+ Z; Xtest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)8 z& r: h! i4 } Q- Y. C# K; v
7 M+ O+ {: S1 D$ h* D& o8 G, G3. 构建网络创建模型 6 A5 v! L( O8 C7 a. ]4 _" F
build_model <- function() {
9 V* L8 @2 g2 }5 r; U, T% ?' J2 h! ~
model <- keras_model_sequential() %>%
0 c4 ?# b; v2 r# J6 h' b7 x% o0 T layer_dense(units = 64, activation = "relu",
- K$ K4 K" j0 ]* ~ input_shape = dim(train_data)[2]) %>%
F$ C9 ?) _1 m& v: v layer_dense(units = 64, activation = "relu") %>%
. a, [% L, x; s0 P layer_dense(units = 1)7 }( x/ C. o& c
% b, L9 E) H% a: e9 W3 D
model %>% compile( { j A! H+ Q) Z5 `% \% A G( y4 h
loss = "mse",3 o0 q7 b( W4 } L3 A1 \
optimizer = optimizer_rmsprop(),0 ~ s' Y% X$ V% i1 M! ?7 @7 D
metrics = list("mean_absolute_error")
: s: }% `0 S3 b* H- j" Q )
7 y8 _. ]% j& {. l
. N* d: ^7 g0 U' u/ R5 G5 T) e model
2 G/ W& j8 X( W% @& Z) Y$ O}5 m) ^- y2 w& j j6 D" Q
$ v3 Y) r8 O$ u0 s! ? tmodel <- build_model()) n# u3 L; |- ]- ^# J
model %>% summary()
" x. D7 V6 Y' X4 J8 b" H1 I. a v) v$ v, y
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
! [4 ^8 T3 L* V5 o# N4 ]) I! A; }# Display training progress by printing a single dot for each completed epoch.
. }3 |5 q+ l/ F" e% m. Vprint_dot_callback <- callback_lambda(9 v2 D' B2 `5 H" B6 ~
on_epoch_end = function(epoch, logs) {
5 L+ U$ \( S8 @0 j if (epoch %% 80 == 0) cat("\n")$ A0 Z( R) R2 o6 l2 Y% u7 U0 n
cat(".")
; S h& D. G" L) z8 O# `7 I& ` }
/ r+ w# r! P2 x5 L4 t)
$ n- V% ?1 C% H7 `+ M/ t
/ h& Y$ Y5 K; c2 E" x& {; ]9 kepochs <- 500
$ E, Z! O+ o0 M$ V8 J( H3 E ^
; h u' w: v. X" a1 _. r3 O G: G# Fit the model and store training stats) A; ]! d0 U4 q* O" C5 _) |
history <- model %>% fit(
6 G9 L) I2 R/ ]1 U9 u$ y5 y train_data,5 ^- @7 _+ E6 x/ N2 {
train_labels,
/ e O" c3 }# @* N+ a epochs = epochs,
8 U* L. e: ?2 S% a validation_split = 0.2,
+ f1 n: M- x) d, A/ b: F verbose = 0,* |" n3 G5 Y2 n/ E! B' Q
callbacks = list(print_dot_callback)* r' G% x& `& r
)$ c% N- j5 s# H5 t t) j8 C
& F4 v" P' X1 k0 @! k
library(ggplot2)0 N" _2 ?. b% R4 n
: I3 c, s- V/ @# q0 j9 u9 c
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +
' e4 g; a, c7 R% b* } coord_cartesian(ylim = c(0, 5))% z- `1 ]; Z4 C! [6 O
9 w. s6 d3 j9 u' e# U
. m2 C! X3 E; d. K
" y8 z6 ]% t) L* A小结
8 C% X& y6 r. X5 m1 ?) ?4 [1)回归常用的损失函数是均方误差(MSE)。
G: v2 U! Y' H% v2)常见的回归指标是平均绝对误差(MAE)。8 j6 t( _+ m! X$ E4 M8 j+ C
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。
: {2 L! K0 R2 Y0 ?: b( R4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
4 d/ x ?! G; I9 y' p' J
: s6 i0 n# v8 s$ M1 ^0 h7 o$ }: y+ ?$ \9 N: r% [
( |4 {6 I1 b- j" r* @, W4 ?3 ~4 r' A; k
|