预测房价:回归问题——R语言0 o5 s( S3 w8 Z' t1 F4 l$ n. C
在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。
6 Q, A0 Q! w" q$ S! A! l1 } l! b* G) l1 \; a. k, T% K
问题描述
8 p5 x( ^, T1 w" K( h" D$ I我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。
1 M7 v f, w$ l9 k3 |+ c; q& U D本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。: x9 ~! \$ z( w0 j8 L8 q, I
数据特征:: l; I7 @, k. L9 p7 u
人均犯罪率。) g( E! [+ _8 t: B/ x: k$ x
占地面积超过25,000平方英尺的住宅用地比例。& h( O, _+ r6 ?# d5 a5 e2 R
每个城镇非零售业务的比例。2 J. `" x: d% p7 J! D* |+ _' K* N
Charles River虚拟变量(如果管道限制河流则= 1;否则为0)。5 q; {3 O( K, W$ o, }
一氧化氮浓度(每千万份)。1 {; c7 L/ C( e2 [2 I
每栋住宅的平均房间数。5 V" a' t) b* i1 y0 D
1940年以前建造的自住单位比例。
( C! P: H. _! L到波士顿五个就业中心的加权距离。
" {5 L2 r( ~4 V9 f; ~ ?径向高速公路的可达性指数。4 D! U$ C I6 }# ^: O% o
每10,000美元的全额物业税率。: Y) Q4 u0 Y7 X
城镇的学生与教师比例。6 c! R: f7 y0 s/ x. E
1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。% P8 z6 Q/ b7 d8 f6 B
人口比例较低的百分比。
& ^; K$ u1 }" \( H+ o* \1. 加载波士顿房价数据$ x6 d" r7 c) J9 n8 v# Y& h
library(keras)
. x& A1 C1 p/ q7 ^" c! x: y" z5 i' \7 `: c2 P
boston_housing <- dataset_boston_housing()
! F+ w- l3 ^. U3 ~% o# U/ _: Z$ ^4 ^( k
c(train_data, train_labels) %<-% boston_housing$train6 {' o& d9 M9 W1 r
c(test_data, test_labels) %<-% boston_housing$test
/ }% p( W- o/ o! g+ N$ v( {$ ~& C
每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。
6 i* Z. j- | Y" H; H# Test data is *not* used when calculating the mean and std.- e9 H | ]) J
- @) I! y7 O2 b! V5 J+ R# Normalize training data4 {6 x, x8 ?0 U( B+ n2 _" C2 F
train_data <- scale(train_data)
1 V3 K; X) u9 R! Y! ?( _- C0 |* h7 I! ~- B( m& h2 r: j
# Use means and standard deviations from training set to normalize test set
6 |! p- G# X) _6 _0 w% V8 _5 E9 ^/ X Zcol_means_train <- attr(train_data, "scaled:center") : ^; _* M' F- M3 u
col_stddevs_train <- attr(train_data, "scaled:scale")
! f) n2 W5 @1 v' B9 Ftest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)% ~4 w. f& q. l& h3 p4 h
" M3 G) o. V8 P! n* j% `7 K# o
3. 构建网络创建模型 7 E$ z9 `9 p3 x7 G. N; s
build_model <- function() {
' l4 n2 J/ F9 M5 n, M. \3 q
" _: Z) i0 s: ^8 b0 }1 G; @ model <- keras_model_sequential() %>%
( x' Y" y4 M6 W layer_dense(units = 64, activation = "relu",
/ e" t' D. `/ I( c7 o input_shape = dim(train_data)[2]) %>%
# D. \- _5 r | { layer_dense(units = 64, activation = "relu") %>%* L" j1 m( L+ J7 d
layer_dense(units = 1)$ R: m+ Q& V) }6 l# N
' o W2 Y( x. U1 t; C1 k( Q) | model %>% compile(; g* H; p% [/ d4 y$ ~% H& z# s2 n
loss = "mse",
* s" D! Y: W: T; c optimizer = optimizer_rmsprop(),' K. g; L/ l% I3 a8 Z
metrics = list("mean_absolute_error")0 C" w7 C+ p: Q: z: E
)
7 |1 D. i: K. ^0 f2 l( `
( g1 q( A1 V* |1 x [0 k6 p model$ q+ g( g7 w1 v8 _
}: z6 e) \3 r3 e2 K: \9 @
! K' s' ]1 W, d( Hmodel <- build_model()
; @1 |) ]0 [7 K smodel %>% summary()5 b! Q1 z; H; d- Q
% G4 r1 r2 }" H
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型
) ~7 ^; D& a ~" T; L: c, i6 ~# Display training progress by printing a single dot for each completed epoch.
1 Z* s7 M: f: U+ _. P5 Nprint_dot_callback <- callback_lambda(! B$ z- l9 G. B/ E/ b, k
on_epoch_end = function(epoch, logs) {/ y( U: w. U, H M
if (epoch %% 80 == 0) cat("\n")
; e4 {. X4 f9 L$ _/ S L! f cat(".")# ?0 v. \- R' \& @9 T" v2 g
}# O4 E. X# t6 x5 g7 P1 `
) 4 O j8 O5 K5 Q$ a# Y
4 F. a. m1 p6 T' i( C
epochs <- 500
8 R, C* j( ~+ P0 W1 G, O" G' ] T/ j' h
# Fit the model and store training stats
t3 W! D+ X' ~( c7 Rhistory <- model %>% fit(
' ~5 c# j; ]5 K0 d train_data,
5 [6 P0 b/ x' U. Z z train_labels,
9 Z- }; o/ c" C0 X0 {& B$ B epochs = epochs,
) W9 G/ y! G7 D9 V& o2 p$ R6 | validation_split = 0.2, S: ]3 [2 ~8 H! J
verbose = 0,
% n3 b P/ r8 V callbacks = list(print_dot_callback)7 j9 ]9 j/ I2 f5 J% e |
)
1 K! v% y5 }* f3 l) |" `/ n T* p% _' e* q5 a( F- ~' `4 l
library(ggplot2)5 Z `2 u4 t+ X7 e2 g
. g. N( Q" ~9 T g5 I( @" q/ O
plot(history, metrics = "mean_absolute_error", smooth = FALSE) +5 r& O; D9 n1 {- y$ M9 L
coord_cartesian(ylim = c(0, 5))* g0 Z: X* T" N) |
" j! {3 e+ J$ o
" x4 t7 _: w( G2 ^! Z2 l4 Z
8 H0 p/ t }! D" N( \小结% ?: x. Z/ t- x2 B' O- Q
1)回归常用的损失函数是均方误差(MSE)。$ H- [! d! ?" K5 U) }4 L7 U7 _
2)常见的回归指标是平均绝对误差(MAE)。9 P( R0 {+ I5 G$ [2 C7 Q- M( c) F
3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。$ e$ g' j, T8 m% y* _8 a
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
5 C5 j+ I6 _* u8 o/ P2 y/ J9 Z/ \ L: P- }3 R
- y/ P* v' f. d9 h9 m
" O Q/ \: k+ ^9 o% F% N9 `
|