预测房价:回归问题——R语言8 m; m. i! B$ Z6 I1 [
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
% S8 Y- E" `1 F, e$ d! g$ v$ y# b _; a6 K/ U: ^
问题描述
' D# X: l# ]( C4 N8 o7 c我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。! ?/ ~& s8 N9 y$ t& l! K0 r) f
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。8 w+ H. I% U3 e& k' c1 e
数据特征:
$ S! |7 d2 C8 z& `9 L u3 P人均犯罪率。) T, R. \7 f; F, ^$ x
占地面积超过25,000平方英尺的住宅用地比例。
$ m" ~# M: V" k9 J每个城镇非零售业务的比例。
2 C3 {4 p: z( b! I! H( qCharles River虚拟变量(如果管道限制河流则= 1;否则为0)。; r' G/ } q( Y7 Y
一氧化氮浓度(每千万份)。. g0 _$ d: m+ `) k, p
每栋住宅的平均房间数。
6 |& B/ D8 w" p6 d7 q4 _7 i$ d1940年以前建造的自住单位比例。
J" R7 y3 n! X* ^4 q" J. d到波士顿五个就业中心的加权距离。, w# e7 J' O4 f1 Y2 Q4 c0 R
径向高速公路的可达性指数。+ P7 d/ J, k' Q3 S% y
每10,000美元的全额物业税率。( G; L( ~- e% G; i* w' l4 r
城镇的学生与教师比例。
5 ?$ P* `( R, y* K. _. A6 u1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
4 B% t% u" G9 @: u2 [% p人口比例较低的百分比。 T/ l: B7 K5 \' _" Q: {9 t; U
1. 加载波士顿房价数据2 h3 z- p1 e; `- ^4 v
library(keras)
$ p0 M ^/ J( f% _' W7 e$ ]' A
0 v' Z) Y3 I2 X) s" {4 \9 R P' L. Gboston_housing <- dataset_boston_housing()! d. B2 w# }' B' O9 A" C+ i
2 d7 b& n: F& a# \; Bc(train_data, train_labels) %<-% boston_housing$train
0 p( x& W. ~" yc(test_data, test_labels) %<-% boston_housing$test
6 J+ _$ X& D/ i R7 ~4 o/ T% J0 Y) x4 M/ b( E0 K8 t
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
- }2 J! b9 t) x5 A3 l# Test data is *not* used when calculating the mean and std.8 v% r' K. g6 v; T4 \: ?
# T- @7 S6 D* O0 X# Normalize training data5 b$ ]! n) W* s1 X0 d
train_data <- scale(train_data) * g/ p) j$ F8 z( d
% C2 q* }# ?1 k: j" e# Use means and standard deviations from training set to normalize test set% x. N9 l; @+ ?. }2 l+ P4 z0 W
col_means_train <- attr(train_data, "scaled:center")
) Q& @8 C! E. t. X% X- `col_stddevs_train <- attr(train_data, "scaled:scale")
7 ^) v; j2 s3 `' F- Z4 Z2 p+ N$ Stest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)
; q1 j$ c4 W6 b+ W) O+ q' x
& J Q8 z- J- D. t! ?3. 构建网络创建模型 8 J* n7 D9 c7 o5 {- D( c
build_model <- function() {$ l/ v( Z0 t c, _1 B$ P1 u
2 S" J+ b. w3 j# l# c
model <- keras_model_sequential() %>%
9 g9 R% s2 q. e; a# \" l; w( s layer_dense(units = 64, activation = "relu",5 l" {8 T L7 e; @, z. m6 U: Z
input_shape = dim(train_data)[2]) %>%
" ~, y8 ?$ h# V9 h layer_dense(units = 64, activation = "relu") %>%0 n* s; Z" z8 b- p0 N. X
layer_dense(units = 1)
2 ~ ~. v* Y; c
5 m, Q. J% u' D model %>% compile(0 V% Q, p- l5 [# x" y* l
loss = "mse",, u0 r6 X1 a1 l# n2 v
optimizer = optimizer_rmsprop(),
! V6 \8 Q, w) u metrics = list("mean_absolute_error")
9 u& m- q( N& ^ )
8 k$ w( l& N9 R( O8 |2 S# ]# z m
3 ~- Q& W; ^- t2 N9 L model* ?( \5 A) c1 z* a# ?" N
}! H* P: s% U3 S: R8 B0 q$ @1 }
9 `0 Z8 j z! e i
model <- build_model()
9 t' D7 ]7 n' `: m' ?" Y, _model %>% summary()
( `& K& ~" |. K7 S1 R$ }0 C9 E+ M: f
3 j5 F& a9 @2 |2 o5 j$ c网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型/ k4 m; v) a: {% z8 E% m$ {* N
# Display training progress by printing a single dot for each completed epoch.
6 O2 Z3 N2 p1 K( h7 }) F) oprint_dot_callback <- callback_lambda(
# |) `4 q: H, d% A4 l( Q on_epoch_end = function(epoch, logs) {' M) h* O+ @ U
if (epoch %% 80 == 0) cat("\n")
$ Q, Q* Q1 e% f' S8 ~; R cat("."): i) s# P2 M% Q- F7 G; n' W. j
}
9 c; `/ U( E2 B6 Z5 V" h6 Q) ! A, @; B" [ @2 z! \% f
4 r- w0 E: K+ x* repochs <- 500
( @6 K: N! y0 W
0 p# o6 V; A3 ?( p. Z+ W# Fit the model and store training stats
% ^2 h2 ?4 L3 T2 H: b; [history <- model %>% fit(
" z6 f: [2 I6 G3 X. T$ C: x0 j6 m train_data,
, l' J9 }9 w, J u train_labels,9 z+ m; [& G" N8 e% I9 }9 s6 W9 N
epochs = epochs,
4 s4 L4 ?0 ]& w, j; O" g- P validation_split = 0.2,
' W, M8 J9 T" O- e9 F+ A& ~+ S7 { verbose = 0,- s, e. r8 \2 l; k, j! y2 d
callbacks = list(print_dot_callback)3 T0 P5 T" m& s' O! W6 o
)5 @' s% C3 e$ I+ X+ \% _+ B- H
; \5 i: `& k* f/ ~, U
library(ggplot2)
3 y1 N; I" I& h) U3 r6 k3 c8 a& F; a9 E! s
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +
5 i8 T: I' V, Z coord_cartesian(ylim = c(0, 5))
& U. m: ?9 j5 n, B7 g! [( D
* Z: U S a% _7 @1 H9 U6 l: O% _ % z) Q# f" ?* C1 ~3 q6 ]* y/ g
$ M, @/ d$ A: J+ V; H, H小结
$ V; V: J/ I8 m/ K1)回归常用的损失函数是均方误差(MSE)。
. Z- h* ?+ X$ N/ K; |! ~# Q2)常见的回归指标是平均绝对误差(MAE)。4 Y7 E) L2 R N' J+ p' i9 j9 z) ?9 {
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。5 q. d% q1 h+ J% H- C3 y4 S9 z
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
1 h$ a- E! o7 h" Y# V- f: ^5 Z6 e( ^7 y; s% ?( L
7 Q; B7 m( z" K+ o
( K K" t6 |0 B2 C |