预测房价:回归问题——R语言
5 _3 J+ i6 z. I- n在回归问题中,我们的目标是预测连续值的输出,如价格或概率。将此与分类问题进行对比,分类的目标是预测离散标签(例如,图片包含苹果或橙色)。2 ?1 C3 q! U8 |! G
' Y; s$ x+ {' b1 U问题描述0 c2 a9 a- g- K, h1 I. G; O
我们将要预测20世纪70年代中期波士顿郊区房屋价格的中位数,已知当时郊区的一些数据点,比如犯罪率、当地房产税率等。) l, c' C! F) ?! f* F& t0 S% ^
本次用到的数据集包含的数据点相对较少,只有506个,分为404个训练样本和102个测试样本。输入数据的每个特征(比如犯罪率)都有不同的取值范围。例如,有些特征是比例,取值范围0 ~ 1;有的取值范围为1 ~ 12;还有的取值范围0 ~ 100,等等。
% u- g+ O8 ^9 O8 |7 h+ j数据特征:+ @5 h# n2 H% b7 @& T2 Z7 H; ~" g
人均犯罪率。
4 l8 B: l9 S3 \占地面积超过25,000平方英尺的住宅用地比例。, {+ Y2 N; [! _$ a
每个城镇非零售业务的比例。
5 e$ K7 f& Y0 V9 XCharles River虚拟变量(如果管道限制河流则= 1;否则为0)。7 D u5 a1 t& R/ h: J
一氧化氮浓度(每千万份)。8 E& Y1 M* P3 y, x: Z
每栋住宅的平均房间数。
$ P8 a+ p1 ]; j$ }9 p. ^# O1940年以前建造的自住单位比例。
( D# |; ~/ a$ ]) x6 E# e到波士顿五个就业中心的加权距离。
`6 O+ J: W7 ^径向高速公路的可达性指数。7 @, j; P0 y% l
每10,000美元的全额物业税率。
9 v$ _1 N0 ?4 x. W城镇的学生与教师比例。
. b& H, @, y/ i- r4 L! A5 m8 e, l0 n1000 (Bk - 0.63)* 2其中Bk是城镇黑人的比例。
a# C$ U3 c/ V, x2 V4 `2 g6 c& m1 X人口比例较低的百分比。
; [; r5 B% n; V; b+ s: `$ k1. 加载波士顿房价数据) j* t4 ?/ E" [' u
library(keras)
/ ~1 q: A7 m5 ^ j! q7 `' t- z; @# P& O' ~% U' v4 H% C
boston_housing <- dataset_boston_housing(). ], Z5 `9 }/ M# B% E, D
6 M" u1 B3 p: o- C
c(train_data, train_labels) %<-% boston_housing$train8 u7 i" e8 r; g: V: p- J
c(test_data, test_labels) %<-% boston_housing$test
; ?$ ]4 G! n! d! d; M. t: m# ?, a1 ~
! g4 u9 u# ` D9 N每个样本有13个数值特征,目标是房屋价格的中位数,单位千美元。 2. 准备数据数据标准化 将取值范围差异很大的数据输入到神经网络中,这是有问题的。网络可能会自适应这种取值范围不同的数据,但学习肯定变得更加苦难。对于这种数据,普遍采用的最佳实践是对每个特征做标准化。 ( s: U+ \- D, m' _# ]: A
# Test data is *not* used when calculating the mean and std.
: d3 `0 V& H; S$ U' W; o8 q: c
" S/ F4 }6 f2 l9 ?5 j7 N+ n H! J# Normalize training data) F3 M& h/ l! W* J' A
train_data <- scale(train_data) 2 M, w& z G$ T
$ W6 w7 X# o, O& U# Use means and standard deviations from training set to normalize test set% }2 ~, C% h9 f" N- _
col_means_train <- attr(train_data, "scaled:center") 8 v9 j0 @1 H, s/ E
col_stddevs_train <- attr(train_data, "scaled:scale")
9 D1 A7 w4 f; R; Rtest_data <- scale(test_data, center = col_means_train, scale = col_stddevs_train)- O0 f% l5 N5 R; x, T* {) Y* `
7 Y4 s9 M u3 u* G e* e
3. 构建网络创建模型 # P0 E; e: s) U- O& l `0 ~
build_model <- function() {
" C1 O2 [( L% s- {% q5 S
?/ G, i) R @7 C, D/ ^* P model <- keras_model_sequential() %>%8 Y) _& G% {. r# i2 N1 q2 m- ^
layer_dense(units = 64, activation = "relu",
) w2 }; L2 Z. P- ^ input_shape = dim(train_data)[2]) %>%
; D+ I: W8 o( H8 _7 y o8 E0 R2 w1 Q layer_dense(units = 64, activation = "relu") %>%: E4 S1 `/ f: E" F+ F& m
layer_dense(units = 1), J3 g- X" s2 S/ ]2 l
: D D! n4 a6 w
model %>% compile(- J5 d' M+ f/ x: O; z
loss = "mse",
+ ^0 H5 f7 \( n0 y* V optimizer = optimizer_rmsprop(),
8 ~7 p+ s1 `6 d; Y metrics = list("mean_absolute_error")
2 F, r9 g9 k0 @7 J* \ L- g3 V, [$ V )
: Y+ e# K4 B" p% y9 N% B0 J/ d6 a! g
1 ?% E8 O- b- a& p2 |2 d2 z model: w; i! }8 D$ A" S) Z
}
/ J6 ~; V/ E1 ~' ~8 V" r9 }3 L
7 o( h4 ^3 {% b4 V3 Q( {3 Kmodel <- build_model()
+ u2 D2 j: f5 L4 Q7 Cmodel %>% summary()+ |- y+ N$ s7 c7 e" o. G
" Q2 p; d9 [+ G, @) z
网络的最后一层只有一个单元,没有激活,是一个线性函数。这是标量回归(标量回归是预测单一连续值得回归)得典型设置。添加激活函数将会限制输出范围。 4. 训练模型' q4 ^ i) M( p& X
# Display training progress by printing a single dot for each completed epoch.7 M3 X( ]% I# r! g
print_dot_callback <- callback_lambda(
6 Y4 Q/ E" O% b3 x6 H4 g( p% c on_epoch_end = function(epoch, logs) {: ^9 M5 n; o& C( m# J# G1 [5 n% p
if (epoch %% 80 == 0) cat("\n")
' E% \1 w& C y ] cat(".")- G8 j6 f3 B3 W; ~' n# _
}
* s# G' [+ K* n7 A. b l. y)
3 I x3 D3 ~) s
9 `# ]/ z8 [( Z9 Repochs <- 5005 A" l* ~. y! P; m+ p: V) A
2 H% T& e% o4 x0 Y# Fit the model and store training stats
0 p* |- S) z7 L* Y j" bhistory <- model %>% fit(& ]% Q, |6 _ y9 t* q4 s' }
train_data,5 ~! ^9 d3 D* w% z4 | d/ c6 r8 s
train_labels,
$ X3 z$ X v+ S/ r3 \8 z* s, I: I epochs = epochs,! `( J/ I J$ t& s/ ^7 o4 U
validation_split = 0.2,
: l6 `6 R6 u e9 W7 O+ Z! T* h verbose = 0,
6 E2 @' W# Z% h' \+ J! D callbacks = list(print_dot_callback)
6 |- L' v3 S1 Q! W8 x2 V# o, t' S)
! _/ p) I8 N0 Q% k: ~4 X2 U. s% u! z0 z' \
library(ggplot2)
7 N1 c u' }$ } V2 x0 P$ g
3 b* A J: g- ]+ q) ~, m P: M! Bplot(history, metrics = "mean_absolute_error", smooth = FALSE) +% ~$ E5 ~0 Q* ]0 q8 C
coord_cartesian(ylim = c(0, 5))
" h0 ?! ^* }+ r; E- n" K: E& g% C: Y5 A' N" M
![]()
6 _6 V& {8 D/ k; i# {) }% B6 X( u/ s0 k9 V' w. k
小结
$ Y7 [, U; D1 ^9 o) Y1 ~1)回归常用的损失函数是均方误差(MSE)。4 y. J: l8 `0 O' d6 B; M$ I9 W& R6 j
2)常见的回归指标是平均绝对误差(MAE)。
) R( Q, m! k/ `3 N9 e0 E; |# @" W3)如果输入数据的特征具有不同的取值范围,应该先进行预处理,对每个特征单独进行缩放。8 h3 w+ D0 I3 D0 l4 O$ T- ^9 H3 f
4)如果可用训练数据很少,最好使用隐藏层较少(通常只有1~2个)的小型网络,以避免严重的过拟合。
* Y: n; c6 I. H3 N4 a
- s+ t% G& @ E- G: a b% K' E: t
- p& V- `% y5 I1 m5 I+ A$ i
& P: I& a; S: h5 j' y; D y0 N/ @ |